【问题标题】:Conflict between BeSimple Soap bundle and FOSRest BundleBeSimple Soap 包和 FOSRest 包之间的冲突
【发布时间】:2017-02-09 00:01:22
【问题描述】:

我正在做一些 Rest 和一些 SOAP 服务,对于 REST 我正在使用的 FOSRestBundle 和 SOAP 类型我正在使用BeSimple Soap Bundle(这实际上并不相关,因为问题在于FOSRest 侦听器IMO,但我这样说是为了以防万一)。

问题是FOSRest 提供了一个监听器来处理响应并像这样序列化/呈现它们:

<?php
/**
 * @Rest\View
 */
public function getAction()
{
  return $item;
}

它处理将其序列化为JSON/XML 或其他任何内容的响应。 当我尝试调用我的 SOAP 服务并且听众对我大喊它不支持 SOAP 作为格式(它支持 JSON、XML 等)时,冲突就出现了。

当我将view_response_listener: 'force' 放入我的 FOSRest yml 配置文件时会发生这种情况。如果我将其更改为view_response_listener: 'enabled',SOAP 服务确实可以工作,但我似乎失去了自动处理我的响应的方便的 FOSRest 能力。

我怎样才能让FOSRest view_response_listener 只处理正确的响应,让SOAP Bundle 处理肥皂类型的响应。

编辑:

fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener: true
    view:
        view_response_listener: 'force' #This is the parameter that is driving me crazy. Value to 'force' Rest controllers work just fine SOAP don't, value to 'enabled' the other way around
        formats:
            xml: true
            json : true
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
    routing_loader:
        default_format: json

FOSRestBundle 配置。

这是我的routing.yml,用于 Rest 端点和 SOAP 端点:

#config/routing.yml
rest_api:
  resource:    "@RESTBundle/Resources/config/api_routes.yml"
  host:        "%host_front%" #api.myproject.local
  type:        rest

#api_routes.yml detail
accounts:
    resource:    'RESTBundle\Controller\AccountsController'
    type:        rest
    name_prefix: api_

#config/routing.yml
soap_api:
  resource: "@SOAPBundle/Resources/config/soap_routing.yml"
  host:     "%host_ws%"
  prefix:   "%contexto_ws%"

#soap_routing.yml detail
_besimple_soap:
  resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml"
soap_ws:
  resource: "@SOAPBundle/Controller/"
  type: annotation

RestController 示例:

<?php

namespace RESTBundle\Controller\API;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Nelmio\ApiDocBundle\Annotation\ApiDoc as ApiDoc;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Rest\RouteResource("accounts", pluralize=false)
 */
class AccountsController extends FOSRestController
{
    /**
     * @Rest\View
     */
    public function getAction($userId)
    {
        return [
          ['name' => 'Example', 'pass'=> 'example'],
          ['name' => 'Example2', 'pass'=> 'example2']
        ];
    }
}

SOAP 控制器:

/**
 * @Soap\Header("user", phpType="string")
 * @Soap\Header("token", phpType="string")
 */
class AccountsController implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    /**
     * @Soap\Method("getAccounts")
     * @Soap\Param("account", phpType="SOAPBundle\DataType\AccountFilter" )
     *
     * @Soap\Result(phpType="SOAPBundle\DataType\Account[]"")
     */
    public function getAccountsAction(Request $request, AccountFilter $filter)
    {
       return [(new Account())->setName('Example')->setPass('example')] //This is just an example
    }
}

编辑错误:

request.ERROR: 未捕获的 PHP 异常 Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: “不支持格式 'soap',必须实施处理程序”在 /home/teampro/Sites/corinto/vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php 第 292 行 {“异常”:“[对象] (Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException(代码: 0): 不支持格式“soap”,处理程序必须在 /.../vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php:292)"} []

【问题讨论】:

  • 请用config 更新您的问题,这很难读懂:) 另外,您能分享一下您的代码吗?
  • @Samundra Done,这不是我的代码(不能在这里发布),但它是一个基于它的虚拟示例,所以它大喊相同的东西。

标签: php symfony soap fosrestbundle


【解决方案1】:

您可以在 fos_rest 配置中定义如何让规则像 this 一样监听:

format_listener:
      rules:
        - { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true } # default routes
        - { path: '/soap', priorities: [xml], fallback_format: xml, prefer_extension: true } # your soap route
        - { path: '^/rest', priorities: [xml, json], fallback_format: xml, prefer_extension: true } # your rest route

希望有帮助!!

【讨论】:

  • 你有时间测试吗?我在服务器上制作了相同的 API,效果很好。
【解决方案2】:

首先,使用prefix 属性明确分离路由资源

# app/config/routing.yml
_besimple_soap:
  resource: "@BeSimpleSoapBundle/Resources/config/routing/webservicecontroller.xml"
  prefix:   "%contexto_ws%"

rest_api:
  resource:    "@RESTBundle/Resources/config/api_routes.yml"
  host:        "%host_front%" #api.myproject.local
  prefix:      /rest
  type:        rest

目前看来,您的 REST 控制器处理 WS 路由,因为它与配置重叠。用前缀分隔路由命名空间会有所帮助。

其次,验证请求主机,因为您的配置已经根据请求主机变量拆分路由

第三,检查路由配置

bin/console debug:router
bin/console router:match

【讨论】:

  • 它们是分开的,其余的有一个前缀:'api'(我只是忘了把它放在 OP 上)。无论如何,他们也有他们的 owm 主机。这与路由冲突无关,而是关于 FOS 侦听器试图处理所有 响应,甚至是 SOAP 响应。
猜你喜欢
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 2019-02-09
  • 2018-07-09
  • 1970-01-01
  • 2021-09-23
相关资源
最近更新 更多