在WLP 8.5.5.8上运行的JAX-RS应用程序中发布JSON时抛出异常

时间:2016-01-29 20:41:25

标签: json jax-rs websphere-liberty

我有一个非常简单的Java应用程序,使用JAX-RS,在WLP 8.5.5.8上运行。当我发布复合结构的JSON时,我收到此错误:

  

[ERROR]错误处理期间出错,放弃!无效的类型   有价值的。键入:[java.util.LinkedHashMap],其值为:[{d = e}] [错误   ] SRVE0777E:应用程序类抛出的异常   ' org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'   java.lang.RuntimeException:org.apache.cxf.interceptor.Fault:无效   价值的类型。键入:[java.util.LinkedHashMap],其值为:[{d = e}]     在   org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)     在[内部类]引起:org.apache.cxf.interceptor.Fault:   无效的值类型。键入:[java.util.LinkedHashMap],其值为:   [{d = e}] at   org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:76)     ... 1更多引起:java.lang.IllegalArgumentException:无效   价值的类型。键入:[java.util.LinkedHashMap],其值为:[{d = e}]     在com.ibm.json.java.JSONObject.put(JSONObject.java:241)... 1更多

当我对资源执行POST并且json对象包含属性为json数组或json对象时,在到达函数之前抛出异常

导致此问题的示例JSON(如果我删除" c"属性,它可以正常工作):

{
    "a": "b",
    "c": {
        "d": "e"
    }
}

如果" c"会抛出同样的错误是一个数组:

{
    "a": "b",
    "c": [
        {"d": "e"},
        {"d": "f"},
        {"d": "g"}
    ]
}

我没有添加任何我自己的库,所有这些都包含在WLP中。如果我在WLP 8.5.5.3上运行此示例,它可以正常工作。任何想法我都缺少,因为我发现很难相信这个简单的样本会暴露缺陷吗?

这是我的资源:

RootResouce.java

package com.sample;

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.MediaType;
import javax.ws.rs.core.Response;

import com.ibm.json.java.JSONObject;

@Path("/hello")
public class RootResource {

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response postTest(JSONObject json) {
        return Response.ok(json).build();
    }
}

这是我的应用:

package com.sample;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

public class MyApp extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(RootResource.class);
        return s;
    }
}

这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <description>Simple Test service</description>
        <display-name>sample</display-name>
        <servlet-name>sample</servlet-name>
        <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.sample.MyApp</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <enabled>true</enabled>
        <async-supported>false</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>sample</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <display-name>SimpleTest</display-name>
</web-app>

1 个答案:

答案 0 :(得分:4)

再看一下提供的代码,我在异常中看到了这一点:

    Caused by: java.lang.IllegalArgumentException: Invalid type of value.  Type: [java.util.LinkedHashMap] with value: [{d=e}]
at com.ibm.json.java.JSONObject.put(JSONObject.java:241)
at org.codehaus.jackson.map.deser.MapDeserializer._readAndBind(MapDeserializer.java:244)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:166)
at org.codehaus.jackson.map.deser.MapDeserializer.deserialize(MapDeserializer.java:24)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1961)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:889)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:410)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1356)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1307)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:847)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:810)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:255)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:85)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307

也许jax-rs 1.1和2.0之间的默认json提供程序发生了变化?将Jackson的请求数据反序列化为json4j对象并不顺利。像这样设置提供程序似乎允许它工作:

    import com.ibm.websphere.jaxrs.providers.json4j.JSON4JArrayProvider;
    import com.ibm.websphere.jaxrs.providers.json4j.JSON4JObjectProvider;

    public class MyApp extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(RootResource.class);
        s.add(JSON4JObjectProvider.class);
        s.add(JSON4JArrayProvider.class);
        return s;
    }