关于 java:Camel POST RestService 接受 JSONArray :注释和解析错误

Camel POST RestService accepting JSONArray : annotations and parsing errors

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Content-Type:application/json;charset=UTF-8

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

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

这里是路由定义:

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

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

1
2
3
4
5
6
7
8
9
10
11
@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:

1
2
3
4
5
6
7
public class CustomMessage {
    private String aaa;
    private String bbb;
    private int ccc;

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

当我在 POJO 上不使用注释时,我得到了这个异常:

1
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 解析异常:

1
2
3
4
5
6
7
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?

提前感谢您的帮助:)


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

所以,在 camel-context.xml 中我们定义了一个提供程序并在 osgi:

中安装了相关的库

1
2
3
4
5
6
7
<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>

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

1
2
3
4
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 对象数组:

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

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

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


我记得遇到过类似的问题(但与编组有关)。
解决方法是在列表周围定义一个package器,以便 Jackson 库现在能够解组您的 JSON 有效负载

1
2
3
4
5
6
7
8
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());
}

希望这会有所帮助。