How to deserialize JSON to model object with Spring's RestController
I'm developing a REST web application using Betfair's API, so I need to serialize/deserialize JSON in order to send HttpRequest and read HttpResponse.
I'm using Spring MVC so I want to use Jackson with @RestController, @RequestBody and @ResponseBody but I'm struggling to understand how they work.
In the following example I'm sending a POST request to Betfair to obtain user's firstname and lastname. I think that the HTTP Response should be deserialized into my model object AccountDetailsResponse, because I'm using @RequestBody annotation, but no value is shown in the home web page (only "Welcome, "). No exception is thrown.
Controller
@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 I've omitted the showLoginForm (value = "/index", method = RequestMethod.GET) and 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>
User
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
}
Result
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
}
JSON response from Betfair
[
{
"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 dependencies
<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>
Where am I wrong?
Shouldn't you be doing
response.getResult().getFirstName();
response.getResult().getLastName();
in the LoginController 's else block?
What OP needs is a Spring resource called RestTemplate. That's used to make a request to a URL, which response can be bound to a custom class, with Jackson taking care of the deserialization.
Take a look at the exchange
method.
上一篇: Spring响应api筛选器字段