代码之家  ›  专栏  ›  技术社区  ›  Kimble

Jersey/JAXB:对空json数组的解组将导致一个列表中有一个项,其中所有字段都设置为空

  •  6
  • Kimble  · 技术社区  · 14 年前

    我有一个非常简单的rest web服务返回一个问题列表。当返回的问题数大于零时,此代码按预期工作。但是,如果服务器返回一个空的json数组,比如[],JAXB会创建一个带有一个问题实例的列表,其中所有字段都设置为空!

    我对Jersey和JAXB都不熟悉,所以我不知道我是否没有正确配置它,或者这是否是一个已知的问题。有什么建议吗?

    客户端配置:

     DefaultApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
     config.getProperties().put(DefaultApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES, true);
     config.getClasses().add(JAXBContextResolver.class);
     //config.getClasses().add(JacksonJsonProvider.class); // <- Jackson causes other problems
    
     client = ApacheHttpClient.create(config);
    

    JAXBContextResolver:

    @Provider
     public final class JAXBContextResolver implements ContextResolver<JAXBContext> {
    
      private final JAXBContext context;
      private final Set<Class> types;
      private final Class[] cTypes = { Question.class };
    
      public JAXBContextResolver() throws Exception {
       this.types = new HashSet(Arrays.asList(cTypes));
       this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), cTypes);
      }
    
      @Override
      public JAXBContext getContext(Class<?> objectType) {
       return (types.contains(objectType)) ? context : null;
      }
    
     }
    

    客户代码:

    public List<Question> getQuestionsByGroupId(int id) {
        return digiRest.path("/questions/byGroupId/" + id).get(new GenericType<List<Question>>() {});
    }
    

    问题类只是一个简单的pojo。

    2 回复  |  直到 14 年前
        1
  •  0
  •   Samuel EUSTACHI    13 年前

    我知道这并不能完全回答你的问题,但我选择在泽西岛上使用GSON,用于我目前的项目。(我尽量避免使用JAXB),我发现它非常简单,而且很有弹性。

    你只要申报

    @Consumes(MediaType.TEXT_PLAIN)
    

    @Produces(MediaType.TEXT_PLAIN)
    

    或者同时使用GSON marshaller/unmarshaller,并使用纯字符串。很容易调试,unittest也很容易。。。

        2
  •  0
  •   wyck    12 年前

    使用 Jackson 可能有帮助。 见 org.codehaus.jackson.map.ObjectMapper org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_EMPTY

    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.annotate.JsonSerialize;
    
    public class SampleContextResolver implements ContextResolver<ObjectMapper>
    {
            @Override
            public ObjectMapper getContext(Class<?> type)
            {
                ObjectMapper mapper = new ObjectMapper();
    
                mapper.setSerializationConfig(mapper.getSerializationConfig()
                    .withSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY)
            }
    }