0

Я разрабатываю веб-приложение REST с использованием API Betfair, поэтому мне нужно сериализовать/десериализовать JSON, чтобы отправить HttpRequest и прочитать HttpResponse.Как десериализовать JSON для моделирования объекта с помощью RestController Spring

Я использую Spring MVC, поэтому я хочу использовать Jackson с @RestController, @RequestBody и @ResponseBody, но я изо всех сил пытаюсь понять, как они работают.

В следующем примере я отправляю запрос POST в Betfair для получения имени и фамилии пользователя. Я думаю, что HTTP-ответ должен быть десериализован в моем объекте модели AccountDetailsResponse, потому что я использую аннотацию @RequestBody, но на домашней веб-странице не отображается значение (только «Добро пожаловать»). Никакое исключение не выбрасывается.

Контроллер

@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); 
     } 
    } 
} 

нотабене Я опустил 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 
} 

JSON ответ от 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

<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> 

Где я ошибаюсь?

+0

Запрос на Betfair не имеет ничего общего с контроллером. – zeroflagL

+0

Что это значит? – andy

+0

Точно то, что я написал.Нет связи между 'AccountDetailsResponse' и' response = HttpRequestHandler.sendRequest' – zeroflagL

ответ

0

Вы не должны делать

response.getResult().getFirstName(); 
response.getResult().getLastName(); 

в еще блоке LoginController «s?

+0

Ответ - это String, а не объект AccountDetailsResponse. Я мог бы использовать ObjectMapper от Jackson для привязки ответа к JsonNode, но это не моя цель, потому что весной MVC-сериализация и десериализация должны работать автоматически, используя @RestController. – andy

+0

From Spring docs - «Аннотирование параметра метода @RequestBody указывает, что параметр метода должен быть связанный со значением тела запроса HTTP ». Его целью является в основном сбор параметров запроса в вашем классе домена. В вашем случае это помогает отображать электронную почту и пароль в объекте User. – user3138997

+0

адрес электронной почты и пароль только отображаются в объекте User благодаря методу doLogin. Здесь мой RequestBody - это объект AccountDetailsResponse, а ответ Betfair - тот, который я опубликовал выше. Из этого JSON я хочу взять поля firstName и lastName. Поскольку JSON соответствует объекту AccountDetailsResponse, который должен быть сопоставлен с последним объектом, нет? – andy

0

Что нужно OP - это ресурс Spring, называемый RestTemplate. Это используется для запроса запроса на URL-адрес, ответ которого может быть привязан к пользовательскому классу, а Джексон заботится о десериализации.

Посмотрите на метод exchange.

Смежные вопросы