環(huán)境:SpringBoot2.7.12
@Configuration@EnableWebMvcpublic class WebConfig {}如需要自定義數(shù)據(jù)類型的轉(zhuǎn)換,可以通過如下方式注冊
@Configurationpublic class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(new ConverterFactory<String, Number>() { @Override public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) { return new Converter<String, T>() { public T convert(String source) { return (T) Integer.valueOf(source) ; } } ; } }); } }以上添加了從String到Integer的轉(zhuǎn)換(這里只是舉例,系統(tǒng)默認(rèn)已經(jīng)有了從String到Number的轉(zhuǎn)換器)。每種轉(zhuǎn)換器最終被包裝成ConvertersForPair對象,該對象中有個隊(duì)列保存了所有的轉(zhuǎn)換器。后添加的添加到首位,如下:
private static class ConvertersForPair { private final Deque<GenericConverter> converters = new ConcurrentLinkedDeque<>(); public void add(GenericConverter converter) { this.converters.addFirst(converter); }}所有如你有自定義的轉(zhuǎn)換器,自定義的優(yōu)先級比系統(tǒng)自帶的要高。
默認(rèn)情況下,如果類路徑上存在 Bean Validation(例如 Hibernate Validator),則 LocalValidatorFactoryBean 會被注冊為全局 Validator,與控制器方法參數(shù)上的 @Valid 和 Validated 一起使用。
@Configurationpublic class WebConfig implements WebMvcConfigurer { public Validator getValidator() { return new LocalValidatorFactoryBean(); }}4. 請求攔截器
@Configurationpublic class WebConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getHeader("token") == null) { return false ; } return true ; } }).addPathPatterns("/**") ; }}上面配置了一個攔截任意請求的攔截器,在請求到達(dá)時會先驗(yàn)證請求header中token是否為null。
攔截器并不適合作為安全層,因?yàn)樗锌赡芘c控制器Controller路徑匹配不匹配,而Controller路徑匹配還可以透明地匹配尾部斜線和路徑擴(kuò)展名以及其他路徑匹配選項(xiàng)。其中許多選項(xiàng)已被棄用,但仍有可能出現(xiàn)不匹配。一般情況下,我們建議使用 Spring Security,它包含一個專用的 MvcRequestMatcher,可與 Spring MVC 路徑匹配保持一致,還具有安全防火墻,可阻止 URL 路徑中許多不需要的字符。
自定義Spring MVC 如何從請求中確定所請求的媒體類型(例如,接受頭、URL 路徑擴(kuò)展、查詢參數(shù)等)。
默認(rèn)情況下,只選中"Accept" header。
@Configurationpublic class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { // 這樣配置后,視圖技術(shù)就能夠根據(jù)你請求的Accept輸出指定的文件內(nèi)容了 configurer.mediaType("yaml", new MediaType("application", "yaml")) ; }}上面的配置最終是對ContentNegotiationManager對象進(jìn)行添加MappingMediaTypeFileExtensionResolver文件擴(kuò)展解析器。
@Beanpublic ContentNegotiationManager mvcContentNegotiationManager() { if (this.contentNegotiationManager == null) { ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext); configurer.mediaTypes(getDefaultMediaTypes()); configureContentNegotiation(configurer); this.contentNegotiationManager = configurer.buildContentNegotiationManager(); } return this.contentNegotiationManager;}protected ContentNegotiationManager buildContentNegotiationManager() { this.factory.addMediaTypes(this.mediaTypes); return this.factory.build();}部分代碼
public class ContentNegotiationManagerFactoryBean { public ContentNegotiationManager build() { if (!CollectionUtils.isEmpty(this.mediaTypes) && !this.favorPathExtension && !this.favorParameter) { this.contentNegotiationManager.addFileExtensionResolvers( new MappingMediaTypeFileExtensionResolver(this.mediaTypes)); } }}有了MappingMediaTypeFileExtensionResolver解析器后,還需要Controller接口返回ModelAndView對象。如下接口
@GetMapping("/contentType")public ModelAndView contentType() { return new ModelAndView("test") ;}在classpath下新建test.yaml文件,內(nèi)容隨意。有了這些還不夠,我們需要能夠解析處理*.yaml的文件。所以還需要視圖解析器
@Componentpublic class YamlViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { if (!viewName.endsWith(".yaml")) { return null ; } return new View() { // 支持的類型 public String getContentType() { return "application/yaml" ; }; @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { ClassPathResource resource = new ClassPathResource(viewName) ; InputStream is = resource.getInputStream() ; OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = is.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush() ; is.close(); outputStream.close() ; } } ; }}有了這些我們配置Spring MVC才能正確的輸出我們所需要的文件內(nèi)容。這個功能是不是太麻煩了,沒撒用
本文鏈接:http://m.www897cc.com/showinfo-26-70401-0.htmlSpring MVC核心擴(kuò)展點(diǎn)及使用技巧總結(jié)和使用案例
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com