Как вернуть JSON без родительского тега на JAX-RS? - PullRequest
1 голос
/ 25 апреля 2019

Я пытаюсь создать модуль REST API для Liferay, но у меня возникают проблемы при попытке генерировать ответы 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 без корневого тега?Я попытался добавить (name = "") рядом с аннотацией @XmlRootElement, но это не сработало.

1 Ответ

0 голосов
/ 30 апреля 2019

Я бы предложил вам использовать провайдера Джексона для маршалинга / демаршаллинга ввода / вывода json (как я делал в моих комментариях к вашему сообщению):

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 запускается, она должна установить провайдера Джексона и задать 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);   

    }
...