BeSimple Soap 包和 FOSRest 包之间的冲突

Conflict between BeSimple Soap bundle and FOSRest Bundle

我正在为 REST 做一些 Rest 和一些 SOAP 服务我正在使用 FOSRestBundle 并且对于 SOAP 类型我正在使用 BeSimple Soap Bundle (这真的不是那么相关,因为问题出在 FOSRest listener IMO, 但我说是为了以防万一).

问题是 FOSRest 提供了一个监听器来处理响应,serialize/render 它们像这样:

<?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 处理 soap 类型的响应。

编辑:

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: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException: "Format 'soap' not supported, handler must be implemented" at /home/teampro/Sites/corinto/vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php line 292 {"exception":"[object] (Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException(code: 0): Format 'soap' not supported, handler must be implemented at /.../vendor/friendsofsymfony/rest-bundle/View/ViewHandler.php:292)"} []

您可以在 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

希望对您有所帮助!!

首先,用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