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.

链接地址: http://www.djcxy.com/p/48482.html

上一篇: Spring响应api筛选器字段

下一篇: 如何使用Spring的RestController将JSON反序列化为模型对象