Camel cxf REST 请求不分离查询参数
Camel cxf REST request not separating query parameters
我正在尝试通过本地 RESTful 网络服务发送一些消息。 URL 允许包含查询参数。我的 REST 方法处理器没有看到这些查询参数。有人看到我做错了什么吗?
我正在使用 Camel 2.16.0。
我的蓝图路线 XML 是:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf
http://camel.apache.org/schema/cxf/camel-cxf-blueprint.xsd">
<bean id="issPreprocessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.IssPreprocessor"/>
<bean id="webServiceProcessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.WebServiceProcessor"/>
<bean id="packageWebServiceReplyForIss" class="com.rockwellcollins.railwaynet.messagerouter.routing.PackageWebServiceReplyForIss"/>
<!-- These two cooperate to send web service requests to the mocked
out web service substitute. The crewMock bean handles requests sent
to the jetty service stand-in; the webService rsClient sends the
request.
-->
<bean id="steve" class="messagerouter.EmployeeInfo">
<argument value="Stephen"/>
<argument value="D."/>
<argument value="Huston"/>
<argument value="1234"/>
</bean>
<bean id="crewMock" class="messagerouter.CrewServiceMock">
<property name="info">
<map>
<entry key="rraa">
<map>
<entry key="steve" value-ref="steve"/>
</map>
</entry>
</map>
</property>
</bean>
<camel-cxf:rsClient id="webService" address="http://localhost:9000" serviceClass="com.rockwellcollins.railwaynet.messagerouter.routing.WebService" loggingFeatureEnabled="true"/>
<camelContext id="rraaCamelContext" xmlns="http://camel.apache.org/schema/blueprint">
<dataFormats>
<json id="IssRequest" library="Jackson"/>
</dataFormats>
<!-- Mocked out web service -->
<route id="CrewMock">
<from uri="jetty:http://localhost:9000?matchOnUriPrefix=true"/>
<to uri="cxfbean:crewMock"/>
</route>
<route id="rraaIss">
<from uri="seda:from_rraa"/>
<process ref="issPreprocessor"/>
<unmarshal ref="IssRequest"/>
<process ref="webServiceProcessor"/>
<to uri="cxfrs:bean:webService"/>
<process ref="packageWebServiceReplyForIss"/>
<to uri="seda:to_rraa"/>
</route>
</camelContext>
</blueprint>
我的WebServiceclass设置请求是:
public class WebServiceProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
exchange.setPattern(ExchangePattern.InOut);
Message in = exchange.getIn();
// Using proxy client API; needs the op name.
in.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.FALSE);
in.setHeader(CxfConstants.OPERATION_NAME, "verifyEmployee");
VerifyEmployeeRequest req = in.getBody(VerifyEmployeeRequest.class);
MessageContentsList params = new MessageContentsList();
params.add(req.getHeader().getScac());
params.add(req.getBody().getEmployeeID());
params.add(req.getBody().getPin());
params.add(req.getBody().getReason());
in.setBody(params);
}
}
我的服务调用接口 class 是:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}?pin={pin}&reason={reason}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@PathParam("pin") String pin,
@PathParam("reason") String reason);
}
处理请求的class是:
@Path("/rest")
public class CrewServiceMock {
// scac -> { id -> employeeInfo }
private Map<String, Map<String, EmployeeInfo> > info;
public Map<String, Map<String, EmployeeInfo> > getInfo()
{ return info; }
public void setInfo(Map<String, Map<String, EmployeeInfo> > info)
{ this.info = info; }
@GET
@Path("/authentication/{scac}/employees/{id}")
public Response getAuth(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("reason") String reason,
@QueryParam("pin") String pin) {
Map<String, EmployeeInfo> employees = info.get(scac);
if (employees == null) {
return Response.status(404).build();
}
System.out.println(employees);
System.out.println("id is " + id);
System.out.println("scac is " + scac);
System.out.println("reason is " + reason);
EmployeeInfo emp = (EmployeeInfo)employees.get(id);
if (emp == null) {
return Response.status(404).entity("{ message: \"id not found\" }").build();
}
return Response.status(200).entity("{ \"employeeID\": " + id + ", \"employeeName\": { \"first\": \"" + emp.getFirstName() + "\", \"middle\": \"" + emp.getMiddleName() + "\", \"last\": \"" + emp.getLastName() + "\" } }").build();
}
}
当我 运行 时,我在测试输出中看到以下内容:
[Camel (rraaCamelContext) 线程 #0 - seda://from_rraa] 信息 org.apache.cxf.interceptor.LoggingOutInterceptor - 出站消息
编号:1
地址:http://localhost:9000/rest/authentication/rraa/employees/steve%3Fpin=1234&reason=INIT
Http-Method:获取
Content-Type: application/xml
Headers: {OriginalHeader=[{name=VerifyEmployeeRequest, version=1, scac=rraa, timeSent=null, uuid=abcd-1234}], Content-Type=[application/xml], 接受=[application/json]}
{史蒂夫=messagerouter.EmployeeInfo@1dd62581}
id 是 steve?pin=1234&reason=INIT
scac 是 rraa
原因为空
因此,查询参数显然没有被解析出来——它们附加到最后一个路径参数。我做错了什么吗?
您的接口有 4 个路径参数,而不是 2 个路径和 2 个查询参数,它应该是:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("pin") String pin,
@QueryParam("reason") String reason);
}
我正在尝试通过本地 RESTful 网络服务发送一些消息。 URL 允许包含查询参数。我的 REST 方法处理器没有看到这些查询参数。有人看到我做错了什么吗?
我正在使用 Camel 2.16.0。
我的蓝图路线 XML 是:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf
http://camel.apache.org/schema/cxf/camel-cxf-blueprint.xsd">
<bean id="issPreprocessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.IssPreprocessor"/>
<bean id="webServiceProcessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.WebServiceProcessor"/>
<bean id="packageWebServiceReplyForIss" class="com.rockwellcollins.railwaynet.messagerouter.routing.PackageWebServiceReplyForIss"/>
<!-- These two cooperate to send web service requests to the mocked
out web service substitute. The crewMock bean handles requests sent
to the jetty service stand-in; the webService rsClient sends the
request.
-->
<bean id="steve" class="messagerouter.EmployeeInfo">
<argument value="Stephen"/>
<argument value="D."/>
<argument value="Huston"/>
<argument value="1234"/>
</bean>
<bean id="crewMock" class="messagerouter.CrewServiceMock">
<property name="info">
<map>
<entry key="rraa">
<map>
<entry key="steve" value-ref="steve"/>
</map>
</entry>
</map>
</property>
</bean>
<camel-cxf:rsClient id="webService" address="http://localhost:9000" serviceClass="com.rockwellcollins.railwaynet.messagerouter.routing.WebService" loggingFeatureEnabled="true"/>
<camelContext id="rraaCamelContext" xmlns="http://camel.apache.org/schema/blueprint">
<dataFormats>
<json id="IssRequest" library="Jackson"/>
</dataFormats>
<!-- Mocked out web service -->
<route id="CrewMock">
<from uri="jetty:http://localhost:9000?matchOnUriPrefix=true"/>
<to uri="cxfbean:crewMock"/>
</route>
<route id="rraaIss">
<from uri="seda:from_rraa"/>
<process ref="issPreprocessor"/>
<unmarshal ref="IssRequest"/>
<process ref="webServiceProcessor"/>
<to uri="cxfrs:bean:webService"/>
<process ref="packageWebServiceReplyForIss"/>
<to uri="seda:to_rraa"/>
</route>
</camelContext>
</blueprint>
我的WebServiceclass设置请求是:
public class WebServiceProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
exchange.setPattern(ExchangePattern.InOut);
Message in = exchange.getIn();
// Using proxy client API; needs the op name.
in.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.FALSE);
in.setHeader(CxfConstants.OPERATION_NAME, "verifyEmployee");
VerifyEmployeeRequest req = in.getBody(VerifyEmployeeRequest.class);
MessageContentsList params = new MessageContentsList();
params.add(req.getHeader().getScac());
params.add(req.getBody().getEmployeeID());
params.add(req.getBody().getPin());
params.add(req.getBody().getReason());
in.setBody(params);
}
}
我的服务调用接口 class 是:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}?pin={pin}&reason={reason}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@PathParam("pin") String pin,
@PathParam("reason") String reason);
}
处理请求的class是:
@Path("/rest")
public class CrewServiceMock {
// scac -> { id -> employeeInfo }
private Map<String, Map<String, EmployeeInfo> > info;
public Map<String, Map<String, EmployeeInfo> > getInfo()
{ return info; }
public void setInfo(Map<String, Map<String, EmployeeInfo> > info)
{ this.info = info; }
@GET
@Path("/authentication/{scac}/employees/{id}")
public Response getAuth(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("reason") String reason,
@QueryParam("pin") String pin) {
Map<String, EmployeeInfo> employees = info.get(scac);
if (employees == null) {
return Response.status(404).build();
}
System.out.println(employees);
System.out.println("id is " + id);
System.out.println("scac is " + scac);
System.out.println("reason is " + reason);
EmployeeInfo emp = (EmployeeInfo)employees.get(id);
if (emp == null) {
return Response.status(404).entity("{ message: \"id not found\" }").build();
}
return Response.status(200).entity("{ \"employeeID\": " + id + ", \"employeeName\": { \"first\": \"" + emp.getFirstName() + "\", \"middle\": \"" + emp.getMiddleName() + "\", \"last\": \"" + emp.getLastName() + "\" } }").build();
}
}
当我 运行 时,我在测试输出中看到以下内容:
[Camel (rraaCamelContext) 线程 #0 - seda://from_rraa] 信息 org.apache.cxf.interceptor.LoggingOutInterceptor - 出站消息
编号:1 地址:http://localhost:9000/rest/authentication/rraa/employees/steve%3Fpin=1234&reason=INIT Http-Method:获取 Content-Type: application/xml
Headers: {OriginalHeader=[{name=VerifyEmployeeRequest, version=1, scac=rraa, timeSent=null, uuid=abcd-1234}], Content-Type=[application/xml], 接受=[application/json]}
{史蒂夫=messagerouter.EmployeeInfo@1dd62581} id 是 steve?pin=1234&reason=INIT scac 是 rraa 原因为空
因此,查询参数显然没有被解析出来——它们附加到最后一个路径参数。我做错了什么吗?
您的接口有 4 个路径参数,而不是 2 个路径和 2 个查询参数,它应该是:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("pin") String pin,
@QueryParam("reason") String reason);
}