总结POST、GET @RequestBody和@RequestParam区别 There was an unexpected error (type=Bad Request, status=400)

导读:本篇文章讲解 总结POST、GET @RequestBody和@RequestParam区别 There was an unexpected error (type=Bad Request, status=400),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

引入问题

今天在使用spring boot做设备微服务的开发时,报出了标题中的错误,错误信息如下:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Feb 02 15:42:15 CST 2021
There was an unexpected error (type=Bad Request, status=400).

分析问题

翻译最后一句为:发生意外错误(类型=错误的请求,状态= 400) ,如下贴出我的代码

    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public ResponseDto getDeviceDetail(
            @RequestHeader(name = Constant.HEADER_X_TRACE_ID, required = false) String traceId,
            @Validated @RequestBody DetailDeviceRequestBody requestBody,
            @PathVariable String requestPath,
            @PathVariable String requestCategory
    ) {
        。。。。。。
        String sn = requestBody.getSn();
        if ( isBlank(sn)) {
            return new ResponseDto(ErrorResponse.REQUEST_ERROR.getCode(),ErrorResponse.REQUEST_ERROR.getMessage());
        }
        。。。
        return iDeviceService.getDeviceDetail(deviceEntity);
    }

问题出现在这里 @Validated @RequestBody DetailDeviceRequestBody requestBody,,我明明是get请求,却使用@RequestBody去接收数据,然而get请求是没有请求体的,因为报出了这样的问题。我们可以使用@RequestParam来接收。

那么, @RequestParam@RequestBody有什么区别呢?

@RequestParam

注解@RequestParam接收的参数是来自HTTP请求体或请求url的QueryString中。

RequestParam可以接受简单类型的属性,也可以接受对象类型。

@RequestParam有三个配置参数:

  • required 表示是否必须,默认为 true,必须。

  • defaultValue 可设置请求参数的默认值。

  • value 为接收url的参数名(相当于key值)。

在工作的过程中,我们一般使用@RequestParam来处理get方法请求的数据,如下代码所示:

@GetMapping("/saveStudent")
  public Object saveStudent(
          @RequestParam("name") String name,
          @RequestParam("age") int age
  ) {
    Student student = new Student();
    student.setName(name);
    student.setAge(age);
    return student;
  }

使用postman发送请求,如下图所示:

在这里插入图片描述

假如我们使用 @RequestBody来处理get方法请求的数据,如下代码所示:

  @PostMapping("/saveStudent")
  public Object saveStudent(
          @RequestParam("student") Student student
  ) {
    return student;
  }

便报出如下错误:

在这里插入图片描述

@RequestBody

注解@RequestBody接收的参数是来自requestBody中,即请求体。

一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如application/jsonapplication/xml等类型的数据。

application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。

POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type。

SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上,如下代码所示:

 @PostMapping("/saveStudent")
  public Object saveStudent(
          @RequestBody Student student
  ) {
    return student;
  }

输出结果如下图所示:

在这里插入图片描述
前端使用$.ajax的话,一定要指定 contentType: “application/json;charset=utf-8;”,默认为 application/x-www-form-urlencoded。

解决问题

通过对@RequestMapping@RequestBody的分析后,特修改以上代码,如下所示:

   @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public ResponseDto getDeviceDetail(
            @RequestHeader(name = Constant.HEADER_X_TRACE_ID, required = false) String traceId,      
            @RequestParam(required = false) String sn,
            @PathVariable String requestPath,
            @PathVariable String requestCategory
    ) {
        if ( isBlank(sn)) {
            return new ResponseDto(ErrorResponse.REQUEST_ERROR.getCode(),ErrorResponse.REQUEST_ERROR.getMessage());
        }
        。。。
        return iDeviceService.getDeviceDetail(deviceEntity);
    }

这样就能轻松地接收get的请求值了。

重要总结

post请求

从content-type方面总结

form-data、x-www-form-urlencoded

  1. 不可以用@RequestBody;

  2. 可以用@RequestParam。见postman的格局,这两种方式的时候没有json字符串部分。

application/json

  1. json字符串部分可以用@RequestBody;

  2. url中的?后面参数可以用@RequestParam。见postman的格局

从注解方式总结:

@RequestBody

(@RequestBody Map map)
(@RequestBody Object object)
application/json时候可用
form-data、x-www-form-urlencoded时候不可用

@RequestParam

@RequestParam Map map

application/json时候,json字符串部分不可用,url中的?后面添加参数即可用

form-data、x-www-form-urlencoded时候可用,但是要将Headers里的Content-Type删掉

@RequestParam String variable

application/json时候,json字符串部分不可用,url中的?后面添加参数即可用

form-data、x-www-form-urlencoded时候可用,且参数可以没有顺序(即前端传过来的参数或者url中的参数顺序不必和后台接口中的参数顺序一致,只要字段名相同就可以),但是要将Headers里的Content-Type删掉

@RequestParam Object object

不管application/json、form-data、x-www-form-urlencoded都不可用

特殊情况

既不是@RequestBody也不是@RequestParam,没有指定参数哪种接收方式:

(Map map)
(Object object)
application/json时候:json字符串部分不可用,url中的?后面添加参数不可用。
因为没有指定,它也不知道到底是用json字符串部分还是?后面添加参数部分,所以干脆都不可以用
form-data、x-www-form-urlencoded时都不可用
 
(HttpServletRequest request)
application/json不可用
form-data、x-www-form-urlencoded时可用

GET请求

从@RequestBody总结

RequestBody -- Map / Object
GET请求中不可以使用@RequestBody

从@RequestParam总结

@RequestParam Map map

在url中的?后面添加参数即可使用

@RequestParam String variable

在url中的?后面添加参数即可使用

@RequestParam Object object

GET请求中不可以使用
当使用GET请求时,通过postman添加?后面的参数,不用在url中自己一个一个拼,点击Params,在下面key-value中输入就自动拼接到url中

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99225.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!