不學無數——SpringBoot入門V

SpringBoot

1.開發一個Web程序

SpringBoot是很是適合開發Web應用的,由於他內嵌有Tomcat、Jetty、Undertow或者Netty。大部分的應用能夠經過加載spring-boot-starter-web模塊可以快速的建立並啓動一個Web應用。html

1.1SpringMVC框架

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

1.1.1 SpringMVC自動配置

SpringMVC不用再像以前同樣用許多的配置文件來開啓各類功能,SpringBoot已經將其許多的功能進行了自動配置化。下面就是SpringBoot針對SpringMVC的自動配置的一些功能:github

  • 包括ContentNegotiatingViewResolver和BeanNameViewResolver類
  • 支持靜態資源的服務,包括支持WebJars
  • 自動註冊Converter、GenericConverter和Formatter
  • 支持HttpMessageConverters
  • 自動註冊MessageCodesResolver
  • 支持靜態的index.html
  • 對於定製化Favicon的支持
  • 自動使用ConfigurableWebBindingInitializer

若是你想保持上面的功能不變,可是想要額外的添加一些功能。可以使用@Configuration註解進行配置不能加上@EnableWebMvc,若是你不想要上面的功能,想徹底本身定義SpringMVC的功能,那麼就加上@EnableWebMvc。若是想要擁有定製化的RequestMappingHandlerMapping、RequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver,聲明一個WebMvcRegistrationsAdapter實例提供相應的內容。web

1.1.2 HttpMessageConverters

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);
	}
}

複製代碼

1.1.3 定製JSON的序列化和反序列化

若是使用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> {
		// ...
	}

}

複製代碼

1.1.4 靜態資源

默認狀況下,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/");
    }
}

複製代碼

1.1.5 模板文件

在網絡傳輸中,想要提高效率,第一個是提高網絡帶寬,第二個就是在有限的帶寬下傳輸更少的東西,而模板文件就是這樣。一般在用戶第一次訪問網站的時候,若是一些不變的內容能夠在用戶本機生成一個模板文件,而後第二次訪問或者刷新的時候只傳輸動態的內容便可。

SpringBoot支持下列的模板技術的自動配置:

  • FreeMarker
  • Groovy
  • Thymeleaf
  • Mustache

若是使用SpringBoot的默認配置的話,那麼模板文件將會自動掃描放在src/main/resources/templates的文件做爲模板文件。

若是使用IDEA進行項目的開發的話,因爲IDEA掃描路徑的方式不一樣。因此若是使用IDE進行main方法的啓動和使用gradle或者maven進行jar包的啓動的話,掃描路徑也是不一樣的。這有可能形成SpringBoot在classpath中去找不到templates文件。若是有這種問題的話,可使用IDEA中的配置資源文件配置一下,或者在配置文件中配置classpath*:/templates/便可。

1.1.6 錯誤處理

一般在開發過程當中,在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就能夠去掉了。

1.1.7 自定義錯誤頁面

在網站中,若是沒有找到某個資源的話就會返回404的錯誤,默認的404界面有點醜,不夠美觀。若是想要自定義錯誤頁面的話,那麼就在靜態資源文件夾下建立一個error文件夾,error文件夾下放想要處理狀態碼的文件,其中文件名爲狀態碼。下面爲狀態碼爲404的例子:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

複製代碼

固然你也能夠和上一節相結合,將錯誤信息返回到錯誤頁面中,而後運用模板技術將錯誤信息拼接返回給用戶。

1.1.8 自定義內嵌的Servlet容器

通用的Servlet的配置能夠經過Spring的環境變量來設置,通常都是講配置寫在application.properties中的。

常見的配置以下:

  • 默認的端口是8080,若是想改變端口號能夠經過server.port改變。接口地址綁定server.address
  • session設置:session是否一直保存,server.servlet.session.persistence。session過時時間server.servlet.session.timeout。本地的session數據存放地址:server.servlet.session.store-dir。session-cookie的配置:server.servlet.session.cookie.*
  • error頁面的存放地址:server.error.path

ServerProperties 更加詳細的配置屬性

1.1.8.1 程序化配置

若是想要程序化配置內嵌的Servlet容器的話,須要在Spring中註冊實現了WebServerFactoryCustomizer接口的Bean。WebServerFactoryCustomizer提供了ConfigurableServletWebServerFactory。而ConfigurableServletWebServerFactory提供了許多的set方法進行設置屬性。例子以下:

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

	@Override
	public void customize(ConfigurableServletWebServerFactory server) {
		server.setPort(9000);
	}

}

複製代碼
1.1.8.2 直接配置ConfigurableServletWebServerFactory

若是上面的例子還不知足的話,那麼能夠直接在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;
}
複製代碼

1.1.9 JSP的侷限性

SpringBoot是不推薦在項目中使用JSP的,由於JSP在SpringBoot有如下的缺點:

  • Tomcat和Jetty若是使用war進行打包,而後用java -jar進行執行的時候均可以運行的,可是JSPs不支持。
  • Undertow不支持JSPs
  • 建立error.jsp不會覆蓋掉默認的錯誤頁面

這有一個JSP Sample教你如何在SpringBoot配置JSP

相關文章
相關標籤/搜索