关于在@RequestMapping的控制器方法中接收不到post请求参数或前端报错Bad Request的问题

先考虑请求头参数Content-Type的问题

当我们使用axios的默认请求方式{'Content-Type' : 'application/json'}时,后端控制器方法中要用@RequestBody注解,而且注意后面必须是一个实体类对象,不能写具体的一个参数,因为@RequestBody注解会把整个JSON字符串赋值给紧跟它的第一个参数。下面是一个错误例子:包含用户名和密码的JSON字符串直接赋值给了username,而password为空。

@RequestMapping(value = "/login")
    @ResponseBody
    public String logined(@RequestBody String userName, String password,HttpServletRequest request) throws IOException {

        Managers manager=new Managers();
        manager.setUserName(userName);
        manager.setPassword(password);
        System.out.println("manager = " + manager);
        Managers manager1 = msi.queryOne(manager);
        System.out.println("manager1 = " + manager1);
        HttpSession session = request.getSession();
        if (manager1==null){
            System.out.println("noUser");
            return "noUser";
        } else if (manager.getPassword().equals(manager1.getPassword())) {
            session.setAttribute("loginManager", manager1.getUserName());
            System.out.println("success");
            return "success";
        }else {
            System.out.println("errPassword");
            return "errPassword";
        }
    }

控制台输出:

manager = com.entity.Managers{id=0, userName='{"userName":"章北海","password":"123456"}', password='null', superManager=false}

正确用法(用实体类对象接受):

@RequestMapping(value = "/login")
    @ResponseBody
    public String logined(@RequestBody Managers manager ,HttpServletRequest request) throws IOException {

        System.out.println("manager = " + manager);
        Managers manager1 = msi.queryOne(manager);
        System.out.println("manager1 = " + manager1);
        HttpSession session = request.getSession();
        if (manager1==null){
            System.out.println("noUser");
            return "noUser";
        } else if (manager.getPassword().equals(manager1.getPassword())) {
            session.setAttribute("loginManager", manager1.getUserName());
            System.out.println("success");
            return "success";
        }else {
            System.out.println("errPassword");
            return "errPassword";
        }
    }

结果:

manager = com.entity.Managers{id=0, userName='章北海', password='123456', superManager=false}

但如果我们没有对应的实体类,希望用参数名接收,则保证前端请求头为

{'Content-Type' : 'application/x-www-form-urlencoded;charset=utf-8'},例如

axios({
                    method:"post",
                    url:"http://localhost:8080/login",
                    data:this.manager,
                    headers:{'Content-Type' : 'application/x-www-form-urlencoded;charset=utf-8'}
                })

注意:字符编码需要写上,可能会因为编码问题导致接收到的参数为乱码;

此时后端就可以用@RequestParam 去匹配对应的参数名,当然前后端名字相同该注解可以省略

总而言之,@RequestBody注解对应请求头类型:{'Content-Type' : 'application/json'},后面跟实体类对象;@RequestParam注解对应请求头类型:{'Content-Type' : 'application/x-www-form-urlencoded;charset=utf-8'},后面匹配具体参数;两个注解不能同时用

我在这里吃了大亏,找了两天才发现,当初学习时也未注意

 

 

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值