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方法得到用戶對象。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM