如何使用Spring的RestController将JSON反序列化为模型对象
我正在使用Betfair的API开发REST Web应用程序,所以我需要序列化/反序列化JSON以发送HttpRequest并读取HttpResponse。
我正在使用Spring MVC,所以我想用@RestController,@RequestBody和@ResponseBody来使用Jackson,但我很努力去理解它们是如何工作的。
在下面的示例中,我向POST发送POST请求以获取用户的名和姓。 我认为HTTP响应应该反序列化到我的模型对象AccountDetailsResponse中,因为我使用了@RequestBody注释,但主页面中没有显示值(仅“Welcome”)。 没有例外被抛出。
调节器
@EnableWebMvc
@RestController
public class LoginController {
private final String APP_KEY = "myAppKey";
private final String LOGIN_END_POINT = "https://identitysso.betfair.it/api/login";
private final String LOGOUT_END_POINT = "https://identitysso.betfair.it/api/logout";
private final String ACCOUNT_END_POINT = "https://api.betfair.com/exchange/account/json-rpc/v1";
private String token;
@RequestMapping(value = "/index", method = RequestMethod.POST, params = { "firstName", "lastName" })
public ModelAndView getAccountDetails(User user, @RequestBody AccountDetailsResponse accountDetails) {
String response = null;
JsonRequest jsonRequest = new JsonRequest();
jsonRequest.setJsonrpc("2.0");
jsonRequest.setMethod("AccountAPING/v1.0/getAccountDetails");
jsonRequest.setId("1");
response = HttpRequestHandler.sendRequest("POST", ACCOUNT_END_POINT, APP_KEY, jsonRequest);
if(response.equals("ERROR")) {
String message = "Error";
return new ModelAndView("home", "message", message);
}
else {
user.setFirstName(accountDetails.getResult().getFirstName());
user.setLastName(accountDetails.getResult().getLastName());
return new ModelAndView("home", "user", user);
}
}
}
NB我省略了showLoginForm(value =“/ index”,method = RequestMethod.GET)和doLogin(value =“/ index”,method = RequestMethod.POST,params = {“email”,“password”})
HttpRequestHandler
public static String sendPostRequest(String url, String APP_KEY, JsonRequest jsonRequest) {
try {
URL urlRequest = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlRequest.openConnection();
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("X-Application", APP_KEY);
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
if(response.toString().contains("error")) {
return "ERROR";
}
else
return response.toString();
}
else
return "ERROR";
}
catch (MalformedURLException e) {
return "ERROR";
}
catch (IOException e) {
return "ERROR";
}
}
home.html的
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>RestController test</title>
</head>
<body>
<span th:if = "${user.logged}">
Welcome, <span th:text = "${user.firstName}"></span> <span th:text = "${user.lastName}"></span>
</span>
<p><span th:text = "${message}"></span></p>
</body>
</html>
用户
public class User {
private Long id;
private String firstName;
private String lastName;
private String email;
private String password;
private Double toBetBalance;
private boolean logged;
public User() { }
//getters and setters
}
AccountDetailsResponse
public class AccountDetailsResponse {
private String jsonrpc;
private Result result;
private String id;
public AccountDetailsResponse() { }
//getters and setters
}
结果
public class Result {
private String currencyCode;
private String firstName;
private String lastName;
private String localeCode;
private String region;
private String timezone;
private Float discountRate;
private Integer pointsBalance;
private String countryCode;
public Result() { }
//getters and setters
}
来自Betfair的JSON响应
[
{
"jsonrpc":"2.0",
"result":{
"currencyCode":"EUR",
"firstName":"My name",
"lastName":"My lastname",
"localeCode":"it_IT",
"region":"GBR",
"timezone":"CET",
"discountRate":0.0,
"pointsBalance":0,
"countryCode":"IT"
},
"id":1
}
]
POM依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.2</version>
</dependency>
</dependencies>
我错在哪里?
你不应该这样做吗?
response.getResult().getFirstName();
response.getResult().getLastName();
在LoginController的else块?
OP需要的是名为RestTemplate的Spring资源。 这用于向URL发出请求,该响应可以绑定到自定义类,并由Jackson负责解序列化。
看看exchange
方法。
上一篇: How to deserialize JSON to model object with Spring's RestController