Горячее редактирование вывода объекта JSON с помощью Jersey & Netbeans? - PullRequest
0 голосов
/ 25 октября 2011

У меня проблема с моим веб-сервисом RESTful - снова :( Резюме: Когда я звоню по этому адресу:

http://localhost:8080/iOSWebServices/resources/credits/1

Я получаю этот вывод JSON:

{"id":1,"lastname":null,"firstname":"lalsdaksldlasds"}

но я хочу этот вывод JSON:

{"creditRequest": {"id": 1, "lastname": null, "firstname": "lalsdaksldlasds"}}

Длинная версия: Я использую netbeans, glassfish 3 и jersey 1.9.1 для предоставления нескольких простых тестовых веб-сервисов. проблема в том, что во всех выходах json отсутствует имя класса в выводе ...

Для примера выше: CreditRequest.java

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "creditRequest")
@XmlType(name = "creditRequestType")
@XmlAccessorType(XmlAccessType.FIELD)
public class CreditRequest {

    private Long id;
    private String firstname;
    private String lastname;

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
}

CreditRequest.java

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("credits")
@RequestScoped
public class CreditsResource {

    @Context
    private UriInfo context;

    /** Creates a new instance of CreditsResource */
    public CreditsResource() {
    }

    //OUTPUT AS ABOVE!
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getCreditById(@PathParam("id") long id) {
        System.out.println("getCreditById");
        CreditRequest creditRequest = new CreditRequest();
        creditRequest.setId(new Long(1));
        creditRequest.setFirstname("lalsdaksldlasds");
        return Response.ok().entity(creditRequest).build();        
    }
}

Руководство пользователя по джерси объясняет, как ДОЛЖНО работать - цитата ...

Example 5.14. Keep XML root tag equivalent in JSON mapped JSON notation
    JSONConfiguration.mapped().rootUnwrapping(false).build()
and get the following JSON for our Contact bean:
Example 5.15. XML root tag equivalent kept in JSON using mapped notation
    {"contact":{ "id":"2" 
     ,"name":"Bob"
     ,"addresses":{"street":"Long Street 1"
                        ,"town":"Short Village"}}}

Для этого я написал простой класс, реализующий реализации ContextResolver (также в руководстве пользователя)

JAXBContextResolver.java // Кажется, не работает

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext context;
    private Class[] types = {CreditRequest .class}; //FIXED

    public JAXBContextResolver() throws Exception {

        System.out.println("init");
        this.context = new JSONJAXBContext(
                JSONConfiguration.mapped().rootUnwrapping(false).build(), types);
    }

    @Override
    public JAXBContext getContext(Class<?> objectType) {
        System.out.println("get");
        for (Class type : types) {
            if (type == objectType) {
                return context;
            }
        }
        return null;
    }
}

Когда я запускаю веб-сервис, вывод, определенный в конструкторе JAXBContextResolver, будет записан как "init" - но "получить" не будет ....

В этом проекте netbeans контролирует ресурсы моих веб-сервисов - и снова инициализирует JAXBContextResolver при запуске сервера - но по-прежнему нет rootUnwrapping: (

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
       <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

Есть идеи? Я действительно не знаю, почему в моем выводе JSON нет изменений: (* ​​1034 *

Ответы [ 4 ]

1 голос
/ 19 января 2013

У меня была такая же проблема на прошлой неделе.Я нашел решение в файле web.xml.После того как я удалил следующие строки:

<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
1 голос
/ 01 марта 2012

Это почти как класс провайдера не найден. Вы говорите, что Netbeans контролирует ваши ресурсы, но разве не Glassfish (и, в конечном итоге, джерси) сканирует / загружает классы ресурсов и провайдеров? Нужна ли Glassfish какая-либо конфигурация, чтобы знать, где искать? В Tomcat это свойство устанавливается в конфигурации сервлета: "com.sun.jersey.config.property.packages".

Я попробовал ваш пример точно, у вас есть, и rootUnwrapping работает с Tomcat 6 и Jersey 1.4, в затмении.

1 голос
/ 26 октября 2011

Я заметил, что массив JAXBContextResolver.types содержит CreditsResource, где должен быть класс CreditRequest.
Хотя это объясняет, почему в выводе JSON нет изменений для CreditRequest, а не почему сообщение "get" не являетсяпечатается ...

0 голосов
/ 27 октября 2011

Не знаю, является ли это лучшим решением, но оно решает проблему ... Я написал класс-оболочку для CreditRequest

CreditRequestWrapper

@XmlType(name = "creditRequestType")
@XmlAccessorType(XmlAccessType.FIELD)
public class CreditRequestWrapper {

    @XmlElement(name = "creditRequest")
    private CreditRequest creditRequest;

    public CreditRequestWrapper() {
    }

    public CreditRequestWrapper(CreditRequest creditRequest) {
        this.creditRequest = creditRequest;
    }

    public CreditRequest getCreditRequest() {
        return creditRequest;
    }

    public void setCreditRequest(CreditRequest creditRequest) {
        this.creditRequest = creditRequest;
    }
}

И @GET в моемресурс

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getCreditById(@PathParam("id") long id) {
    System.out.println("getCreditById");
    CreditRequest creditRequest = new CreditRequest();
    creditRequest.setId(new Long(1));
    creditRequest.setFirstname("lalsdaksldlasds");
    return Response.ok().entity(new CreditRequestWrapper(creditRequest)).build();
}

Теперь я получаю то, что хотел ...

{"creditRequest":{"id":1,"firstname":"lalsdaksldlasds","creditVolume":0.0,"creditRate":0.0}}

Но мне бы очень хотелось узнать, почему, черт возьми, официальный способ не работает для меня-.-

...