骆驼POST RestService接受JSONArray:注释和解析错误

时间:2018-10-19 14:11:27

标签: java json apache-camel

我正在尝试构建Apache Camel(v2.15)路由来处理REST服务上的POST请求。

预期的POST请求将如下所示(一个JSONArray,代表一个JSONObject列表,这些列表都是单个给定类型的所有实例):

Content-Type:application/json;charset=UTF-8

[
    {
        "aaa": "TEST",
        "bbb": "TEST",
        "ccc": 5004000
    },
    {
        "aaa": "TEXT",
        "bbb": "TEXT",
        "ccc": 5004001
    },
    ...
]

我的问题是配置东西以使POST正文正确地未序列化...

这是路线定义:

from("cxfrs:bean:messageServer").choice()
        .when(header("operationName").isEqualTo("postJsonMessage"))
        .beanRef("messageService", "postJsonMessage")
        .end();

现在,通过beanRef行引用的服务定义:

@Path("/root-path/")
public class MyService {
    private final Logger logger = LoggerFactory.getLogger(MyService.class);

    @POST
    @Path("/message/")
    @Consumes(MediaType.APPLICATION_JSON + ";charset=UTF-8")
    public void postJsonMessage(@Body final List<CustomMessage> data) {
        logger.info("body size :" + data.size());
    }
}

以及描述未序列化列表项的POJO:

public class CustomMessage {
    private String aaa;
    private String bbb;
    private int ccc;

    // ...getters and setters...
}

当我在POJO上不使用任何注释时,出现此异常:

JAXRSUtils | 152 - org.apache.cxf.cxf-core - 3.0.6 | No message body reader has been found for class java.util.List, ContentType: application/json;charset=UTF-8

但是,如果我在POJO上使用 @XMLRootElement ,则会收到JSON解析异常:

AbstractJAXBProvider | 152 - org.apache.cxf.cxf-core - 3.0.6 | javax.xml.stream.XMLStreamException: ParseError at [row,col]:[0,1] Message: A JSONObject text must begin with '{' at character 1 of [
    {
        "aaa": "TEST",
        "bbb": "TEST",
        "ccc": 5004000
    },
    ...

那么我如何配置解析器以将发布的数据解释为JSONArray而不是JSONObject?

在此先感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

最后,通过使用org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider@Body参数的数组类型定义,找到了解决我问题的方法:

因此,在camel-context.xml中,我们定义了一个提供程序并将相关的库安装在osgi中:

<cxf:rsServer id="messageServer"
    address="http://0.0.0.0:${rest.service.message.port}"
    serviceClass="com.example.service.MyService">
    <cxf:providers>
        <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider" />
    </cxf:providers>
</cxf:rsServer>

(在我们的环境中)所需的库是

install mvn:org.codehaus.jackson/jackson-core-asl/1.9.12
install mvn:org.codehaus.jackson/jackson-mapper-asl/1.9.12
install mvn:org.codehaus.jackson/jackson-jaxrs/1.9.12
install mvn:org.codehaus.jackson/jackson-xc/1.9.12

然后,修改了服务方法签名以期望包含CustomMessage个对象的数组:

    @POST
    @Path("/message/")
    @Consumes(MediaType.APPLICATION_JSON + ";charset=UTF-8")
    public void postJsonMessage(@Body final CustomMessage[] data) {
        // process data...
    }

此外,在路由生成器中添加了类型定义:

    from("cxfrs:bean:messageServer").choice()
            .when(header("operationName").isEqualTo("postJsonMessage"))
            .convertBodyTo(CustomMessage[].class)
            .beanRef("messageService", "postJsonMessage")
            .end();

答案 1 :(得分:0)

我记得曾经遇到过类似的问题(但是要进行编组)。 解决方法是在列表周围定义一个包装器,以便Jackson库现在可以解组JSON有效负载

public class CustomMessageList extends ArrayList<CustomMessage> {};

@POST
@Path("/message/")
@Consumes(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public void postJsonMessage(@Body final CustomMessageList data) {
   logger.info("body size :" + data.size());
}

希望这会有所帮助。