您好,登錄后才能下訂單哦!
本篇內容主要講解“Springboot下SpringMVC的常用配置方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Springboot下SpringMVC的常用配置方法”吧!
Sprinboot中配置SpringMVC主要是繼承WebMvcConfigurerAdapter(1.x版本)或者WebMvcConfigurationSupport(2.x版本)。這次主要介紹下web應用的一些常用配置。
參數解析器的作用,通俗來說,參數解析器的作用是將請求中的參數映射到我們Controller方法參數,比如說通過參數解析器,我們可以將前端傳過來的token參數做一下處理,從redis中取出用戶信息,直接映射為一個userInfo對象,然后Controller方法的參數就直接是UserInfo類型的對象就可以了。如何使用勒?下面是一個簡單范例,這里只貼出偽代碼:
首先我們創建一個解析器類,并且實現HandlerMethodArgumentResolver接口。
public class TokenHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { private RedissonClient redissonClient; private UserDao userDao; public TokenHandlerMethodArgumentResolver(RedisClient redisClient, UserDao userDao) { this.redissonClient = redisClient; this.userDao = userDao; } @Override public boolean supportsParameter(MethodParameter methodParameter) { return User.class.isAssignableFrom(methodParameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception{ HttpServletRequest nativeRequest = (HttpServletRequest) nativeWebRequest.getNativeRequest(); String token = nativeRequest.getHeader("token"); RBucket<String> userIdBucket = redissonClient.getBucket(token); if(StringUtils.isNotBlank(userIdBucket.get())){ User user = userDao.getById(userIdBucket.get()); } return user; } }
然后創建類MyWebConfig,繼承WebMvcConfigurerAdapter并實現ApplicationContextAware接口,為什么實現ApplicationContextAware,是為了從IOC容器當中取出redissonClient和userDao,用于構造TokenHandlerMethodArgumentResolver。
public class MyWebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { private UserDao userDao; private RedissonClient redissonClient; @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new TokenHandlerMethodArgumentResolver(redissonClient,userDao)); super.addArgumentResolvers(argumentResolvers); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { userDao = applicationContext.getBean(UserDao.class); redissonClient = applicationContext.getBean(RedissonClient.class); } }
如上,HandlerMethodArgumentResolver最重要的兩個方法是boolean supportsParameter(MethodParameter methodParameter)
和 Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)
,前者是如果返回ture表示使用該解析器進行解析,后者就是返回處理后的方法參數。另外例子中比較關鍵的方法有通過NativeWebRequest獲取HttpServletRequest的方法 nativeWebRequest.getNativeRequest()。
這里的邏輯是,如果參數中有參數的類型是User類型,那么直接通過token去獲取注入在這里。對于我們來說,如果需要用戶信息就只需要在Controller中加個User參數,就自動有了,不需要自己查,就可以很方便的引用用戶的相關信息。
配置數據序列化有兩種方式,一個是通過添加Formatter,一個是添加Converter,兩者區別不大,SpingMVC內部處理Formatter時也是包裝了一層Converter。同時這里值得注意的是,Formatter和Converter是在SpringMVC使用默認RequestParamMethodArgumentResolver或ServletModelAttributeMethodProcessor參數解析器情況下使用的,如果你自定義了參數解析器,那么其接管的參數,轉換規則由自定義參數解析器里面的邏輯來確定。
另外主要被應用于form表單參數或query參數字段,Json傳參不是用這個,Json傳參默認參數解析器是:RequestResponseBodyMethodProcessor,針對的主要是@RequestBody修飾的方法參數,調用的消息轉換器會用Jackson的ObjectMapper來序列化或反序列化,所以如果是JSON傳參,配置這個東西沒有用。
以配置一個LocalDateTime類與字符串之間的轉換為例:
首先新建一個類LocalDateTimeFormatter如下:
public class LocalDateTimeFormatter implements Formatter<LocalDateTime> { private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss:mm"); @Override public LocalDateTime parse(String s, Locale locale) throws ParseException { return LocalDateTime.parse(s, dateTimeFormatter); } @Override public String print(LocalDateTime localDateTime, Locale locale) { return dateTimeFormatter.format(localDateTime); } }
其中parse方法主要是將字符串轉換為對象的邏輯,print方法是將對象轉換為字符串的邏輯。
然后注冊該Formatter,在MyWebConfig重寫public void addFormatters(FormatterRegistry registry) 方法:
@Override public void addFormatters(FormatterRegistry registry) { registry.addFormatter(new LocalDateTimeFormatter()); super.addFormatters(registry); }
這樣,當不是json傳參的時候,默認情況下會使用這個自定義的格式化器進行字符串和對象的轉換。
一般情況下我們使用Formatter替代Converter,兩者作用差不多。Converter的好處是因為有兩個泛型參數,可以限制需要轉換的類型和要轉換為的類型,但翻看源碼發現在引用converter的時候判斷選用哪個converter傳入的來源類型貌似都是String(就算query參數是一個數字),感覺formatter已經夠用了,這里存疑把。
converter的用法很簡單,只需要往spring容器里面注冊一個實現了org.springframework.core.convert.converter的bean,除了這種形式,也可以直接注冊ConverterFactory實現獲取converter的工廠方法<T extends R> Converter<S, T> getConverter(Class<T> targetType)
,用在一個來源類型,多個目標類型的場景。另外還有GenericConverter,需實現Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
方法,用于多個來源類型,多個目標類型的場景,返回值直接為轉換后的值。
配置靜態資源重寫的方法為:void addResourceHandlers(ResourceHandlerRegistry registry)
,如重寫方法為:
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**").addResourceLocations("classpath:/upload/"); super.addResourceHandlers(registry); }
其中addResourceHandler("/upload/**").addResourceLocations("classpath:/upload/")
的意思表示將URL:項目訪問url+upload/xxx映射到classpath下的upload目錄里面名為XXX的靜態資源,其中addResourceLocations參數為變長參數,可以映射多個路徑,也可以前面加'file:',映射磁盤上任意目錄,如:file:/D://upload/
,表示映射到d盤的upload目錄。
添加過濾器只需要注冊一個FilterRegistrationBean類對象到spring容器即可,如在測試環境注冊一個允許跨域的過濾器:
@Conditional(value = {TestCondition.class}) @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setOrder(10); filterRegistrationBean.setFilter(new CorsFilter(urlBasedCorsConfigurationSource)); filterRegistrationBean.setName("corsFilter"); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; }
@Conditional注解標識在上面表示在測試環境即引用的aplication-test.yml|properties,這里的value應該傳入一個org.springframework.context.annotation.Condition接口實現類的Class對象。這里傳入的是TestCondition。代碼如下:
@Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { Environment environment = conditionContext.getEnvironment(); String[] activeProfiles = environment.getActiveProfiles(); if (null != activeProfiles) { for (String x : activeProfiles) { if ("test".equals(x)) { return true; } } } return false; }
另外對于自定義的過濾器,常規操作如下:
繼承OncePerRequestFilter抽象類,實現doFilterInternal方法。
將這個Filter對象注入到filterRegistrationBean,并配置其他信息,如order,已經過濾的Url。
如:
@Bean public FilterRegistrationBean myFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new MyFilter()); //order越小,優先級越高 filterRegistrationBean.setOrder(1); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.setName("myFilter"); return filterRegistrationBean; }
攔截器與過濾器的區別在于過濾器的優先級比攔截器高,Filter是作用于Servlet前,而Interceptor則相對于Filter更靠后一點。另外Filter不可以使用IOC容器資源,Interceptor則可以。過濾器能完成的功能,通過Interceptor都可以完成,通常情況下,推薦使用Interceptor。
配置攔截器的步驟是:
HandlerInterceptorAdapter有三個方法可以重寫,未重寫前不做任何處理。三個方法是:
//在業務處理器處理請求之前被執行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception { return true; } //在業務處理器處理請求返回響應之前執行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception { } //返回響應之后執行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception { }
在MyWebConfig類重寫方法void addInterceptors(InterceptorRegistry registry),如:
@Override public void addInterceptors(InterceptorRegistry registry) { // 可以多個攔截器組成一個攔截器鏈 // addPathPatterns 用于添加攔截規則 // excludePathPatterns 用于排除攔截 registry.addInterceptor(new MyInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/swagger*/**"); super.addInterceptors(registry); }
以上就是基于Springboot下的SpringMVC常用配置方法,基本上能滿足常用項目配置需求,其他就暫時不作了解了。
到此,相信大家對“Springboot下SpringMVC的常用配置方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。