Преобразование параметров запроса 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?
Ответы
Ответ 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
Ответ 5
Возможно, вы могли бы использовать
http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/beans/BeanUtils.html
BeanUtils.copyProperties(source, target)
Ответ 6
Если вы заинтересованы в создании своих DTO, могу ли я предложить jsonschema2pojo? Вы можете определить свои объекты с помощью JSON Schema и автоматически создать ваши DTO.
После того, как вы написали схему, вы также можете предоставить ее своим потребителям, чтобы они точно понимали, как следует отформатировать запросы.