自定義Controller方法參數解析器
- 2019 年 12 月 19 日
- 筆記
自定義Controller方法參數注入,比如主動注入當前用戶等等
核心類:HandlerMethodArgumentResolver
package org.springframework.web.method.support; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; /** * Strategy interface for resolving method parameters into argument values in * the context of a given request. * * @author Arjen Poutsma * @since 3.1 * @see HandlerMethodReturnValueHandler */ public interface HandlerMethodArgumentResolver { /** * Whether the given {@linkplain MethodParameter method parameter} is * supported by this resolver. * @param parameter the method parameter to check * @return {@code true} if this resolver supports the supplied parameter; * {@code false} otherwise */ boolean supportsParameter(MethodParameter parameter); /** * Resolves a method parameter into an argument value from a given request. * A {@link ModelAndViewContainer} provides access to the model for the * request. A {@link WebDataBinderFactory} provides a way to create * a {@link WebDataBinder} instance when needed for data binding and * type conversion purposes. * @param parameter the method parameter to resolve. This parameter must * have previously been passed to {@link #supportsParameter} which must * have returned {@code true}. * @param mavContainer the ModelAndViewContainer for the current request * @param webRequest the current request * @param binderFactory a factory for creating {@link WebDataBinder} instances * @return the resolved argument value, or {@code null} if not resolvable * @throws Exception in case of errors with the preparation of argument values */ @Nullable Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception; }
這個介面中有兩個方法,supportsParameter用於判斷是否通過本解析器解析該參數,resolveArgument用於編寫解析的邏輯,返回的對象賦值給方法的相對應的參數。
舉個例子
import lombok.Data; /** * @author donghaibin */ @Data public class User { private String name; private String age; }
一個User對象,現在需要在Controller的一個介面中獲取當前請求的User,最直接的方法是在方法體中編寫邏輯獲取,但這樣寫不是那麼的優雅。另一種方法就是通過HandlerMethodArgumentResolver實現。
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; /** * @author donghaibin */ public class UserArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { // isAssignableFrom方法判斷類型是否為本身或者子類 return methodParameter.getParameterType().isAssignableFrom(User.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { // 這裡測試直接構建一個對象返回 User user = new User(); user.setAge("18"); user.setName("DHB"); return user; } }
import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; /** * @author donghaibin */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { // 添加進參數解析器集合 resolvers.add(new UserArgumentResolver()); } }
測試
import cn.dhbin.test.config.User; import cn.dhbin.test.config.UserFlag; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author donghaibin */ @RestController @Slf4j public class TestController { @RequestMapping("/test") public String test(String a, User user) { log.info(user.toString()); return a; } }
結果
2019-07-18 23:47:14.535 INFO 44852 --- [nio-8080-exec-1] cn.dhbin.test.controller.TestController : User(name=DHB, age=11)
總結
通過這個demo大概明白自定義參數解析只需兩步
- 繼承HandlerMethodArgumentResolver編寫解析邏輯
- 重寫WebMvcConfigurer的addArgumentResolvers方法,添加自定義的解析器到參數解析器集合中