springboot自定義引數解析HandlerMethodArgumentResolver
阿新 • • 發佈:2020-07-28
自定義解析器需要實現HandlerMethodArgumentResolver
介面,HandlerMethodArgumentResolver
介面包含兩個介面函式:
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter var1);
@Nullable
Object resolveArgument(MethodParameter var1, @Nullable ModelAndViewContainer var2, NativeWebRequest var3, @Nullable WebDataBinderFactory var4) throws Exception;
}
自定義一個解析器CurrentUserMethodArgumentResolver
我們在解析器中返回一個固定的UserBeannew UserBean(1L,"admin")
,實際情況是從Session、資料庫或者快取中查。
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
* 用於繫結@CurrentUser的方法引數解析器
*
* @author lism
*/
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
public CurrentUserMethodArgumentResolver() {
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.getParameterType().isAssignableFrom(UserBean.class) && parameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CurrentUser currentUserAnnotation = parameter.getParameterAnnotation(CurrentUser.class);
//從Session 獲取使用者
Object object = webRequest.getAttribute(currentUserAnnotation.value(), NativeWebRequest.SCOPE_SESSION);
//從 accessToken獲得使用者資訊
if (object == null) {
String token = webRequest.getHeader("Authorization");
if (token == null) {
token = webRequest.getParameter("accessToken");
}
//為了測試先寫死使用者名稱
//TODO: 取真實使用者
return new UserBean(1L,"admin");
}
return object;
}
}
自定義註解@CurrentUser
import java.lang.annotation.*;
/**
* <p>綁定當前登入的使用者</p>
* <p>不同於@ModelAttribute</p>
*
* @author lism
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentUser {
/**
* 當前使用者在request中的名字
*
* @return
*/
String value() default "user";
}
在控制器中使用@CurrentUser
在控制器方法上加入@CurrentUser UserBean userBean
即可自動注入userBean的值
@RestController
@RequestMapping(value = "/test")
public class TestController {
/**
* 根據name查詢
*
* @param request
* @return
*/
@RequestMapping(value = "/testCurrentUser", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
@ResponseBody
public void test(@CurrentUser UserBean userBean, @RequestBody SubjectRequest request) {
String createdBy = userBean.getUsername();
log.info(createdBy);
}
}
User實體UserBean
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserBean implements Serializable {
private Long id;
private String username;
}
總結
我們可以通過實現HandlerMethodArgumentResolver
介面來實現對自定義的引數進行解析。
比如可以解析自定義的時間格式、自定義解析Map物件等這些spring原本不支援的物件格式。