【问题标题】:What is the secret to successfully calling a REST/POST operation using the "to" method in the RouteBuilder class?使用 RouteBuilder 类中的“to”方法成功调用 REST/POST 操作的秘诀是什么?
【发布时间】:2017-08-22 19:08:49
【问题描述】:

我有一个 JAX-RS 休息服务,其 POST 方法如下所示:

...
@Path("/post1/")
@POST
@Produces({MediaType.TEXT_PLAIN})
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response post(@Context javax.servlet.http.HttpServletRequest request, ContainerListType containerListType) throws Exception, Throwable, RuntimeException {

    Response response = null;
    try {
        List<ContainerType> containerList = containerListType.getContainer();  <=== null value:  "containerListType" is null!
        ContainerType ct = containerList.get(0);
        URI uri = UriBuilder.fromUri(uriInfo.getRequestUri()).path(ct.getFielda()).path(ct.getFieldb()).path(ct.getFieldc()).build();
        response = Response.created(uri).build();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return response;
}
...
    
    

(注意:使用工具测试上述 POST 操作 - 即,像 FireFox 插件:“HttpRequestor” - 适用于发布 - JSON 和 XML 消息。)

我正在尝试使用“to”进行 POST 操作。方法如下图(在RouteBuilder类中)。

...
    from("direct:thingH")
            .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    exchange.getIn().setBody("{'container':[{'fielda': '...this is fielda value...','fieldb': '...this is fielda value...','fieldc': '...this is fielda value...'}]}");
                }
            })
            .log("---------------------- (from(\"direct:thingH\")) ----------------------> process yields...:" + body().toString())                
            .to("restlet:http://localhost:7001/jaxrsRestService/service/post1/?restletMethod=POST&exchangePattern=InOut");
...

注意:日志条目似乎表明“正文”不为空:

2017-08-24 11:17:19,488 | INFO  | stlet-1261331139 | route42                          | 232 - org.apache.camel.camel-core - 2.17.0.redhat-630187 | ---------------------- (from("direct:thingH")) ----------------------> process yields...:simple{{'container':[{'fielda': '...this is fielda value...','fieldb': '...this is fielda value...','fieldc': '...this is fielda value...'}]}}

但执行 post 方法会产生 java.lang.NullPointerException - 即 REST 服务的 POST 方法中的“containerListType”参数为空。这是为什么呢?

...
java.lang.NullPointerException
    at aaa.bbb.ccc.JaxrsRestService.post(JaxrsRestService.java:51)
    at sun.reflect.GeneratedMethodAccessor949.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3679)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3649)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
    at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
    at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259)
    at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1691)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1651)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270)
    at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
    at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
    at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
    at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
    at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
...     

发生 NullPointerException 是因为调用“post1”方法时,POST 的“ContainerListType”值为 null:为什么是 null?

是否以这种方式调用 REST/POST 操作 - 即,以任何方式使用“to()”方法不正确/不正确?:

.to("restlet:http://localhost:7001/jaxrsRestService/service/post1/?restletMethod=POST&exchangePattern=InOut");

或者,我是否需要从处理器内部执行客户端 REST 调用?

为什么发布的对象为空? FWIW:我在发布之前检查了 body() - 使用日志记录 - 它不为空。

其他环境信息:

jdk1.8.0_131
jboss-fuse-6.3.0.redhat-187
WebLogic 12.2.1  (running the rest service)

【问题讨论】:

  • 这个问题 [ibm-mq] 的任何部分是否相关?
  • 好点,乔希。我现在将删除该标签引用。谢谢!
  • 如果我是你,我会简单地编写一个测试来测试 restlet 端点,而不是挖掘大量代码。 FWIW,我在文档中没有看到任何 POST 生产者的示例,但是 Camel 文档的质量并不是非常高。
  • 嗨 Abhijit - 不确定你的意思。使用 HttpRequestor 之类的工具从外部进行测试时,端点可以工作。我同意,Camel 文档经常过时。不容易确定明确/当前的例子。它们通常也偏向“弹簧”方向。

标签: apache-camel jax-rs jbossfuse blueprint-osgi


【解决方案1】:

是的,你可以这样写。文档中也是这么说的。

.to("restlet:http://localhost:" + port + "/securedOrders?restletMethod=post");

您确定该进程实际上是在向正文返回某些内容以使 POST 正文不为空吗?我的意思是这里;

 from("direct:thingH")
            .process(proc1)  

进程是否返回一个主体?

【讨论】:

  • 嗨 Souciance - 是的,process() 函数正在返回一个值...这是一个日志: process(proc1) 产生...:simple{{'container':[{'fielda ': '...这是字段值...','fieldb': '...这是字段值...','fieldc': '...这是字段值...'}] }}谢谢
【解决方案2】:

