spring boot 2.0之web应用开发

简介

spring boot 非常适合进行web程序开发。可以通过使用 spring-boot-starter-web快速创建一个内嵌tomcat或 Jetty,或netty的应用。也可以通过使用 spring-boot-starter-webflux 创建交互式的应用。

Spring Web MVC框架

springMVC框架是一个基于“model,view, controller"的web框架,spring MVC让你可以@c ontroller  或者  @RestController beans 去处理http的请求。在你的control的方法中将会使用 @RequestMapping   映注解映射成URL。
以下是 @RestController   列子处理json数据:代码如下:
@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 getUserCustomers(@PathVariable Long user) {
		// ...
	}

	@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
	public User deleteUser(@PathVariable Long user) {
		// ...
	}

}

01. spring mvc的自动配置
 为大多数的应用都配置了 spring mvc 自动配置  。其自动配置默认在spring的基础上增加了如下特性:
  •  包含了ContentNegotiatingViewResolver(根据请求头输出不同的形式:例如xml,json)BeanNameViewResolver(返回的逻辑视图名称去匹配定义好的视图bean对象)
  •  支持服务静态资源(包括WebJars 
  • 自动注册ConverterGenericConverter, 与 Formatter  beans
  • 支持 HttpMessageConverters 
  • 自动注册 MessageCodesResolver 
  • 静态index.html支持
  • 自定义 Favicon支持
  • 自动使用ConfigurableWebBindingInitializer
如果想保持 Spring Boot MVC特性,你想要添加附加的 MVC 配置( interceptors, formatters, view controllers, 与其他配置)。你可以不使用 @EnableWebMvc,而是添加其 @Configuration 配置类 其。如果你希望提供自定义的 RequestMappingHandlerMapping RequestMappingHandlerAdapter , or  ExceptionHandlerExceptionResolver的 实例。可以使用 WebMvcRegistrationsAdapter提供组件。
如果想完全控制MVC,通过使用 @Configuration与   @EnableWebMvc  。

02. httpMessageConverters
Spring MVC 使用 httpMessageConverters来转换http请求与响应。合理的默认值应该包含哪些不确定的情况,例如:对象可能会自动的被转换为JSON或者XML。默认情况下使用UTF-8.
如果要添加或者自定义的转换器,可以使用 Spring Boot的   HttpMessageConverters类  其代码如下:
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);
	}

}

03. 自定义json serializer与json de serializer
 如果使用 Jackson去串行化一个数据或对象话一个json 数据,可能需要些自己的json对象转换器。自定义的json转换器通过一个module的形式注册到 JsonComponent  ,其提供了  @JsonComponent  使其能够快速注册到json上去。你可以使用 @JsonComponent  直接进行 JsonSerializer  or  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 {
		// ...
	}

	public static class Deserializer extends JsonDeserializer {
		// ...
	}

}
使用   @JsonComponent  会自动注册到jackson,因为 @JsonComponent  的元数据使用 @Component, 数, component-scanning能够被应用。

04. messageCodeResolver
spring mvc 提供了   MessageCodesResolver 来根据产生的错误码来提示对应的错误信息。如果你设置了 spring.mvc.message-codes-resolver.format属性  PREFIX_ERROR_CODE  或者是 POSTFIX_ERROR_CODE

