SpringBoot是很是適合開發Web應用的,由於他內嵌有Tomcat、Jetty、Undertow或者Netty。大部分的應用能夠經過加載spring-boot-starter-web模塊可以快速的建立並啓動一個Web應用。html
SpringMVC是一個「model view controller」的Web級的框架。SpringMVC可以用@Controller或者@RestController註解在Bean中攔截相應的HTTP請求。具體請求方法是在用@Controller或者@RestController進行註解的類中的方法裏面。方法用@RequestMapping進行註解。下面的例子展現了典型的@RestController的使用方法。java
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
複製代碼
Spring MVC是Spring框架的一部分,詳細的信息能夠看SpringMVC官方文檔git
SpringMVC不用再像以前同樣用許多的配置文件來開啓各類功能,SpringBoot已經將其許多的功能進行了自動配置化。下面就是SpringBoot針對SpringMVC的自動配置的一些功能:github
若是你想保持上面的功能不變,可是想要額外的添加一些功能。可以使用@Configuration註解進行配置不能加上@EnableWebMvc,若是你不想要上面的功能,想徹底本身定義SpringMVC的功能,那麼就加上@EnableWebMvc。若是想要擁有定製化的RequestMappingHandlerMapping、RequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver,聲明一個WebMvcRegistrationsAdapter實例提供相應的內容。web
SpringMVC使用HttpMessageConverter去轉換從HTTP發出來的請求及響應的內容。HTTP的請求其實都會封裝在ServletInputStream流中,而響應則會封裝在ServletOutputStream流中。而從流中讀取的數據都是原始的字符串的報文,此時就須要將報文進行轉換。而基本上都是字符串和java對象進行互轉的過程。因此SpringMVC用到了HttpMessageConverter來進行解決的。spring
例如如今有一個實體類User,我直接返回頁面UserDao對象。瀏覽器
@RequestMapping("/user")
UserDao getUser(){
return new UserDao("不學無數",23,"HeNan","1111111");
}
複製代碼
此時在訪問的時候就會在頁面發現對象被轉換成了Json字符串bash
若是須要本身定製轉化器的話,能夠在SpringBoot使用HttpMessageConverters進行配置,以下所示:cookie
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
複製代碼
若是使用Jackson去序列化和反序列化JSON數據的話,可能須要本身定製JsonSerializer和JsonDeserializer的類。SpringBoot提供了@JsonComponent註解能夠直接很是容易的將你寫的定製化解析JSON的類註冊在Spring中。網絡
也可使用@JsonComponent直接註解在JsonSerializer和JsonDeserializer的實現上。也能夠註解在類上,類中包含了JsonSerializer和JsonDeserializer的實現.以下所示:
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;
@JsonComponent
public class Example {
public static class Serializer extends JsonSerializer<SomeObject> {
// ...
}
public static class Deserializer extends JsonDeserializer<SomeObject> {
// ...
}
}
複製代碼
默認狀況下,SpringBoot會將放在/static、/public、/resources或者/META-INF/resources目錄下的文件稱爲靜態資源。由於SpringBoot默認配置的映射地址爲/**。例如咱們在項目中resources中建立一下兩個文件夾,而且將靜態的圖片資源放入,分別起名爲a和b。
此時咱們若是將項目啓動起來,而後在瀏覽器中分別訪問一下地址
http://localhost:8080/a.png
http://localhost:8080/b.png
複製代碼
都可以正常訪問到相應的圖片資源。所以能夠知道SpringBoot在訪問靜態資源的時候會從/static、/public、/resources或者/META-INF/resources目錄下進行尋找文件,若是找到的話便直接返回。
若是默認的靜態資源訪問路徑不符合需求的話,也能夠進行自定義靜態資源的訪問路徑配置。第一種的配置方式就是經過spring.mvc.static-path-pattern元素的配置。此時若是以下配置
##這裏表示在頁面的訪問路徑中爲/resources/**的時候纔會處理請求
spring.mvc.static-path-pattern=/resources/**
複製代碼
那麼仍是以前的靜態資源存放路徑的狀況下,瀏覽器得以下訪問才能訪問到文件。
http://localhost:8080/resources/a.png
http://localhost:8080/resources/b.png
複製代碼
若是此時是想更改靜態資源文件的存放路徑,那麼能夠經過spring.resources.static-locations元素進行配置
##默認狀況下SpringBoot會在如下的文件夾中尋找靜態文件
spring.resources.static-locations=classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources
複製代碼
因此「spring.mvc.static-path-pattern」用於闡述HTTP請求地址,而「spring.resources.static-locations」則用於描述靜態資源的存放位置。
第二種方式是經過@Configure註解而後繼承WebMvcConfigurerAdapter重寫addResourceHandlers方法。
/**
* @program: FirstSpringBoot
* @description: 配置靜態資源的映射
* @author: hu_pf@suixingpay.com
* @create: 2018-07-27 14:37
**/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/");
}
}
複製代碼
在網絡傳輸中,想要提高效率,第一個是提高網絡帶寬,第二個就是在有限的帶寬下傳輸更少的東西,而模板文件就是這樣。一般在用戶第一次訪問網站的時候,若是一些不變的內容能夠在用戶本機生成一個模板文件,而後第二次訪問或者刷新的時候只傳輸動態的內容便可。
SpringBoot支持下列的模板技術的自動配置:
若是使用SpringBoot的默認配置的話,那麼模板文件將會自動掃描放在src/main/resources/templates的文件做爲模板文件。
若是使用IDEA進行項目的開發的話,因爲IDEA掃描路徑的方式不一樣。因此若是使用IDE進行main方法的啓動和使用gradle或者maven進行jar包的啓動的話,掃描路徑也是不一樣的。這有可能形成SpringBoot在classpath中去找不到templates文件。若是有這種問題的話,可使用IDEA中的配置資源文件配置一下,或者在配置文件中配置classpath*:/templates/便可。
一般在開發過程當中,在Controller中每一個方法或許都得寫一個異常處理的代碼。例以下面這個例子:
@RequestMapping(value = "/query", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> queryCondition() {
try {
//業務代碼省略
return setResult(list, count);
} catch (Exception e) {
return setFailure("查詢失敗");
}
}
@RequestMapping(value = "/getDetail", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> getByKey() {
try {
//業務代碼省略
return map;
} catch (Exception e) {
return setFailure("查詢失敗");
}
}
複製代碼
代碼中存在着許多的try-catch 並且處理的還都是一個異常,返回的信息也是同樣的,因此這時代碼就會顯得難看並且臃腫。SpringBoot提供了全局的異常處理方法。例以下面例子
/**
* @program: FirstSpringBoot
* @description: 全局Controller層異常處理
* @author: hu_pf@suixingpay.com
* @create: 2018-07-27 16:54
**/
@ControllerAdvice
public class GlobExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public String handleException(Exception e){
return "Exception BuXueWuShu "+e.toString();
}
}
複製代碼
其中@ControllerAdvice註解是將所寫的類註冊到Spring容器中,@ControllerAdvice有個參數basePackageClasses,若是寫了的話那麼他就會處理所寫的那個類所傳出來的異常。若是不寫的話,那麼默認處理全部傳出來的異常。另外@ExceptionHandler註解裏面加上了異常的種類的話,那麼此方法就單獨的處理所寫的異常,若是沒寫的話,就默認處理全部的異常。這時候在Controller層中全部的try-catch就能夠去掉了。
在網站中,若是沒有找到某個資源的話就會返回404的錯誤,默認的404界面有點醜,不夠美觀。若是想要自定義錯誤頁面的話,那麼就在靜態資源文件夾下建立一個error文件夾,error文件夾下放想要處理狀態碼的文件,其中文件名爲狀態碼。下面爲狀態碼爲404的例子:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
複製代碼
固然你也能夠和上一節相結合,將錯誤信息返回到錯誤頁面中,而後運用模板技術將錯誤信息拼接返回給用戶。
通用的Servlet的配置能夠經過Spring的環境變量來設置,通常都是講配置寫在application.properties中的。
常見的配置以下:
ServerProperties 更加詳細的配置屬性
若是想要程序化配置內嵌的Servlet容器的話,須要在Spring中註冊實現了WebServerFactoryCustomizer接口的Bean。WebServerFactoryCustomizer提供了ConfigurableServletWebServerFactory。而ConfigurableServletWebServerFactory提供了許多的set方法進行設置屬性。例子以下:
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
複製代碼
若是上面的例子還不知足的話,那麼能夠直接在Spring容器中註冊TomcatServletWebServerFactory、JettyServletWebServerFactory或者UndertowServletWebServerFactory
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
複製代碼
SpringBoot是不推薦在項目中使用JSP的,由於JSP在SpringBoot有如下的缺點:
這有一個JSP Sample教你如何在SpringBoot配置JSP