我正在做一些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'
放入我的forestyml配置文件时,就会发生这种情况。如果我将其更改为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
}
}
编辑错误:
请求。错误:未捕获的PHP异常Symfony '组件' HttpKernel ' ' UnsupportedMediaTypeHttpException异常:"不支持格式'soap',必须实现处理程序" at/home/teampro/Sites/corinto/vendor/friendsofsymfony/rest-bundle/视图/ViewHandler.php第292行{"exception":"[object]组件(Symfony ' ' HttpKernel '例外' UnsupportedMediaTypeHttpException(代码:0):格式'soap'不支持,处理程序必须在/…/供应商/friendsofsymfony/rest-bundle/视图/ViewHandler.php: 292)"}[]
您可以在fos_rest配置中定义如何使规则像这样侦听:
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