【问题标题】:How do I return JSON without parent tag on JAX-RS?如何在 JAX-RS 上返回没有父标签的 JSON?
【发布时间】:2019-04-25 12:56:00
【问题描述】:

我正在尝试为 Liferay 创建一个 REST API 模块,但在尝试从我的网络服务生成 JSON 响应时遇到了问题。

我想生成一个像这样的简单 JSON:

{
    "status": "ok",
    "message": "News not found for ID: 5"
}

但是,这就是我得到的:

{
    "parentResponse": {
        "status": "ok",
        "message": "News not found for ID: 5"
    }
}

这是我的 POJO 类:

@XmlRootElement
public class ParentResponse {

    public String status, message;
    public Object item;

    public ParentResponse() {

    }

    public ParentResponse(String status, String message, Object item) {
        this.status = status;
        this.message = message;
        this.item = item;
    }   
}

返回 json 的我的网络服务:

// return a single news based on supplied ID
    @GET
    @Path("{id}")
    @Produces("application/json")
    public Response getNewsById(@PathParam("id") String id) {
        ResponseBuilder builder;
        try {
            News news = findById(new Long(id));
            if (news != null) {
                builder = Response.ok(news);
            } 
            else { // This is my POJO class returned as a JSON
                ParentResponse parentResponse = new ParentResponse("ok", "News not found for ID: " + id, null);

                builder = Response.status(Response.Status.NOT_FOUND).entity(parentResponse);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return builder.build();
    }

那么,如何获取没有根标签的 JSON?我尝试在 @XmlRootElement 注释旁边添加 (name=""),但这不起作用。

【问题讨论】:

  • 你不尝试使用 jackson 来编组你的 bean 吗?
  • 如何将它添加到我的项目的 build.gradle 文件中?我试图添加这个:compileInclude group: 'com.fasterxml.jackson.core', name: 'jackson-core' 但这不起作用。
  • 尝试在模块的 build.gradle 中添加以下行:compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.9.0" compile "com.fasterxml.jackson.core:jackson-annotations:2.9.0"
  • 感谢@javaxiss 这似乎有效。但是现在,我该怎么办?
  • 您应该在模型属性 (ParentResponse) 上使用 @JsonProperty,如下所示:@JsonInclude(JsonInclude.Include.NON_EMPTY) public class ParentResponse { @JsonProperty("message") public String message; @JsonProperty("status") public String status; ... }

标签: java json jax-rs liferay


【解决方案1】:

我建议您使用 jackson 提供程序来编组/解组 json 输入/输出(就像我在 cmets 中对您的帖子所做的那样):

compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.9.0" 
compile "com.fasterxml.jackson.core:jackson-annotations:2.9.0"

您的模型应如下所示:

@JsonInclude(JsonInclude.Include.NON_EMPTY) 
public class ParentResponse { 

  @JsonProperty("message") 
  public String message; 

  @JsonProperty("status") 
  public String status; 

//... 

}

如果您使用 Liferay 7,我建议您也利用 OSGi,通过创建一个调用您的服务端点 (Response getNewsById(@PathParam("id") String id)) 的服务。当您的 OSGi 服务启动时,它应该设置 jackson 提供程序并设置 Web 服务端点 url ...以及其他任何东西来初始化您的服务。


@Component(immediate = false)
public class WonderfulOsgiService{

    private MyWebService myWebService;

    public Response getNews( String id) {
        return myWebService.getNewsById(id);
    }


    @Activate
    @Modified
    private void activate(Map<String, Object> config) {
        // Creates jackson provider for marshalling/unmarshalling json
        ObjectMapper myMapper = new ObjectMapper();
        myMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
        JacksonJsonProvider provider = new JacksonJsonProvider(myMapper);
        provider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        List<Object> providers = new ArrayList<>();
        providers.add(provider);


        //web service endpoint address
        String address = "http://my-web-service-address.com/url/"
        //MyWebService is the class containing getNewsById(id)
        myWebService = JAXRSClientFactory.create(address, MyWebService.class, providers);   

    }

【讨论】:

    【解决方案2】:

    如果您使用具有 CXF 的 Jettison 支持的 Liferay 7.1,您可以通过将配置文件添加到 /configs 目录来配置它:

    org.apache.aries.jax.rs.jaxb.json.cfg 内容:

    drop.collection.wrapper.element=true
    drop.root.element=true
    serialize.as.array=true
    support.unwrapped=true
    

    从 Liferay 7.2 开始,Liferay 将 Jackson 作为默认的 JAXB 提供程序。

    请注意,Liferay 中的 OSGi JAX-RS 白板支持允许您切换 JSON 提供程序,而无需更改应用程序的代码。您可以在https://github.com/apache/aries-jax-rs-whiteboard/tree/master/integrations中找到不同的集成

    或者如何在 Liferay 中提供 jackson 支持(如果不是在 7.2 中,包括在内)与这里的依赖关系:https://github.com/liferay/liferay-portal/blob/7.2.x/modules/apps/portal-remote/portal-remote-jaxrs-whiteboard-jaxb-json/build.gradle

    只需确保替换 CXF 抛弃的那些,这可能会对依赖它的其他捆绑包产生副作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 2012-11-29
      相关资源
      最近更新 更多