Java 我们为什么使用<;cxf:rsServer>;与平原相对<;jaxrs:server>;使用CXF-RS组件时?
作为后续工作,我仍然对如何正确使用CXF-RS组件感到困惑 我不明白为什么我们需要Java 我们为什么使用<;cxf:rsServer>;与平原相对<;jaxrs:server>;使用CXF-RS组件时?,java,spring,web-services,apache-camel,cxfrs,Java,Spring,Web Services,Apache Camel,Cxfrs,作为后续工作,我仍然对如何正确使用CXF-RS组件感到困惑 我不明白为什么我们需要标记来指定CXF-RS端点(或者甚至有这样的概念吗?),而我可以很好地使用标记 以下是我针对Camel和CXF的配置XML: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x
标记来指定CXF-RS端点(或者甚至有这样的概念吗?),而我可以很好地使用
标记
以下是我针对Camel和CXF的配置XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<jaxrs:server id="userService" address="/users">
<jaxrs:serviceBeans>
<bean class="com.example.UserServiceNoop" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<bean id="user" class="org.apache.camel.component.direct.DirectComponent" />
<camel:camelContext id="someCamelContext">
<camel:route id="userServiceRoute">
<camel:from uri="cxfrs:bean:userService" />
<camel:routingSlip>
<camel:simple>user:${header.operationName}</camel:simple>
</camel:routingSlip>
</camel:route>
<camel:route id="userServiceRetrieveUser">
<from uri="user:retrieveUser" />
<!-- Assume this is going to a useful Processor -->
</camel:route>
</camel:camelContext>
</beans>
userservicenop.java
package com.example;
/* a bunch of imports ... */
public class UserServiceNoop implements UserService
{
@Override
public User retrieveUser(Integer id) {
throw new RuntimeException();
}
}
在本例中,我没有使用任何
标记,但它工作正常。我知道它是通过CXF-RS组件实现的,因为当我运行应用程序时,它不会抛出任何运行时异常
,这是使用CXF-RS时的预期行为(不会调用服务类中的方法实现)
如果不使用此标记,是否丢失了某些内容?如果要使用cxf endpoint作为某些内容的使用者,请使用cxf:reserver标记。例如,在复杂的apachecamel路由或Spring集成中。当您是端点服务请求的提供者时使用。正如另一个答案所说,
cxf:rsServer
主要用于通过驼峰路由进行处理,就像在jaxrs:server
中一样,请求的处理由经典控制器完成
例如:
@Produces({ MediaType.APPLICATION_XML })
@Path("/")
public class DeviceServiceRest {
@GET
public Response listDevicess(
@QueryParam("model") String model,
@QueryParam("sid") String sid,
) {
return null; // never used
}
@GET
@Path("{id}")
public Response getDeviceById(
@PathParam("id") String id,
@QueryParam("model") String model,
@QueryParam("sid") String sid
){
return null; // never used
}
}
REST控制器有空方法(返回null),但我认为最新的camel cxf
现在支持接口
,它比返回null
的方法更优雅。
现在,请求处理可以通过驼峰路由实现,如下所示:
from("cxfrs:bean:rsServer?synchronous=true")
.routeId("cxf-device-rest-v1")
.process( new CheckAuthenticationProcessor())
.choice()
.when(header("operationName").isEqualTo("listDevice"))
.setHeader("backenOperation").constant("list")
.setHeader("backendResource").constant("device")
.endChoice()
.when(header("operationName").isEqualTo("getDeviceById"))
.setHeader("backenOperation").constant("retrieve")
.setHeader("backendResource").constant("device")
.endChoice()
.end()
.bean("requestProcessor")
.to(InOut, backendEndpoint)
.process(checkResponseStatusCode())
.bean(new HttpResponseProcessor())
;
您还可以根据需要从路由控制请求/响应处理
这是两种实现RESTAPI(服务器端)的不同类型,但在我看来,这有点老派,因为像SpringBoot这样的现代框架不需要这些
我发现第二种方法有点过分,因为出于集成目的我喜欢Camel,但将其用于restapi可能会引起讨论。
我可以看到的一个用例是用于异步处理的HTTP REST Web服务,服务响应202被接受,驼峰路由以异步模式集成请求,特别是当可以轻松使用特定的驼峰组件而不是复杂类(或任何EIP模式的需要)时
<cxf:rsServer id="rsServer" address="/device/v1"
serviceClass="org.mycomp.device.rest.v1.ws.api.DeviceServiceRest">
<cxf:properties>
<!-- whatever here -->
</cxf:properties>
<!-- and other interceptors, etc... here -->
</cxf:rsServer>
@Produces({ MediaType.APPLICATION_XML })
@Path("/")
public class DeviceServiceRest {
@GET
public Response listDevicess(
@QueryParam("model") String model,
@QueryParam("sid") String sid,
) {
return null; // never used
}
@GET
@Path("{id}")
public Response getDeviceById(
@PathParam("id") String id,
@QueryParam("model") String model,
@QueryParam("sid") String sid
){
return null; // never used
}
}
from("cxfrs:bean:rsServer?synchronous=true")
.routeId("cxf-device-rest-v1")
.process( new CheckAuthenticationProcessor())
.choice()
.when(header("operationName").isEqualTo("listDevice"))
.setHeader("backenOperation").constant("list")
.setHeader("backendResource").constant("device")
.endChoice()
.when(header("operationName").isEqualTo("getDeviceById"))
.setHeader("backenOperation").constant("retrieve")
.setHeader("backendResource").constant("device")
.endChoice()
.end()
.bean("requestProcessor")
.to(InOut, backendEndpoint)
.process(checkResponseStatusCode())
.bean(new HttpResponseProcessor())
;