Параметр JSON в контроллере spring MVC
У меня
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
SessionInfo register(UserProfile profileJson){
...
}
Я передаю profileJson таким образом:
http://server/url?profileJson={"email": "[email protected]"}
но мой объект profileJson имеет все нулевые поля. Что делать, чтобы сделать spring синтаксический анализ моего json?
Ответы
Ответ 1
Это можно сделать с помощью специального редактора, который преобразует JSON в объект UserProfile:
public class UserProfileEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
ObjectMapper mapper = new ObjectMapper();
UserProfile value = null;
try {
value = new UserProfile();
JsonNode root = mapper.readTree(text);
value.setEmail(root.path("email").asText());
} catch (IOException e) {
// handle error
}
setValue(value);
}
}
Это для регистрации редактора в классе контроллера:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(UserProfile.class, new UserProfileEditor());
}
И вот как использовать редактор, чтобы размонтировать параметр JSONP:
@RequestMapping(value = "/jsonp", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
SessionInfo register(@RequestParam("profileJson") UserProfile profileJson){
...
}
Ответ 2
Решение этого настолько просто и просто, что вы почти смеете, но прежде чем я даже доберусь до него, позвольте мне вначале подчеркнуть, что ни один уважающий себя Java-разработчик никогда не будет, и я имею в виду, что EVER работает с JSON без использования высокопроизводительная библиотека JSON от Jackson.
Джексон - это не только рабочая лошадь и библиотека дефолт JSON для разработчиков Java, но также предоставляет целый набор вызовов API, что делает JSON-интеграцию с Java частью торта (вы можете скачать Jackson at http://jackson.codehaus.org/).
Теперь для ответа. Предполагая, что у вас есть pojo UserProfile, который выглядит примерно так:
public class UserProfile {
private String email;
// etc...
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// more getters and setters...
}
... тогда ваш метод Spring MVC для преобразования имени параметра GET "profileJson" с значением JSON { "email": "[email protected]" } будет выглядеть следующим образом в вашем контроллере:
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper; // this is your lifesaver right here
//.. your controller class, blah blah blah
@RequestMapping(value="/register", method = RequestMethod.GET)
public SessionInfo register(@RequestParam("profileJson") String profileJson)
throws JsonMappingException, JsonParseException, IOException {
// now simply convert your JSON string into your UserProfile POJO
// using Jackson ObjectMapper.readValue() method, whose first
// parameter your JSON parameter as String, and the second
// parameter is the POJO class.
UserProfile profile =
new ObjectMapper().readValue(profileJson, UserProfile.class);
System.out.println(profile.getEmail());
// rest of your code goes here.
}
Bam! Все готово. Я бы посоветовал вам изучить основную часть Jackson API, потому что, как я уже сказал, это спасатель. Например, вы вообще возвращаете JSON из своего контроллера? Если это так, все, что вам нужно сделать, это включить JSON в вашу библиотеку и вернуть POJO, и Джексон автоматически преобразует ее в JSON. Вы не можете стать намного легче, чем это. Ура!: -)
Ответ 3
Вы можете создать свой собственный Converter
и позволить Spring использовать его автоматически при необходимости:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
class JsonToUserProfileConverter implements Converter<String, UserProfile> {
private final ObjectMapper jsonMapper = new ObjectMapper();
public UserProfile convert(String source) {
return jsonMapper.readValue(source, UserProfile.class);
}
}
Как вы можете видеть в следующем методе контроллера, ничего особенного не требуется:
@GetMapping
@ResponseBody
public SessionInfo register(@RequestParam UserProfile userProfile) {
...
}
Spring использует автоматический конвертер, если вы используете компонентное сканирование, и аннотируйте класс конвертера с помощью @Component
.
Узнайте больше о Spring Converter и преобразованиях типов в Spring MVC.
Ответ 4
Это решает мою непосредственную проблему, но мне все же интересно узнать, как вы можете передать несколько объектов JSON через вызов AJAX.
Лучший способ сделать это - иметь объект-оболочку, содержащий два (или несколько) объектов, которые вы хотите передать. Затем вы создаете свой объект JSON как массив из двух объектов i.e.
[
{
"name" : "object1",
"prop1" : "foo",
"prop2" : "bar"
},
{
"name" : "object2",
"prop1" : "hello",
"prop2" : "world"
}
]
Затем в вашем методе контроллера вы получаете тело запроса как отдельный объект и извлекаете два содержащихся объекта. то есть:
@RequestMapping(value="/handlePost", method = RequestMethod.POST, consumes = { "application/json" })
public void doPost(@RequestBody WrapperObject wrapperObj) {
Object obj1 = wrapperObj.getObj1;
Object obj2 = wrapperObj.getObj2;
//Do what you want with the objects...
}
Объект-оболочка будет выглядеть примерно так:
public class WrapperObject {
private Object obj1;
private Object obj2;
public Object getObj1() {
return obj1;
}
public void setObj1(Object obj1) {
this.obj1 = obj1;
}
public Object getObj2() {
return obj2;
}
public void setObj2(Object obj2) {
this.obj2 = obj2;
}
}
Ответ 5
Просто добавьте аннотацию @RequestBody
перед этим параметром