HandlerMethodArgumentResolver 是什麼? 就是用於解析參數的一個介面,springMVC(4.1)會直接調用這個介面的方法,對參數進行一定的解析。比如會在 具體實現: 1.@CurrentUser @Target({ElementType.PARAMETER}) @Ret ...
HandlerMethodArgumentResolver 是什麼?
就是用於解析參數的一個介面,springMVC(4.1)會直接調用這個介面的方法,對參數進行一定的解析。比如會在
InvocableHandlerMethod.getMethodArgumentValues()中調用,並解析方法參數。
具體如圖:
然後就會根據這個resolver的規則進行參數的解析。
如何實現?
下麵我們可以自定義一個resolver並實現:
具體實現:
1.@CurrentUser
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CurrentUser { /** * 當前用戶在request中的名字 * * @return */ String value() default "user"; }View Code
2.CurrentUserMethodArgumentResolver
package com.spring.custom_anno; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; 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; @Component 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; } }View Code
3.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; }View Code
4.Controller
import org.springframework.web.bind.annotation.*; @RestController public class TestController { @RequestMapping(value = "/testCurrentUser", method = RequestMethod.POST, produces = "application/json", consumes = "application/json") public void test(@CurrentUser UserBean userBean) { String createdBy = userBean.getUsername(); System.out.println(createdBy); } }View Code
5.配置
1.(在XML中自定義傳統項目做法,註意 自動掃描一定要放在resolver配置的下麵才能生效。。實踐過)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 基本包掃描 --> <context:component-scan base-package="com.spring" /> <!-- 註冊HandlerMapper、HandlerAdapter兩個映射類,負責將請求映射到類和方法中 --> <mvc:annotation-driven> <mvc:argument-resolvers> <bean class="com.spring.custom_anno.CurrentUserMethodArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven> <mvc:annotation-driven /> <!-- 訪問靜態資源,如js, css文件等 --> <mvc:default-servlet-handler /> <!-- 視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>View Code
2.(springboot)
只需要在CurrentUserMethodArgumentResolver 類上加上@Component就行了。