SpringBoot中MVC的自動(dòng)配置詳解
SpringBoot中MVC的自動(dòng)配置詳解
一個(gè)簡單的例子
public class MvcModel { private String modelName; private Integer modelType; /**省略geter、setter方法**/ } @RestController @EnableAutoConfiguration public class SpringMvcGuide { @RequestMapping("/getModel") public MvcModel getMvcModel(){ MvcModel mvcModel = new MvcModel(); mvcModel.setModelName("小明"); mvcModel.setModelType(1); return mvcModel; } public static void main(String[] args){ SpringApplication.run(SpringMvcGuide.class,args); } }
啟動(dòng)服務(wù),訪問//localhost:8080/getModel可以看到頁面顯示
{"modelName":"小明","modelType":1}
頁面上展示會將MvcModel對象轉(zhuǎn)換成json字符串,這是我們最常用的格式,后臺統(tǒng)一返回json格式,前臺接收到j(luò)son格式后進(jìn)行解析
在實(shí)際開發(fā)過程中,還有一些老的系統(tǒng)在使用xml格式來傳輸數(shù)據(jù),SpringBoot也提供了xml格式數(shù)據(jù)的返回,只需要小小的改動(dòng),就可以實(shí)現(xiàn)
增加依賴
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.2' compile 'org.glassfish.jaxb:jaxb-runtime:2.3.3'
將實(shí)體類打上@XmlRootElement注解
@XmlRootElement public class MvcModel { private String modelName; private Integer modelType; /**省略geter、setter方法**/ }
重新啟動(dòng)項(xiàng)目,訪問//localhost:8080/getModel可以看到頁面顯示
<MvcModel>
<modelName>小明</modelName>
<modelType>1</modelType>
</MvcModel>
從上面的例子可以看出來,想返回xml格式的數(shù)據(jù)只需要引入相應(yīng)的jar包就行了,無需修改任何配置
Spring MVC自動(dòng)配置
SpringBoot為SpringMVC提供了自動(dòng)配置,除了SpringMVC默認(rèn)的配置外還提供了以下配置:
- 引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。
- 對靜態(tài)資源的支持,包括對WebJars的支持
- 自動(dòng)注冊Converter,GenericConverter,F(xiàn)ormatter beans。
- 對HttpMessageConverters的支持。
- 自動(dòng)注冊MessageCodeResolver。
- 對靜態(tài)index.html的支持。
- 對自定義Favicon的支持。
- 自動(dòng)使用ConfigurableWebBindingInitializer bean。
如果你想保留SpringBoot MVC的特性,只需要增加相應(yīng)的MVC配置(如攔截器、格式化處理器、視圖控制器),如果你想全面的控制Spring MVC,也可以實(shí)現(xiàn)自己的配置,并使用@EnableWebMvc注解
HttpMessageConverters
Spring MVC使用HttpMessageConverter來轉(zhuǎn)換HTTP請求和響應(yīng)中的數(shù)據(jù),比如對象自動(dòng)轉(zhuǎn)換成JSON或XML對象,這些轉(zhuǎn)換的處理類都是SpringBoot默認(rèn)都配置好了,你不需要做任何配置就可以實(shí)現(xiàn)數(shù)據(jù)的轉(zhuǎn)換,當(dāng)然也提供了自定義HttpMessageConverters的方法,上下文中出現(xiàn)的所有HttpMessageConverter bean都會被添加到converter列表,你可以通過這種方式來覆蓋默認(rèn)的轉(zhuǎn)換器列表。下面通過一個(gè)例子來演示一下如何自定義HttpMessageConverter
默認(rèn)轉(zhuǎn)換json的轉(zhuǎn)換器是使用的jackson,我們先來看看默認(rèn)的例子
@RestController @SpringBootApplication public class SpringMvcGuide { @RequestMapping("/getStudent") public Student getStudent(){ Student stu = new Student(); stu.setName("小明"); return stu; } public static void main(String[] args){ SpringApplication.run(SpringMvcGuide.class,args); } }
public class Student { private String name; private int age; private String address; /** 省略getter、setter方法 **/ }
啟動(dòng)程序,訪問//localhost:8080/getStudent ,頁面顯示
{"name":"小明","age":0,"address":null}
可以看到Student對象被轉(zhuǎn)換成json字符串,age默認(rèn)值為0,address默認(rèn)為null
下面我們替換成fastjson,并且String類型的默認(rèn)值為空字符串
首先引入依賴
compile 'com.alibaba:fastjson:1.2.58'
添加HttpMessageConverter配置類
@Configuration public class HttpMessageConverterConfig { @Bean public HttpMessageConverter fastJsonHttpMessageConverter(){ FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); SerializerFeature[] serializerFeatures = new SerializerFeature[]{ SerializerFeature.QuoteFieldNames,//輸出Key是否包含雙引號 SerializerFeature.WriteMapNullValue,//是否輸出為null的字段,若為null則顯示該字段 SerializerFeature.WriteNullNumberAsZero,//數(shù)字若為null,輸出0 SerializerFeature.WriteNullListAsEmpty, //list為null,輸出[] SerializerFeature.WriteNullStringAsEmpty,//String為null,輸出"" SerializerFeature.WriteNullBooleanAsFalse,//boolean為null,輸出false SerializerFeature.WriteDateUseDateFormat,//Date的日期轉(zhuǎn)換器 SerializerFeature.DisableCircularReferenceDetect //循環(huán)引用 }; fastJsonConfig.setSerializerFeatures(serializerFeatures); fastJsonConfig.setCharset(Charset.forName("UTF-8")); fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig); List<MediaType> mediaTypeList = new ArrayList<MediaType>(); mediaTypeList.add(MediaType.APPLICATION_JSON); fastJsonHttpMessageConverter.setSupportedMediaTypes(mediaTypeList); return fastJsonHttpMessageConverter; } }
重新啟動(dòng)程序,訪問//localhost:8080/getStudent,頁面顯示
{"address":"","age":0,"name":"小明"}
可以看到address默認(rèn)值已經(jīng)變成空字符串,說明我們引入的fastjson生效了
自定義Json序列化和反序列化
如果你使用Jackson來序列化和反序列化json數(shù)據(jù),你可能需要寫自己的JsonSerializer和JsonDeserializer類,自定義序列化器通常通過Module注冊到Jackson,但SpringBoot提供了@JsonComponent注解能輕松的將序列化器注冊為Spring Bean
您可以直接在JsonSerializer、JsonDeserializer或KeyDeserializer實(shí)現(xiàn)上使用@JsonComponent注釋。還可以在包含序列化器/反序列化器的內(nèi)部類上使用它,如下面的示例所示
@JsonComponent public class Example { public static class Serializer extends JsonSerializer<SomeObject> { // ... } public static class Deserializer extends JsonDeserializer<SomeObject> { // ... } }
ApplicationContext中的所有@JsonComponent bean都會自動(dòng)注冊到Jackson中。 因?yàn)锧JsonComponent是用@Component進(jìn)行元注釋的,所以通常的組件掃描規(guī)則也適用。
Spring Boot還提供了JsonObjectSerializer和JsonObjectDeserializer基類,在序列化對象時(shí)為標(biāo)準(zhǔn)Jackson版本提供了有用的替代方案。詳情可以自行查閱JsonObjectSerializer和JsonObjectDeserializer,這里不再展開
靜態(tài)內(nèi)容
默認(rèn)情況下,Spring Boot從類路徑中的/static(/public,/resources,/META-INF/resources)目錄或ServletContext的根目錄中提供靜態(tài)內(nèi)容。它是使用Spring MVC中的ResourceHttpRequestHandler來實(shí)現(xiàn)的, 這樣你就可以通過添加自己的WebMvcConfigurer和覆蓋addResourceHandlers方法來進(jìn)行自定義
在獨(dú)立的web應(yīng)用程序中,容器中的默認(rèn)servlet也被啟用,并充當(dāng)后備,如果Spring決定不處理ServletContext,則從ServletContext的根提供內(nèi)容。大多數(shù)情況下,這種情況不會發(fā)生(除非您修改了默認(rèn)的MVC配置),因?yàn)镾pring總是可以通過DispatcherServlet處理請求
默認(rèn)情況下,資源映射到/**上,但是您可以使用spring.mvc.static-path-pattern屬性來進(jìn)行調(diào)整。例如,將所有資源重新定位到/resources/**,可以通過如下配置實(shí)現(xiàn)
spring: mvc: static-path-pattern: "/resources/**"
還可以使用spring.web.resources來定制靜態(tài)資源位置,除了前面提到的靜態(tài)資源位置之外,Webjars內(nèi)容也是一個(gè)特殊情況,任何/webjars/**路徑的資源都是從jar文件中提供的,前提是它們是以webjars格式打包的
模板引擎
除了REST web服務(wù)之外,還可以使用Spring MVC來提供動(dòng)態(tài)HTML內(nèi)容。Spring MVC支持多種模板技術(shù) (包括Thymeleaf、FreeMarker和jsp), 此外,許多其他模板引擎也包含它們自己的Spring MVC集成。
Spring Boot支持以下模板引擎的自動(dòng)配置:
- FreeMarker
- Groovy
- Thymeleaf
- Mustache
當(dāng)您使用上述模板引擎之一時(shí),將會自動(dòng)從src/main/resources/templates目錄下獲取模板
異常/錯(cuò)誤的處理
默認(rèn)情況下,Spring Boot提供了一個(gè)/error映射,它以一種合理的方式處理所有錯(cuò)誤,并在servlet容器中注冊為一個(gè)“全局”錯(cuò)誤頁面。對于機(jī)器客戶端來說,它生成一個(gè)JSON響應(yīng),其中包含錯(cuò)誤、HTTP狀態(tài)和異常消息的詳細(xì)信息。對于瀏覽器客戶端,有一個(gè)“whitelabel”錯(cuò)誤視圖,它以HTML格式呈現(xiàn)相同的數(shù)據(jù)
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Mar 03 22:46:49 CST 2021
There was an unexpected error (type=Not Found, status=404).
對于返回json格式的請求來說,可以定義一個(gè)帶@ControllerAdvice注釋的類,來處理特定的Controller異常信息,如下面的示例所示
@ControllerAdvice(basePackageClasses = AcmeController.class) public class AcmeControllerAdvice extends ResponseEntityExceptionHandler { @ExceptionHandler(YourException.class) @ResponseBody ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) { HttpStatus status = getStatus(request); return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status); } private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (statusCode == null) { return HttpStatus.INTERNAL_SERVER_ERROR; } return HttpStatus.valueOf(statusCode); } }
對于返回頁面的請求,我們一般會定制自己的異常頁面,例如404、500這些異常的狀態(tài)碼都會定位到對應(yīng)的頁面。
比如要對404定制一個(gè)html頁面,可以把頁面放到對應(yīng)的目錄下
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
再比如要對500定制一個(gè)FreeMarker頁面
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 500.ftlh
+- <other templates>
對于更復(fù)雜的映射,您還可以自己實(shí)現(xiàn)ErrorViewResolver接口,如下面的示例所示:
public class MyErrorViewResolver implements ErrorViewResolver { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // Use the request or status to optionally return a ModelAndView return ... } }
你也可以使用Spring MVC的常規(guī)特性,比如@ExceptionHandler方法和@ControllerAdvice
跨域支持
跨源資源共享(CORS)是由大多數(shù)瀏覽器實(shí)現(xiàn)的W3C規(guī)范,它允許您以靈活的方式指定哪種跨域請求得到授權(quán),而不是使用一些不太安全、功能不太強(qiáng)大的方法,如IFRAME或JSONP。
從4.2版開始,Spring MVC支持CORS。在Spring Boot應(yīng)用程序中使用帶有@CrossOrigin注釋的Controller方法不需要任何特定的配置。通過使用自定義的addcorsmapping (CorsRegistry)方法注冊WebMvcConfigurer bean,可以定義全局CORS配置,如下面的示例所示:
@Configuration(proxyBeanMethods = false) public class MyConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**"); } }; } }
到此這篇關(guān)于SpringBoot中MVC的自動(dòng)配置詳解的文章就介紹到這了,更多相關(guān)MVC的自動(dòng)配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Spring?Cloud?Gateway中的令牌桶限流算法
這篇文章主要為大家淺析了Spring?Cloud?Gateway中的令牌桶限流算法原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02springboot內(nèi)嵌Tomcat安全漏洞修復(fù)方式
針對CVE-2020-1938漏洞,建議升級Tomcat至安全版本以避免受影響,影響版本包括:Apache Tomcat 9.x小于9.0.31、Apache Tomcat 8.x小于8.5.51、Apache Tomcat 7.x小于7.0.100及Apache Tomcat 6.x,2024-10-10java公眾平臺通用接口工具類HttpConnectUtil實(shí)例代碼
下面小編就為大家分享一篇java公眾平臺通用接口工具類HttpConnectUtil實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01springboot實(shí)現(xiàn)過濾器的示例代碼
JavaWeb開發(fā)中,過濾器Filter是三大組件之一,主要用于請求攔截和響應(yīng)處理,如權(quán)限校驗(yàn)、日志記錄、請求過濾等,本文就來介紹一下springboot實(shí)現(xiàn)過濾器的示例代碼,感興趣的可以了解一下2024-10-10springboot+springmvc+mybatis項(xiàng)目整合
這篇文章主要為大家詳細(xì)介紹了springboot+springmvc+mybatis項(xiàng)目的整合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04