1. 使用Spring Boot开发web应用程序
Spring Boot非常适合Web应用程序的开发。 您可以使用嵌入式Tomcat,Jetty或Undertow轻松创建自包含的HTTP服务器。 大多数Web应用程序将使用spring-boot-starter-web模块来快速启动和运行。
1.1 使用SpringBoot集成的Spring Web MVC框架
Spring Web MVC框架(通常简称为“Spring MVC”)是一个丰富的“模型视图控制器”Web框架。 Spring MVC允许您创建特殊的@Controller或@RestController bean来处理传入的HTTP请求。 您的控制器中的方法使用@RequestMapping注释映射到HTTP。
这里是一个典型的例子@RestController来提供JSON数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@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) { // ... } }
1.1.1 Spring MVC自动配置
Spring Boot为Spring MVC提供了自动配置,可以与大多数应用程序配合使用。自动配置在Spring的默认设置之上添加以下功能:
- 包含ContentNegotiatingViewResolver和BeanNameViewResolver bean。
- 支持静态资源,包括对WebJars的支持。
- Converter,GenericConverter,Formatter beans的自动注册。
- 支持HttpMessageConverters。
- 自动注册MessageCodesResolver。
- 静态index.html支持。
- 自定义的Favicon支持。
- 自动使用ConfigurableWebBindingInitializer。
如果你想保持Spring Boot的MVC特性,并且你还想添加额外的MVC配置(拦截器,格式化器,视图控制器等),你可以添加你自己的@Configuration类型的WebMvcConfigurerAdapter。 如果您希望提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明提供此类组件的WebMvcRegistrationsAdapter实例。
如果你想完全控制Spring MVC,你可以添加你自己的用@EnableWebMvc注解的@Configuration。
1.1.2 HttpMessageConverters
Spring MVC使用HttpMessageConverter接口来转换HTTP请求和响应。 默认包括拆箱即用的功能,例如对象可以自动转换为JSON(使用Jackson库)或XML(如果Jackson XML可以使用则使用Jackson XML扩展,否则使用JAXB)。 字符串默认使用UTF-8编码。如果您需要添加或自定义转换器,可以使用Spring Boot的HttpMessageConverters类。
1
2
3
4
5
6
7
8
9
10
11
12
13import 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 Serializers and Deserializers
JSON序列化器和反序列化器
如果您使用Jackson来序列化和反序列化JSON数据,则可能需要编写自己的JsonSerializer和JsonDeserializer类。 自定义序列化器通常通过模块向Jackson注册,但Spring Boot提供了一个替代的@JsonComponent注释,这使得更容易直接注册Spring Bean。
1
2
3
4
5
6
7
8
9
10
11
12
13
14import 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> { // ... } }
Spring Boot还提供了JsonObjectSerializer和JsonObjectDeserializer基类,在序列化对象时为标准Jackson版本提供了有用的替代方法。
假设我们有个controller可以获取当前日期。我们可以发现:如果不加任何日期序列化工具,将会返回当前日期对应的毫秒数。
1
2
3
4
5
6
7
8@RequestMapping("formatedate") @JsonSerialize public TestDate getFormatDate() { TestDate testDate = new TestDate(); testDate.setCreatedate(new Date()); return testDate; }
如果我们自定义一个日期序列化工具,实现日期的格式化输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@JsonComponent public class DateSerializer { public static class Serializer extends JsonSerializer<Date> { @Override public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException, JsonProcessingException { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); jsonGenerator.writeString(simpleDateFormat.format(date)); } } public static class Deserializer extends JsonDeserializer<Date> { @Override public Date deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException { String date = jsonParser.getText(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return simpleDateFormat.parse(date); } catch (ParseException e) { e.printStackTrace(); } return new Date(); } } }
观察输出,可以发现返回我们需要的日期格式:
同样反序列也也是一样的道理:
1
2
3@RequestMapping(value = "str2date") public void getFormatDate(@RequestBody DateVO dateVO) { System.out.println(dateVO); }
1
2
3
4@Data public class DateVO { private Date date; }
入参我们用一个字符串时间:{"date":"2018-01-01 00:00:00"}我们自定的反序列化工具可以实现将字符串转换成Date对象DateVO(date=Mon Jan 01 00:00:00 CST 2018)。
1.1.4 MessageCodesResolver
Spring MVC有一个策略,用于从绑定的errors产生用来渲染错误信息的错误码:MessageCodesResolver。如果设置spring.mvc.message-codes-resolver.format属性为PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE(具体查看DefaultMessageCodesResolver.Format枚举值),Spring Boot会为你创建一个MessageCodesResolver。
1.1.5 Static Content(http://www.webjars.org/)
默认情况下,Spring Boot将从类路径中的/ static(或/ public或/ resources或/ META-INF / resources)目录或从ServletContext的根目录中提供静态内容。 它使用Spring MVC中的ResourceHttpRequestHandler,因此可以通过添加自己的WebMvcConfigurerAdapter并重写addResourceHandlers方法来修改该行为。
默认情况下,资源被映射到/ **,但是你可以通过spring.mvc.static-path-pattern来调整。 例如,将所有资源重定位到/ resources / **可以实现如下:
1
2spring.mvc.static-path-pattern=/resources/**
除了上面的“标准”静态资源位置之外,Webjars是一个特殊情况。 如果资源以Webjars格式打包,并且在/ webjars / **目录下,将会被当成jar包使用。
如果您的应用程序将被打包为jar,请不要使用src/main/webapp目录。 虽然这个目录是一个通用的标准,但它只能用于war包,如果你要生成一个jar包,该目录会被大多数构建工具默默地忽略。
1.1.6 Custom Favicon
Spring Boot会在配置的静态内容位置和类路径的根目录(按此顺序)中查找favicon.ico。 如果这样的文件存在,它会自动用作应用程序的图标。
1.1.7 ConfigurableWebBindingInitializer
Spring MVC使用WebBindingInitializer为特定请求初始化WebDataBinder。 如果您创建自己的ConfigurableWebBindingInitializer @Bean,Spring Boot将自动配置Spring MVC以使用它。
1.1.8 Template engines
除了REST Web服务,您还可以使用Spring MVC为动态HTML内容提供服务。 Spring MVC支持各种模板技术,包括Thymeleaf,FreeMarker和JSP。 许多其他模板引擎也提供了自己的Spring MVC集成。
Spring Boot包含以下模板引擎的自动配置支持:
- FreeMarker
- Groovy
- Thymeleaf
- Mustache
当您使用默认配置的模板引擎之一时,您的模板将自动从src / main / resources / templates中选取。
IntelliJ IDEA根据你不同的运行应用程序的方式排列类路径。 通过主要方法在IDE中运行应用程序将导致与使用Maven或Gradle或从其打包的jar运行应用程序时不同的顺序。 这可能会导致Spring Boot无法在类路径中找到模板。 如果您受到这个问题的影响,您可以在IDE中重新排序类路径,以便首先放置模块的类和资源。 或者,您可以配置模板前缀以搜索类路径中的每个模板目录:classpath *:/ templates /。
举个栗子:
我现在想返回freemaker模本,需要做的准备工作如下:
- 修改application.properties
1
2
3
4
5
6
7
8
9
10
11## Freemarker 配置 ## 文件配置路径 spring.freemarker.template-loader-path=classpath:/templates/ spring.freemarker.cache=false spring.freemarker.charset=UTF-8 spring.freemarker.check-template-location=true spring.freemarker.content-type=text/html spring.freemarker.expose-request-attributes=true spring.freemarker.expose-session-attributes=true spring.freemarker.request-context-attribute=request spring.freemarker.suffix=.ftl
- 新建controller返回视图名称
1
2
3
4
5@RequestMapping("/welcome/{name}") public ModelAndView demo(@PathVariable String name) { Map<String, Object> objectMap = new HashMap<>(1); objectMap.put("name", name); return new ModelAndView("welcome"); }
- 新增/templates/welcome.ftl这个freemaker模版
1
2
3
4
5
6
7
8
9
10
11<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> ${name} 您好,欢迎您 <br/> </body> </html>
执行以下http://localhost:8080/users/welcome/张三,发现返回如下页面:
更多关于freemaker的配置可以参考如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# FREEMARKER (FreeMarkerAutoConfiguration) spring.freemarker.allow-request-override=false # Set whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name. spring.freemarker.allow-session-override=false # Set whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name. spring.freemarker.cache=false # Enable template caching. spring.freemarker.charset=UTF-8 # Template encoding. spring.freemarker.check-template-location=true # Check that the templates location exists. spring.freemarker.content-type=text/html # Content-Type value. spring.freemarker.enabled=true # Enable MVC view resolution for this technology. spring.freemarker.expose-request-attributes=false # Set whether all request attributes should be added to the model prior to merging with the template. spring.freemarker.expose-session-attributes=false # Set whether all HttpSession attributes should be added to the model prior to merging with the template. spring.freemarker.expose-spring-macro-helpers=true # Set whether to expose a RequestContext for use by Spring's macro library, under the name "springMacroRequestContext". spring.freemarker.prefer-file-system-access=true # Prefer file system access for template loading. File system access enables hot detection of template changes. spring.freemarker.prefix= # Prefix that gets prepended to view names when building a URL. spring.freemarker.request-context-attribute= # Name of the RequestContext attribute for all views. spring.freemarker.settings.*= # Well-known FreeMarker keys which will be passed to FreeMarker's Configuration. spring.freemarker.suffix=.ftl # Suffix that gets appended to view names when building a URL. spring.freemarker.template-loader-path=classpath:/templates/ # Comma-separated list of template paths. spring.freemarker.view-names= # White list of view names that can be resolved.
1.1.9 Error Handling
Spring Boot默认提供了一个/error映射,以合理的方式处理所有的错误,并在servlet容器中被注册为一个“全局”错误页面。 对于机器客户端,它将产生一个JSON响应,包含错误的详细信息,HTTP状态和异常消息。 对于浏览器客户端,有一个'whitelabel'错误视图,它以HTML格式呈现相同的数据(自定义它只是添加一个解决'错误'的视图)。 要完全替换默认行为,可以实现ErrorController并注册该类型的bean定义,或者简单地添加一个ErrorAttributes类型的bean来使用现有的机制,但是替换内容。
BasicErrorController可以用作自定义ErrorController的基类。 如果您想为新的内容类型添加处理程序(默认情况下专门处理text / html并提供其他所有内容的回退),这一点尤其有用。 要做到这一点,只需扩展BasicErrorController并添加一个带有@RequestMapping属性的公共方法,并创建一个新类型的bean。
您还可以定义@ControllerAdvice来定制JSON文档以返回特定的控制器和/或异常类型.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@ControllerAdvice(basePackageClasses = FooController.class) public class FooControllerAdvice 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); } }
在上面的例子中,如果由与FooController相同的包中定义的控制器抛出YourException,则将使用CustomErrorType POJO的json表示而不是ErrorAttributes表示形式。
举个栗子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14@ControllerAdvice(basePackageClasses = MyRestController.class) public class CommonControllerAdvice extends ResponseEntityExceptionHandler { @ExceptionHandler(Exception.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); } } @RequestMapping("exception") public void exceptionDemo() { throw new RuntimeException("An uncaught Exception happened"); }
可以看到控制台输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56java.lang.RuntimeException: An uncaught Exception happened at com.example.springboot.controller.MyRestController.exceptionDemo(MyRestController.java:55) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.27.jar:8.5.27] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.27.jar:8.5.27] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_161] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_161] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.27.jar:8.5.27] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]
1.1.10 Custom error pages
如果要为给定的状态代码显示自定义的HTML错误页面,请将文件添加到/ error文件夹。 错误页面可以是静态HTML(即添加在任何静态资源文件夹下),也可以使用模板构建。 该文件的名称应该是确切的状态码或一系列掩码。
例如,要将404映射到静态HTML文件,您的文件夹结构如下所示:
1
2
3
4
5
6
7
8
9
10
11src/ +- main/ +- java/ | + <source code> +- resources/ +- public/ +- error/ | +- 404.html +- <other public assets>
要使用FreeMarker模板来映射所有的5xx错误,你会有这样的结构:
1
2
3
4
5
6
7
8
9
10
11src/ +- main/ +- java/ | + <source code> +- resources/ +- templates/ +- error/ | +- 5xx.ftl +- <other templates>
对于更复杂的映射,您还可以添加实现ErrorViewResolver接口的bean。
1
2
3
4
5
6
7
8public 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功能,如@ExceptionHandler方法和@ControllerAdvice。 ErrorController将会接收任何未处理的异常。
git demo地址:https://github.com/PerseveranceForever/springmcv_demo.git
1https://github.com/PerseveranceForever/springmcv_demo.git
最后
以上就是动听黑裤最近收集整理的关于Spring Boot官方文档学习——使用Spring Boot开发web应用程序1. 使用Spring Boot开发web应用程序的全部内容,更多相关Spring内容请搜索靠谱客的其他文章。
发表评论 取消回复