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";
}
配置方法如下:(與攔截器配置和靜態資源映射配置相似)
- 新建WebConfig類
- 實現WebMvcConfigurer接口
- 重寫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方法得到用戶對象。