restcontroller 和 application/x-www-form-urlencoded;charset=UTF-8 媒体类型的问题
Issue with restcontroller and application/x-www-form-urlencoded;charset=UTF-8 media type
任务微不足道
客户端使用 POST 和 application/x-www-form-urlencoded 媒体类型发送请求。服务器收到状态为 OK 的响应。但看起来媒体类型 application/x-www-form-urlencoded 和 application/x-www-form-urlencoded;charset=UTF-8[=16= 之间存在差异]
服务器部分:
@Slf4j
@Controller
@RequestMapping(produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public class CallbackController {
@RequestMapping(value = "/callback/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<?> callback(HttpServletRequest servletRequest, @RequestBody RequestEntity<?> body) throws IOException {
log.info("Hello: {}", servletRequest);
log.info("Hello: {}", body);
String s = extractPostRequestBody(servletRequest);
log.info("Hello: {}", s);
return new ResponseEntity<Object>(HttpStatus.OK);
}
}
客户端部分:
public void sendcallback() throws IOException {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8082/callback/";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
headers.add(HttpHeaders.ACCEPT_CHARSET, "UTF-8");
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
headers.add(HttpHeaders.USER_AGENT, "uuuuuuuuuuser");
headers.add(HttpHeaders.AUTHORIZATION, "none");
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
List<String> val1 = new ArrayList<>();
val1.add("valllll");
body.put("val", val1);
HttpEntity<?> entity= new HttpEntity<>(body, headers);
ResponseEntity<?> result = restTemplate.exchange(url, HttpMethod.POST, entity, Object.class);
log.info("response: {}", result);
}
客户端输出结果,请求:
"POST /callback/ HTTP/1.1[\r][\n]"
"Content-Type: application/x-www-form-urlencoded[\r][\n]"
"Accept-Charset: UTF-8[\r][\n]"
"Accept: application/x-www-form-urlencoded[\r][\n]"
"User-Agent: uuuuuuuuuuser[\r][\n]"
"Authorization: none[\r][\n]"
"Content-Length: 11[\r][\n]"
"Host: localhost:8082[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"[\r][\n]"
"val=valllll"
回复:
"HTTP/1.1 405 Method Not Allowed[\r][\n]"
"Server: Apache-Coyote/1.1[\r][\n]"
"Allow: GET, HEAD[\r][\n]"
"Content-Language: ru-RU[\r][\n]"
"Content-Length: 0[\r][\n]"
"Date: Tue, 11 Aug 2015 06:28:41 GMT[\r][\n]
"[\r][\n]"
调试模式下的服务器告诉我有趣的事情:
看来我必须手动添加 FormHttpMessageConverter
@SpringBootApplication
public class CallbackApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(CallbackApplication.class);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FormHttpMessageConverter converter = new FormHttpMessageConverter();
MediaType mediaType = new MediaType("application","x-www-form-urlencoded", Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Arrays.asList(mediaType));
converters.add(converter);
super.configureMessageConverters(converters);
}
}
并且不要忘记使用正确的@RequestBody 类型
public @ResponseBody ResponseEntity<?> callback(HttpServletRequest servletRequest, @RequestBody MultiValueMap body)
{
因为有:
- org.springframework.util.MultiValueMap
- org.apache.commons.collections.map.MultiValueMap
任务微不足道 客户端使用 POST 和 application/x-www-form-urlencoded 媒体类型发送请求。服务器收到状态为 OK 的响应。但看起来媒体类型 application/x-www-form-urlencoded 和 application/x-www-form-urlencoded;charset=UTF-8[=16= 之间存在差异]
服务器部分:
@Slf4j
@Controller
@RequestMapping(produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public class CallbackController {
@RequestMapping(value = "/callback/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<?> callback(HttpServletRequest servletRequest, @RequestBody RequestEntity<?> body) throws IOException {
log.info("Hello: {}", servletRequest);
log.info("Hello: {}", body);
String s = extractPostRequestBody(servletRequest);
log.info("Hello: {}", s);
return new ResponseEntity<Object>(HttpStatus.OK);
}
}
客户端部分:
public void sendcallback() throws IOException {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8082/callback/";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
headers.add(HttpHeaders.ACCEPT_CHARSET, "UTF-8");
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
headers.add(HttpHeaders.USER_AGENT, "uuuuuuuuuuser");
headers.add(HttpHeaders.AUTHORIZATION, "none");
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
List<String> val1 = new ArrayList<>();
val1.add("valllll");
body.put("val", val1);
HttpEntity<?> entity= new HttpEntity<>(body, headers);
ResponseEntity<?> result = restTemplate.exchange(url, HttpMethod.POST, entity, Object.class);
log.info("response: {}", result);
}
客户端输出结果,请求:
"POST /callback/ HTTP/1.1[\r][\n]"
"Content-Type: application/x-www-form-urlencoded[\r][\n]"
"Accept-Charset: UTF-8[\r][\n]"
"Accept: application/x-www-form-urlencoded[\r][\n]"
"User-Agent: uuuuuuuuuuser[\r][\n]"
"Authorization: none[\r][\n]"
"Content-Length: 11[\r][\n]"
"Host: localhost:8082[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"[\r][\n]"
"val=valllll"
回复:
"HTTP/1.1 405 Method Not Allowed[\r][\n]"
"Server: Apache-Coyote/1.1[\r][\n]"
"Allow: GET, HEAD[\r][\n]"
"Content-Language: ru-RU[\r][\n]"
"Content-Length: 0[\r][\n]"
"Date: Tue, 11 Aug 2015 06:28:41 GMT[\r][\n]
"[\r][\n]"
调试模式下的服务器告诉我有趣的事情:
看来我必须手动添加 FormHttpMessageConverter
@SpringBootApplication
public class CallbackApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(CallbackApplication.class);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FormHttpMessageConverter converter = new FormHttpMessageConverter();
MediaType mediaType = new MediaType("application","x-www-form-urlencoded", Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Arrays.asList(mediaType));
converters.add(converter);
super.configureMessageConverters(converters);
}
}
并且不要忘记使用正确的@RequestBody 类型
public @ResponseBody ResponseEntity<?> callback(HttpServletRequest servletRequest, @RequestBody MultiValueMap body)
{
因为有:
- org.springframework.util.MultiValueMap
- org.apache.commons.collections.map.MultiValueMap