尝试将 Content-Type 标头设置为application/xml(或application/json

.process(proc1)               
.setHeader(Exchange.CONTENT_TYPE, constant(MediaType.APPLICATION_XML))
.to("restlet:...");

【讨论】:

  • 您的处理器设置了out 消息,尝试像这样设置in 消息:exchange.getIn().setBody("{'container':[...]")
  • 嗨 mgyongyosi - 看来谜团还在继续。尽管将“.getOut”更改为“getIn”,但我们得到了相同的结果。 -还有其他想法吗?谢谢!
【解决方案3】:

*无法让“restlet”工作... - 选择工作的“netty4-http”*

src/main/java/aaa/bbb/ccc/CamelRestRoutes.java

package aaa.bbb.ccc;

import javax.ws.rs.core.MediaType;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.cdi.ContextName;
import org.apache.camel.model.rest.RestBindingMode;

@ContextName("rest-dsl")
public class CamelRestRoutes extends RouteBuilder {

    public CamelRestRoutes() {
    }

    private final org.apache.camel.Processor proc1 = new Processor1();

    @Override
    public void configure() throws Exception {

    restConfiguration().component("netty4-http")
        .host("localhost")
        .port(8182)
        .bindingMode(RestBindingMode.json)
        .enableCORS(true);

    rest("/service")
        .get("/getAll").produces(MediaType.APPLICATION_JSON).to("direct:thingC") 
        .post("/post1").produces(MediaType.APPLICATION_JSON).to("direct:thingD");                             

    from("direct:thingC")
        .setHeader(Exchange.HTTP_METHOD, constant(org.apache.camel.component.http4.HttpMethods.GET))
        .to("netty4-http:http://localhost:7001/jaxrsRestService/service/getAll")
        .to("direct:thingD");

    from("direct:thingD")
        .process(proc1)                    
        .setHeader(Exchange.HTTP_METHOD, constant(org.apache.camel.component.http4.HttpMethods.POST))
        .to("netty4-http:http://localhost:7001/jaxrsRestService/service/post1");
    }
}

src/main/java/aaa/bbb/ccc/Processor1.java

package aaa.bbb.ccc;

import org.apache.camel.Message;

public class Processor1 implements org.apache.camel.Processor {

    private Message inMsg;

    @Override
    public void process(org.apache.camel.Exchange exchange) {
    String s = "{\"container\": [{\"fielda\": \"...this is fielda valueAAA...\",\"fieldb\": \"...this is fielda valueBBB...\",\"fieldc\": \"...this is fielda valueCCC...\"}]}"; //"{'container':[{'fielda': '...this is fielda value...','fieldb': '...this is fielda value...','fieldc': '...this is fielda value...'}]}";
    exchange.getIn().setBody(s);        
    }
};

src/main/resources/OSGI-INF/blueprint/camel-routes.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:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
       xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
       xmlns:camel="http://camel.apache.org/schema/blueprint"
       xsi:schemaLocation="
         http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
         http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
         http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
         ">
    <camel:camelContext id="aaa.bbb.ccc.routing.poc" xmlns="http://camel.apache.org/schema/blueprint">
    <packageScan>
        <package>aaa.bbb.ccc</package>
    </packageScan>
    </camel:camelContext>

    <bean id="camelRestService" class="aaa.bbb.ccc.CamelRestService"/> 

    <bean id="wmqcf" class="com.ibm.mq.jms.MQConnectionFactory">
    <property name="hostName" value="localhost"/>        
    <property name="port" value="1414"/>
    <property name="queueManager" value="QM1"/>     
    <property name="channel" value="DEV.ADMIN.SVRCONN"/>                     
    <property name="transportType" value="1"/>
    </bean>

    <bean id="wmqcfw"  class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
    <property name="targetConnectionFactory" ref="wmqcf" />
    <property name="username" value="admin" />
    <property name="password" value="passw0rd" />
    </bean>  

    <bean id="wmqcfg" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="wmqcfw"/>
    <property name="concurrentConsumers" value="10"/>
    </bean>

    <bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
    <property name="configuration" ref="wmqcfg"/>     
    </bean>    
</blueprint>

jaxrsRestService.java - 提供上下文,这就是 REST 服务(POST 和 GET)的样子...

package aaa.bbb.ccc;

import aaa.bbb.ccc.generated.ContainerListType;
import aaa.bbb.ccc.generated.ContainerType;
import aaa.bbb.ccc.generated.ObjectFactory;
import java.net.URI;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

@Path("/service/")
public class JaxrsRestService {

    @Context
    UriInfo uriInfo;

    @Path("/post1/")
    @POST
    @Produces({MediaType.TEXT_PLAIN})
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public Response post(@Context javax.servlet.http.HttpServletRequest request, ContainerListType containerListType) throws Exception, Throwable, RuntimeException {
    Response response = null;
    try {
        List<ContainerType> containerList = containerListType.getContainer();
        ContainerType ct = containerList.get(0);
        URI uri = UriBuilder.fromUri(uriInfo.getRequestUri()).path(ct.getFielda()).path(ct.getFieldb()).path(ct.getFieldc()).build();
        response = Response.created(uri).build();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return response;
    }

    @Path("/getAll/")
    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public ContainerListType getAll(
        @Context javax.servlet.http.HttpServletRequest request
    ) {
    ObjectFactory of = new ObjectFactory();
    ContainerListType clt = of.createContainerListType();
    ContainerType ct = of.createContainerType();
    ct.setFielda("...this is fielda value...");
    ct.setFieldb("...this is fielda value...");
    ct.setFieldc("...this is fielda value...");
    clt.getContainer().add(ct);

    return clt;
    }
}

“已安装”camel 功能的快照...以防万一

JBossFuse:karaf@root> features:list | grep "camel-" | grep  "\[installed"
[installed  ] [2.7.0                ] xml-specs-api                                 camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel                                         camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-core                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-blueprint                               camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-spring                                  camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-bindy                                   camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-cdi                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-csv                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-cxf                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-exec                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-ftp                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-http4                                   camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jackson                                 camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jacksonxml                              camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jasypt                                  camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jaxb                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jdbc                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jms                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-jmx                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-mail                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-netty4                                  camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-netty4-http                             camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-ognl                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-paxlogging                              camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-restlet                                 camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-rmi                                     camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-routebox                                camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-saxon                                   camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-script                                  camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-snmp                                    camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-spring-javaconfig                       camel-2.17.0.redhat-630187
[installed  ] [2.17.0.redhat-630187 ] camel-xstream                                 camel-2.17.0.redhat-630187
[installed  ] [1.2.0.redhat-630187  ] camel-amq                                     fabric-1.2.0.redhat-630187
JBossFuse:karaf@root>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 2010-10-05
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多