关于在@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'},后面匹配具体参数;两个注解不能同时用

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

 

 

你可能感兴趣的:(java,开发语言)