【问题标题】:Spring Rest : Handling POST requests, at server endSpring Rest:在服务器端处理 POST 请求
【发布时间】:2016-02-29 00:39:25
【问题描述】:

我是根据此链接中的答案提出这个问题

POST request via RestTemplate in JSON

我实际上想从客户端发送 JSON 并在 REST 服务器上接收相同的内容。由于客户端部分是在我上面提到的链接中完成的。同样,我将如何在服务器端处理该请求。

客户:

// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);

// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
  .exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
  JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
  // nono... bad credentials
}

服务器:

@RequestMapping(method=RequestMethod.POST, value = "/login")
    public ResponseEntity<String> login(@RequestBody HttpEntity<String> entity) {
        JSONObject jsonObject = new JSONObject(entity.getBody());
        String username = jsonObject.getString("username");
        return new ResponseEntity<>(username, HttpStatus.OK);
    }

这在客户端给了我 400 错误请求错误。希望提供一些有关如何在服务器端处理此问题的线索。

【问题讨论】:

    标签: android json spring rest spring-io


    【解决方案1】:

    HTTPEntity 不应在您的服务器方法中使用。而是使用从客户端传递给 HTTPEntity 的参数。在您的情况下,它必须是 String,因为您是从客户端传递字符串。下面的代码应该适合你。

    @RequestMapping(method=RequestMethod.POST, value = "/login")
    public ResponseEntity<String> login(@RequestBody String jsonStr) {
        System.out.println("jsonStr  " + jsonStr);
        JSONObject jsonObject = new JSONObject(jsonStr);
        String username = jsonObject.getString("username");
        return new ResponseEntity<String>(username, HttpStatus.OK);
    }  
    

    我的建议是创建 bean 类并在服务器和客户端中使用它,而不是将其转换为 String。它将提高代码的可读性。

    【讨论】:

    • 非常感谢。我实际上把它当作一个字符串,它就像一个魅力。但必须从中删除一些转义字符。
    【解决方案2】:

    在使用 Spring RestTemplate 时,我通常更喜欢直接交换对象。例如:

    第 1 步:声明并定义数据持有者类

    class User {
      private String username;
      private String password;
    
      ... accessor methods, constructors, etc. ...
    }
    

    第二步:使用RestTemplate将这个类的对象发送到服务器

    ... You have a RestTemplate instance to send data to the server ...
    
    // You have an object to send to the server, such as:
    User user = new User("user", "secret");
    
    // Set HTTP headers for an error-free exchange with the server.
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    // Generate an HTTP request payload.
    HttpEntity<User> request = new HttpEntity<User>(user, headers);
    
    // Send the payload to the server.
    restTemplate.exchange("[url]", [HttpMethod], request, User.class);
    

    第三步:在服务器上配置ContentNegotiatingViewResolver

    在 Spring XML 或 Java 配置中声明一个 ContentNegotiatingViewResolver 类型的 bean。这将帮助服务器自动将 HTTP 请求与 bean 对象绑定。

    第四步:在服务器上接收请求

    @RestController
    @RequestMapping("/user")
    class UserAPI {
      @RequestMapping(method = RequestMethod.POST)
      @ResponseBody
      public User create(User user) {
        // Process the user.
    
        // Possibly return the same user, although anything can be returned.
        return user;
      }
    }
    

    ContentNegotiatingViewResolver 确保传入的请求在没有任何其他干预的情况下被转换为 User 实例。

    第 5 步:在客户端接收响应

    // Receive the response.
    HttpEntity<User> response = restTemplate.exchange("[url]", [HttpMethod], request, User.class);
    
    // Unwrap the object from the response.
    user = response.getBody();
    

    您会注意到客户端和服务器都使用相同的 bean 类 (User)。这使两者保持同步,因为 bean 结构中的任何重大更改都会立即导致其中之一或两者的编译失败,因此需要在部署代码之前进行修复。

    【讨论】:

    • 我实际上是在探索我在链接中提到的答案。我总是只做这种对象交换,但为了改变我尝试通过主体本身发送请求,而不是为来自服务器的每个请求创建单独的 pojo 类。
    猜你喜欢
    • 2016-01-27
    • 2017-12-29
    • 2010-10-25
    • 2021-06-30
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多