05.静态内容
默认情况下,spring boot 将根据经下的 /static  (  /public  ,  /resources  ,  /META-INF/resources )作为静态资源路径,它使用来自于 from Spring WebFlux的 ResourceWebHandler以便能修改其行为。
默认情况下,资源被映射成   /** ,,但是可以通过设置 spring.webflux.static-path-pattern  进行调整,例如将资源重定位到   /resources/**  下,可以使用如下配置
spring.webflux.static-path-pattern=/resources/**
通过使用  spring.resources.static-locations  可以自定义资源路径位置。也可以通过使用webjar的方式如果其打包为jar。
Spring Boot 也支持spring mvc支持的资源特性。允许使用 cache-busting静态资源或者是对于 Webjars 使用未知版本资源。对于使用未知版本的webjar资源,需要添加 webjars-locator  依赖。比如:使用jquery为例:使用 "/webjars/jquery/dist/jquery.min.js"  的结果为   "/webjars/jquery/x.y.z/dist/jquery.min.js" .。如果使用jboss的话还需要依赖   webjars-locator-jboss-vfs  ,否则会报404错误。
使用缓存清楚(cache busting),接下来的配置配置了对所有静态资源缓存清楚。高效的添加hash值内容。例如,在URL中的内容: ,、其主要配置为:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
当动态加载资源的时候,js模块加载,文件命名是不打开的,那就是为什么其他策略被支持并且能够被组合。一种修订的策略是在URL中   "fixed"中修定一个静态版本,不用更改其名字。如下配置:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
在这种配置下,js版本使用   "/js/lib/"  使用上述配置之后为  ( "/v12/js/lib/mymodule.js" ),其他的资源内容也是如下  ( ).

06. 开始页
Spring Boot支持静态的和模板的开始页。其首先在配置静态内容中寻找index.html.如果没有发现,则查找使用静态模板。

07. 自定义收藏夹图标
Spring Boot 寻找 收藏夹图标在静态位置或者是classpath的根路径。

08. 配置web绑定初始化
Spring MVC使用 WebBindingInitializer  去初始化 WebDataBinder 初和特殊的请求。如果你创建 ConfigurableWebBindingInitializer @bean, Spring Boot自动配置   Spring MVC  去配置它。

09. 模板引擎
REST 的web service一样,你可以使用   Spring MVC  动态填充内容。spring mvc支持不同的模板技术: Thymeleaf, FreeMarker, 与JSPs。包括其spring mvc自身的操作。
包括自动配置的支持的模板引擎如下:
  • FreeMarker
  • Groovy
  • Thymeleaf
  • Mustache
如果使用默认的模板位置的话:其配置路径如下:   src/main/resources/templates 

10. 错误处理
默认情况下,   Spring Boot以一种合理的方式提供了 /error  mapping的映射处理。其在 servlet container中作为一种全局的错误页,对于机器的客户端,其产生一个json格式的错误信息(包括http状态,以及异常信息)。对于浏览器客户端,有一种叫做“ whitelabel ”的错误,以html的格式渲染。完全替换默认的行为,可以实现一个 ErrorController  注册一个bean的类型并且添加一个   ErrorAttributes  的bean通过替换成内容去实现已存在的机制。
可以通过使用注解   @ControllerAdvice 去自定义一个json文档返回一个特别的控制或者是异常类型。如下例子:

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

}
10.1 自定义错误页
如果想要对给定的错误状态展示一个自定义的错误页。可以添加一个   /error  的文件夹。错误页面可以是一个静态的HTML或者是一个使用模板构建的。文件的名字必须要有准备的状态码或者是一系列的掩码。
例如:如果要映射成404到一个静态页面,文件结构应该如下:

src/
 +- main/
     +- java/
     |   + 
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- 
通过使用模板映射到5xx的错误,你的文件夹的结构应该如下:
src/
 +- main/
     +- java/
     |   + 
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftl
             +- 
对于一些比较复杂的映射,可以通过实现接口   ErrorViewResolver  来完成,如下列子
public class MyErrorViewResolver implements ErrorViewResolver {

	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request,
			HttpStatus status, Map model) {
		// Use the request or status to optionally return a ModelAndView
		return ...
	}

}
10.2 非spring mvc映射错误文件
对于没有使用spring mvc的应用,可以通过实现接口   ErrorPageRegistrar  指向错误页面,如下代码所示:
@Bean
public ErrorPageRegistrar errorPageRegistrar(){
	return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

	@Override
	public void registerErrorPages(ErrorPageRegistry registry) {
		registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
	}

}
如果注册的错误文件的路径在一个过滤器里面,其 Filter  要指定错误的分发:如下代码
@Bean
public FilterRegistrationBean myFilter() {
	FilterRegistrationBean registration = new FilterRegistrationBean();
	registration.setFilter(new MyFilter());
	...
	registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
	return registration;
}
10.3在websphere上处理错误
默认情况下, WebSphere 8.0以后的版本通过 servlet的服务方法能够完全完成,需要将其   com.ibm.ws.webcontainer.invokeFlushAfterService 设置为false。

11. spring hateoas
如果使用超文本开发api,spring boot 为 Spring HATEOAS 提供了自动配置来很好的为应用程序服务。其自动配置使用   @EnableHypermediaSupport 替换了  需求,和注册了一系列的bean使超文本易于构建。包括 LinkDiscoverers  与 ObjectMapper  的配置去编排成想要的结果信息。其   ObjectMapper  通过设置 spring.jackson.*  来进行个性化。
可以通过使用   @EnableHypermediaSupport 来配置 HATEOAS’s配置。这种方式可以让   ObjectMapper  较早的使用。

12.cors 支持( 跨域访问的支持
Cross-origin resource sharing  (CORS)是被大多数的浏览器通过w3c的方式,允许你指定一种灵活的方式对于跨越资源的请求的授权。代替使用更弱的方式实现(例如   IFRAME or JSONP
从spring 4.2开始,spring mvc 支持了跨越访问。通过使用   @CrossOrigin  配置,不需要使用其他的任何的特殊的配置。可以通过自定义的 addCorsMappings(CorsRegistry)   注册方法注册   WebMvcConfigurer  bean,如下代码:
@Configuration
public class MyConfiguration {

	@Bean
	public WebMvcConfigurer corsConfigurer() {
		return new WebMvcConfigurer() {
			@Override
			public void addCorsMappings(CorsRegistry registry) {
				registry.addMapping("/api/**");
			}
		};
	}
}

Spring WebFlux框架

spring webflux是在spring 5.0中引入的响应式的web编程框架。不像spring mvc,其不需要servlet api。其是完全异步并且是非阻塞的。通过交互式流实现交互式流的标准。
spring webflux带来的两大特点:功能性以及其基于注解。基于注解这块与spring mvc比较的类似,如下代码:
@RestController
@RequestMapping("/users")
public class MyRestController {

	@GetMapping("/{user}")
	public Mono getUser(@PathVariable Long user) {
		// ...
	}

	@GetMapping("/{user}/customers")
	Flux getUserCustomers(@PathVariable Long user) {
		// ...
	}

	@DeleteMapping("/{user}")
	public Mono deleteUser(@PathVariable Long user) {
		// ...
	}

}
其功能性的变量“ WebFlux.fn”:将实际处理请求与路由配置进行分离。如下代码:
@Configuration
public class RoutingConfiguration {

	@Bean
	public RouterFunction monoRouterFunction(UserHandler userHandler) {
		return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
				.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
				.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
	}

}

@Component
public class UserHandler {

	public Mono getUser(ServerRequest request) {
		// ...
	}

	public Mono getUserCustomers(ServerRequest request) {
		// ...
	}

	public Mono deleteUser(ServerRequest request) {
		// ...
	}
}
通用使用 spring-boot-starter-webflux  配置,可以添加webflux(注意:通过添加 spring-boot-starter-web  与  spring-boot-starter-webflux 将会导致webflux不会生效)。

01. 自动配置
自动配置除了支持spring的基本特性外,还添加了如下特性:
  • 配置HttpMessageReader 与 HttpMessageWriter 与实例
  • 支持静态资源(包括webjar)
如果想完全控制 spring  WebFlux,可以通过使用   @EnableWebFlux 配置。

02. http解码器httpmessageheader与httpmessagewriter
Spring WebFlux使用 HttpMessageReader  与 HttpMessageWriter  转换器请求。他们通过用 CodecConfigurer 在类路径中配置。spring boot 通过使用   CodecCustomizer 实例。例如: spring.jackson.*,配置主键被应用于 Jackson  中。如果想自定义转码为其,可以通过创建   CodecCustomizer  来处理:
import org.springframework.boot.web.codec.CodecCustomizer;

@Configuration
public class MyConfiguration {

	@Bean
	public CodecCustomizer myCodecCustomizer() {
		return codecConfigurer -> {
			// ...
		}
	}

}

03. 静态内容
通过指定静态路径配置对应的路径信息: spring.webflux.static-path-pattern =/resources/**

04. 模板引擎

05. 错误处理
    

06. 自定义错误页面
  与spring mvc类似

JAX-RS与JERSEY

如果你更喜欢  JAX-RS的restful endpoint编程模型,你可以使用它代替spring mvc。如果你在你的应用程序中注册他们的servlet或者是filter作为一个bean, Jersey 1.x 与 Apache CXF  会工作的更好。 Jersey 2.x提供了对spring的支持,因此我们可以将其封装成一个starter。
在使用   Jersey 2.x的时候,需要依赖 spring-boot-starter-jersey  。你需要一个   ResourceConfig 的类型的bean注册到所有的端点。如下代码:
@Component
public class JerseyConfig extends ResourceConfig {

	public JerseyConfig() {
		register(Endpoint.class);
	}

}
你可以注册任意多的bean去实现多个高级化的配置。所有的注册的endpoints必须使用   @Components ,如下代码所示:
@Component
@Path("/hello")
public class Endpoint {

	@GET
	public String message() {
		return "Hello";
	}

}
因为   Endpoint  是一个 spring   Endpoint  ,其生命周期是被spring进行管理。可以使用自动注解 @Autowired 以及 @Value  去注入外部配置。默认   Jersey servlet被注册并且被mapping成为“/*”.可以在   ResourceConfig 中通过添加 @ApplicationPath  改变其mapping。
默认情况下: Jersey  安装成一个 ServletRegistrationBean  的名字为 jerseyServletRegistration的 bean。默认,其servlet是lazily。你可以通过配置   spring.jersey.servlet.load-on-startup 改变其行为。你可以停用或者是通过定义相同的名字覆盖其配置。也可以通过设置   spring.jersey.type=filter  使用filter进行替换。

内嵌容器的支持

默认的内嵌容器:tomcat,默认的端口为8080.

01. servlets,filters,listener.
当使用内嵌容器的时候,也可以通过servlet标准定义servlets,filter与listener

02. 容器初始化
内嵌的容器不是执行servlet 3.0+, javax.servlet.ServletContainerInitializer  或者是 org.springframework.web.WebApplicationInitializer  接口。这减少地方包在运行一个war包范围内的情况下,会损坏spring boot。
如果执行容器初始化,需要注册一个实现 org.springframework.boot.web.servlet.ServletContextInitializer  的bean。其启动方法提供了   ServletContext  的链接以及如果必要,能够被很容易实现已经存在的 WebApplicationInitializer的实现。

扫描servlets,filters,listerners:
可以通过   @WebServlet @WebFilter , 与 @WebListener自动完成扫描

03. 自定义内嵌的容器
通用的servlet容器配置可以通过spring的环境变量配置。通常,你可以在application.properties中进行设置。
通用的设置包括:
  • 网络设置(包括:server.port与server.address)
  • session设置(server.session.persistence,server.session.timeout以及server.session.store-dir与)
  • 错误管理(server.error.path:错误信息地址)
  • SSL
  • HTTP compression
程序自定义
可以通过实现 WebServerFactoryCustomizer接口,其通过了对 ConfigurableServletWebServerFactory 的链接。包括自定义的配置:其代码如下:
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements WebServerFactoryCustomizer {

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

}
自定义话configuration目录,其代码如下:
@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;
}

04. JSP限制
当使用内嵌容器的时候,这儿有一些JSP支持方面的限制:
  • tomcat 如果使用war包的话,它也应该能够工作。既一个war包可以部署到单独的容器中。一个单独的executable jar将不会工作。
  • Jetty 使用war包也能够工作
  • Undertow 不支持jsp
  • 自定义的错误页面不应该覆盖默认的错误页面

以上内容参考 https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-error-handling

你可能感兴趣的:(spring boot 2.0之web应用开发)