Подтвердить что ты не робот

Преобразование параметров запроса JSON в объекты с помощью JAX-RS

У меня есть ресурс JAX-RS, который получает его параметры как строку JSON следующим образом:

http://some.test/aresource?query={"paramA":"value1", "paramB":"value2"}

Причиной использования JSON здесь является то, что объект запроса может быть довольно сложным в реальных случаях.

Я хотел бы преобразовать строку JSON в объект Java, dto в примере:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") DataTransferObject dto ) {
    ...
}

Поддерживает ли JAX-RS такое преобразование из JSON, которое передается как параметр запроса для объектов Java?

4b9b3361

Ответ 1

Да, вы можете это сделать, но вам нужно будет написать код конверсии самостоятельно. К счастью, это просто, вам просто нужно написать класс, который имеет открытый конструктор String для преобразования. Например:

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

    public DataTransferObject getDTO() {
        return dto;
    }
}

Затем вы можете использовать:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") JSONParam json) {
    DataTransferObject dto = json.getDTO();
    ...
}

Ответ 2

Как уже упоминалось, вам нужно явно преобразовать из параметра String в JSON. Но нет необходимости использовать что-то примитивное, как парсер org.json; Jackson или Gson может выполнять привязку данных (String to JSON, JSON to POJO) в линии или двух. С Джексоном:

MyValue value = new ObjectMapper().readValue(json, MyValue.class);

(для производственного кода просто создайте ObjectMapper один раз как статический член, повторное использование)

Джексон - это то, что большинство реализаций JAX-RS используют для привязки данных для данных POST, поэтому это очень похоже.

Ответ 3

Добавление к решению Jason, используя http://www.json.org/java/ (любезно предоставлено Crockford):

import org.json.JSONObject;

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
            JSONObject jo = new JSONObject(json);
            dto.setParamA(jo.getString("paramA"));
            dto.setParamB(jo.getString("paramB"));
            // There are other get methods for Integer, Double, etc. 
            // You can also build JSON from Java objects.
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

     public DataTransferObject getDTO() {
        return dto;
    }                  
}

Не изобретайте колесо: -)

Ответ 4

JAX-RS поддерживает использование JAXB (Java API для привязки XML) для привязки JavaBean к XML или JSON и наоборот. Более подробную информацию можно найти здесь, например: http://www.ibm.com/developerworks/web/library/wa-aj-tomcat/index.html

Вам нужно

  • Добавить аннотацию @XmlRootElement в DataTransferObject
  • Создайте пустой конструктор по умолчанию в DataTransferObject
  • Добавить @Consumes (MediaType.APPLICATION_JSON) аннотацию к вашему WebService

Ответ 6

Если вы заинтересованы в создании своих DTO, могу ли я предложить jsonschema2pojo? Вы можете определить свои объекты с помощью JSON Schema и автоматически создать ваши DTO.

После того, как вы написали схему, вы также можете предоставить ее своим потребителям, чтобы они точно понимали, как следует отформатировать запросы.