Spring 其余:在服务器端处理 POST 请求
Spring Rest : Handling POST requests, at server end
我是根据 link
中的答案问这个问题的
POST request via RestTemplate in JSON
我实际上想从客户端发送 JSON 并在 REST 服务器上接收相同的内容。由于客户端部分是在我上面提到的 link 中完成的。同样,我将如何在服务器端处理该请求。
客户:
// 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 错误请求错误。希望得到一些关于如何在服务器端处理这个问题的线索。
不应在您的服务器方法中使用 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 class 并在服务器和客户端中使用它,而不是将其转换为 String。它将提高代码的可读性。
使用SpringRestTemplate
时,我通常更喜欢直接交换对象。例如:
Step 1: Declare and define a data holder class
class User {
private String username;
private String password;
... accessor methods, constructors, etc. ...
}
Step 2: Send objects of this class to the server using 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);
Step 3: Configure a ContentNegotiatingViewResolver
on the server
在 Spring XML 或 Java 配置中声明类型 ContentNegotiatingViewResolver
的 bean。这将帮助服务器自动将 HTTP 请求与 bean 对象绑定。
Step 4: Receive the request on the server
@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
实例。
Step 5: Receive the response on the client
// Receive the response.
HttpEntity<User> response = restTemplate.exchange("[url]", [HttpMethod], request, User.class);
// Unwrap the object from the response.
user = response.getBody();
您会注意到客户端和服务器都使用相同的 bean class (User
)。这使两者保持同步,因为 bean 结构中的任何重大更改都会立即导致一个或两个编译失败,需要在部署代码之前进行修复。
我是根据 link
中的答案问这个问题的POST request via RestTemplate in JSON
我实际上想从客户端发送 JSON 并在 REST 服务器上接收相同的内容。由于客户端部分是在我上面提到的 link 中完成的。同样,我将如何在服务器端处理该请求。
客户:
// 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 错误请求错误。希望得到一些关于如何在服务器端处理这个问题的线索。
不应在您的服务器方法中使用 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 class 并在服务器和客户端中使用它,而不是将其转换为 String。它将提高代码的可读性。
使用SpringRestTemplate
时,我通常更喜欢直接交换对象。例如:
Step 1: Declare and define a data holder class
class User {
private String username;
private String password;
... accessor methods, constructors, etc. ...
}
Step 2: Send objects of this class to the server using
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);
Step 3: Configure a
ContentNegotiatingViewResolver
on the server
在 Spring XML 或 Java 配置中声明类型 ContentNegotiatingViewResolver
的 bean。这将帮助服务器自动将 HTTP 请求与 bean 对象绑定。
Step 4: Receive the request on the server
@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
实例。
Step 5: Receive the response on the client
// Receive the response.
HttpEntity<User> response = restTemplate.exchange("[url]", [HttpMethod], request, User.class);
// Unwrap the object from the response.
user = response.getBody();
您会注意到客户端和服务器都使用相同的 bean class (User
)。这使两者保持同步,因为 bean 结构中的任何重大更改都会立即导致一个或两个编译失败,需要在部署代码之前进行修复。