SpringBoot Controller接收参数的几种常用方式

SpringBoot Controller接收参数的几种常用方式

第一类:请求路径参数

1、@PathVariable

获取路径参数。即url/{id}形式的参数。

2、@RequestParam

获取查询参数。即url?name=张三形式的参数。

举例
GET http://localhost:8080/demo/321?name=zhangsan

@GetMapping("/demo/{id}")
public void demo(@PathVariable(name = "id") String id, @RequestParam(name = "name") String name) {
    System.out.println("id="+id);
    System.out.println("name="+name);
}

输出结果:
id=321
name=zhangsan

第二类:Body参数

POST请求或者GET请求都可以接收,这里用Postman的截图结合代码说明

1、@RequestBody

例子

方式一:

@PostMapping(path = "/demo1")
// @GetMapping(path = "/demo1")
public void demo1(@RequestBody Person person) {
    System.out.println(person.toString());
}

输出结果:
name:suki_rong;age=18;hobby:programing

方式二:

也可以是这样

@PostMapping(path = "/demo1")
// @GetMapping(path = "/demo1")
public void demo1(@RequestBody Map<String, String> person) {
    System.out.println(person.get("name"));
}

输出结果:
suki_rong

2、无注解

例子

@PostMapping(path = "/demo2")
public void demo2(Person person) {
    System.out.println(person.toString());
}

输出结果:
name:suki_rong;age=18;hobby:programing

Person类

public class Person {
    private long id;
    private String name;
    private int age;
    private String hobby;

    @Override
    public String toString(){
        return "name:"+name+";age="+age+";hobby:"+hobby;
    }
    // getters and setters
}

第三类:请求头参数以及Cookie

1、@RequestHeader

2、@CookieValue

例子

@GetMapping("/demo3")
public void demo3(@RequestHeader(name = "myHeader") String myHeader,@CookieValue(name = "myCookie") String myCookie) {
    System.out.println("myHeader=" + myHeader);
    System.out.println("myCookie=" + myCookie);
}

也可以这样

@GetMapping("/demo3")
public void demo3(HttpServletRequest request) {
    System.out.println(request.getHeader("myHeader"));
    for (Cookie cookie : request.getCookies()) {
        if ("myCookie".equals(cookie.getName())) {
            System.out.println(cookie.getValue());
        }
    }
}

springboot自定义用户参数(拦截controller的参数进行操作)

在业务逻辑中,会有这样的场景:

需要将用户信息存到session中,为保证用户信息安全,将cookie的值设置为uuid,将存储用户信息的session的key设置为cookie的uuid。

@Override
public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
    String mobile = loginVo.getMobile();
    String password = loginVo.getPassword();
    /*
        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(password)) {
            return RespBean.error(RespBeanEnum.LOGINERROR);
        }
        if (!ValidatorUtil.isMobile(mobile)){
            log.info("{}",ValidatorUtil.isMobile(mobile));
            return RespBean.error(RespBeanEnum.MOBILEERROR);
        }
     */
    User user = userMapper.selectById(mobile);
    if (null == user) {
        throw new GlobalException(RespBeanEnum.LOGINERROR);
    }
    String pass = Md5Util.formPassToDBPass(password, user.getSalt());
    if (!pass.equals(user.getPassword())) {
        throw new GlobalException(RespBeanEnum.LOGINERROR);
    }
    //使用uuid作为session的键,并将其存到cookie中
    String ticket = UUIDUtil.uuid();
    CookieUtil.setCookie(request, response, "userTicket", ticket);
    //将用户对象存入session,用uuid做为键
    request.getSession().setAttribute(ticket, user);
    return RespBean.success(ticket);
}

这种场景下,如果不设置登录拦截器,那么各种核心业务逻辑中全部都需要判断用户是否登录或要将用户返回到页面,就要在每个controller中获取cookie,然后用cookie得到session中存储的用户信息。

@GetMapping("toList")                                 //使用注解获取cookie的值
public String toList(HttpSession session, Model model,@CookieValue("userTicket") String ticket) {
    //从cookie中获取uuid
    if (StringUtils.isBlank(ticket)) {
        return "login";
    }
    //用获取的uuid取出session中的用户对象
    User user = (User) session.getAttribute(ticket);
    if (null == user) {
        return "login";
    }
    model.addAttribute("user",user);
    return "goodsList";
}

如果只是一个业务还好,但事情往往没有这么简单,为满足代码复用及代码优雅,需要简化写法。
在springboot中可以配置自定义用户参数,相当于拦截controller方法中的User参数,自己注入User的返回对象。
使用自定义用户参数的业务代码获取用户对象只需要把用户对象放到controller方法的参数列表中即可:

@PostMapping("doSeckill")
public String doSecKill(Model model, User user,Long goodsId) {
    if (null == user) {
        return "login";
    }
    model.addAttribute("user",user);
    return "orderDetail";
}

配置方法如下:(与拦截器配置和静态资源映射配置相似)

  1. 新建WebConfig类
  2. 实现WebMvcConfigurer接口
  3. 重写addArgumentResolvers方法
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Resource
    private UserArgumentResolver userArgumentResolver;

    /**
     * 添加自定义控制器参数拦截
     * @param resolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userArgumentResolver);
        System.out.println("argumentResolvers"+resolvers);
    }

}

创建自定义拦截参数类:UserArgumentResolver实现HandlerMethodArgumentResolver重写supportsParameter方法和resolveArgument方法。(supportsParameter方法返回true那么就会执行下面的resolveArgument方法) ----在resolveArgument方法中书写获取cookie的值进而获取session中用户信息并进行返回。

@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    @Resource
    private UserService userService;

    /**
     * 返回true执行下面的resolveArgument方法
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class<?> clazz = methodParameter.getParameterType();
        System.err.println("拦截到user");
        return clazz == User.class;
    }


    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
        String userTicket = CookieUtil.getCookieValue(request, "userTicket");
        System.err.println("用户参数拦截:"+userTicket);
        //获取不到cookie中的用户凭证
        if (StringUtils.isBlank(userTicket)) {
            return null;
        }
        return userService.getUserByCookie(userTicket, request, response);
    }
}

最后在WebConfig 类中注入UserArgumentResolver ,并添加到addArgumentResolvers方法中。
现在只需要在controller对应的业务逻辑方法的参数列表中声明User即可自动调用resolveArgument方法得到用户对象。

参考

posted @ 2022-03-30 22:45  黄河大道东  阅读(709)  评论(0编辑  收藏  举报