版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章SpringBoot的Web开发第4章SpringBoot的Web开发4.1SpringBoot对Web开发的支持4.2
自定义消息转换器HttpMessageConverter4.3SpringBoot序列化和反序列化JSON数据4.4SpringBoot对静态资源的访问4.5Thymeleaf模板引擎4.6
错误处理4.7CORS支持4.8
文件上传和下载4.9
嵌入式Servlet容器支持4.10
对JSP的支持
4.24.1SpringBoot对Web开发的支持SpringBoot对Web功能的支持,从开发、测试、部署、运维(安全)等都提供了相应的starter支持。SpringBoot使用spring-boot-starter-web为Web开发提供支持,spring-boot-starter-web又依赖于spring-web和spring-webmvc,其中spring-webmvc就代表了SpringMVC框架。
使用Spring进行Web开发时,只需要在项目中引入对应Web开发框架的依赖启动器即可,一旦引入了Web依赖启动器spring-boot-starter-web,那么SpringBoot整合SpringMVC框架默认实现的一些自动配置类就会自动生效,几乎可在无任何额外配置的情况下进行Web开发。34.1SpringBoot对Web开发的支持SpringBoot为SpringMVC提供的auto-configuration适用于大多数应用,并在Spring默认功能上添加了以下特性:(1)内置了两个视图解析器:ContentNegotiatingViewResolver和BeanNameViewResolver。(2)对服务器静态资源提供支持,包括对WebJars的支持。(3)自动注册了Converter、GenericConverter转换器和Formatter格式化器。(4)支持使用HttpMessageConverters来注册HttpMessageConverter。(5)自动注册消息代码解析器MessageCodeResolver。(6)支持静态的index.html首页。(7)支持定制应用图标favicon.ico。(8)自动初始化Web数据绑定器ConfigurableWebBindingInitializer。大多数时候使用默认配置即可满足开发需求。44.2自定义消息转换器HttpMessageConverterSpringMVC使用HttpMessageConverter接口来转换HTTP请求和响应。例如,可以将对象自动转换为JSON(通过使用Jackson库)或XML(通过使用JacksonXML扩展,或者通过使用JAXB,如果JacksonXML扩展不可用)。1.常见JSON技术
在JSON的使用中,几种常见的JSON技术,介绍如下:(1)Jackson(2)Gson(3)FastJson54.2自定义消息转换器HttpMessageConverter2.默认实现返回JSON数据SpringMVC中使用消息转换器HttpMessageConverter对JSON转换提供了很好的支持,在SpringBoot中更进一步,对相关配置做了进一步的简化。下面我们通过默认实现返回JSON数据来讲解。(1)使用SpringInitializr方式创建一个名为chapter04的SpringBoot项目,在Dependencies依赖下选择Web节点下的SpringWeb,在pom.xml中的Web依赖代码如下:
该依赖中默认加入了jackson-databind作为JSON处理器。6<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
……<dependencies>4.2自定义消息转换器HttpMessageConverter(2)在chapter04项目的com.yzpc包下新建一个entity包,并在该包下新建Person的实体类,代码如下:7packagecom.yzpc.entity;importcom.fasterxml.jackson.annotation.JsonFormat;importjava.util.Date;publicclassPerson{privateStringname;privateStringsex;privateintage;@JsonFormat(pattern="yyyy-MM-dd")privateDatevisitDate;//省略getter、setter方法}4.2自定义消息转换器HttpMessageConverter(3)在com.yzpc包下新建一个controller包,并在该包下新建PersonController类,定义show()方法返回Person对象,代码如下:8packagecom.yzpc.controller;importcom.yzpc.entity.Person;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.Date;@RestControllerpublicclassPersonController{@GetMapping("/show")publicPersonshow(){
Personperson=newPerson();
person.setName("张三");
person.setSex("男");
person.setAge(22);
person.setVisitDate(newDate());
returnperson;}}4.2自定义消息转换器HttpMessageConverter(4)启动项目,在浏览器中输入http://localhost:8080/show,即可看到返回了JSON数据,如图4-1所示。
通过Spring中默认提供的MappingJackson2HttpMessageConverter来实现的,如果需要添加或自定义转换器,可以使用SpringBoot的HttpMessageConverters,代码如下:9importorg.springframework.boot.autoconfigure.http.HttpMessageConverters;importorg.springframework.context.annotation.*;importorg.springframework.http.converter.*;@Configuration(proxyBeanMethods=false)publicclassMyConfiguration{
@Bean
publicHttpMessageConverterscustomConverters(){HttpMessageConverter<?>additional=...HttpMessageConverter<?>another=...
returnnewHttpMessageConverters(additional,another);}}4.2自定义消息转换器HttpMessageConverter3.使用Gson转换器
常见的JSON处理器除了jackson-databind之外,还有Gson作为JSON解析库,这里使用Gson来自定义转换器实现JSON输出。(1)在chapter04项目下,使用Gson时,需要在pom.xml中去除spring-boot-starter-web下的默认jackson-databind依赖,然后加入Gson依赖,这里使用的Gson版本为2.8.7,依赖代码如下:10<dependencies><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
</dependencies>4.2自定义消息转换器HttpMessageConverter(2)在com.yzpc包下新建一个converter包,并在该包下新建GsonConfig类,代码如下:11@Configuration
publicclassGsonConfig{
@Bean
publicGsonHttpMessageConvertergsonHttpMessageConverter(){//自己提供一个GsonGsonHttpMessageConverter的实例
GsonHttpMessageConverterconverter=newGsonHttpMessageConverter();
GsonBuilderbuilder=newGsonBuilder();
//设置Gson解析时日期的格式
builder.setDateFormat("yyyy-MM-dd");
//设置Gson解析时修饰符为protected的字段被过滤
builder.excludeFieldsWithModifiers(Modifier.PROTECTED);
//创建Gson对象放入GsonHttpMessageConverter的实例并返回converter
Gsongson=builder.create();
converter.setGson(gson);
returnconverter;
}
}4.2自定义消息转换器HttpMessageConverter(3)修改Person类的中的age字段的修饰符改为protected,代码如下:
(4)重新启动项目,在浏览器中访问http://localhost:8080/show,运行效果如图4-2所示。12publicclassPerson{
privateStringname;
privateStringsex;
protectedintage;
privateDatevisitDate;
//省略getter、setter方法
}4.3SpringBoot序列化和反序列化JSON数据
现在Java开发大都是前后端分离,通过传递JSON进行信息传递。不可避免会遇到对象的序列化和反序列化。JSON的序列化是指将Java中的对象转换成JSON字符串,反过来,将JSON字符串转换为Java中的对象,就是JSON的反序列化。下面通过示例来演示JSON数据的序列化和反序列化,步骤如下:(1)在chapter04项目中,打开Chapter04ApplicationTests项目测试类,添加toJson()方法实现序列化,代码如下:13@SpringBootTestclassChapter04ApplicationTests{
……@Test
publicvoidtoJson(){
Mapmap=newHashMap();
map.put("id","1001");
map.put("name","zhangsan");
Gsongson=newGson();
//将Java对象转为json字符串,称为"json序列化"
Stringjson=gson.toJson(map);
System.out.println(json);
}}4.3SpringBoot序列化和反序列化JSON数据(2)运行测试方法toJson(),在控制台输出相应的Json格式的字符串,如图4-3所示。(3)在项目测试类中,添加fromJson()方法实现Json数据的反序列化,代码如下:(4)运行测试方法fromJson(),控制台输出如图4-4所示。14@TestpublicvoidfromJson(){
Stringjson="{\"name\":\"zhangsan\",\"id\":\"1001\"}";
Gson
gson=newGson();//newTypeToken<要转换的对象类型>(){}.getType()
Mapmap=gson.fromJson
(json,new
TypeToken<Map>(){}.getType());
System.out.println(map);}
4.4SpringBoot对静态资源的访问在SpringMVC中,对于静态资源都需要开发者手动配置静态资源过滤。SpringBoot中对此也提供了自动化配置,可以简化静态资源过滤配置。4.4.1默认规则默认情况下,SpringBoot将通过类加载路径下的/static目录(或/public或/resources或/META-INF/resources)或当前应用的根路径来提供静态资源。
对应大部分开发者而言,只要将JS脚本、CSS样式文件、图片等静态统一放在加载路径下的/static或/public目录中即可。154.4.1默认规则它使用SpringMVC中的ResourceHttpRequestHandler,以便您可以通过添加自己的WebMvcConfigurer并重写addResourceHandlers方法来修改该行为。SpringBoot中对于SpringMVC的自动化配置都在WebMvcAutoConfiguration类中,因此对于默认静态资源过滤策略可以从这个类获悉。在该类中有一个WebMvcAutoConfigurationAdapter,实现WebMvcConfigurer接口,WebMvcConfigurer接口中有一个添加资源处理的方法addResourceHandlers,是用来配置静态资源过滤的,该方法在WebMvcAutoConfigurationAdapter类中得到了实现。
下面来通过源码的实现来查看一下。164.4.1默认规则
SpringBoot默认会过滤所有的静态资源,所以/**访问当前项目下的任何资源,都去以下五个路径下寻找资源,也就是说可将静态资源放到这5个位置中的任意一个。(1) classpath:/META-INF/resources/(2) classpath:/resources/(3) classpath:/static/(4) classpath:/public/(5) /:当前项目的根路径上面静态资源加载路径的优先级为:/META-INF/resources>/resources>/static>/public。一般情况下,SpringBoot项目不需要Webapp(WebContent)目录,故“/”暂不考虑。174.4.1默认规则在chapter04的项目中,在resources目录下分别创建如上4个目录,4个目录中分别放入同名的静态资源index.html,各目录下的index.html静态网页的内容不同,如图4-5所示。
重新启动项目,在地址栏输入http://localhost:8080/index.html,可看到META-INF/resources/目录下的index.html;
如果将/META-INF/resources目录下的index.html删除,重启1项目,就会访问/resources目录下的index.html,以此类推,如图4-5所示。
如果使用IntelliJIDEA创建SpringBoot项目,就会默认创建出static目录,静态资源一般放在这个目录下即可。184.4.1默认规则在前面chapter04项目的PersonController类中,添加方法hello(),代码如下:
重新启动该项目,在地址栏输入http://localhost:8080/index.html,效果如图4-6所示。从这个结果可以看出,静态映射/**请求进来,先去找Controller看能不能处理,不能处理的所有请求,交给静态资源处理器。静态资源处理器就去找以上的几个目录,如果静态资源能找到则访问,否则就会访问失败。19@GetMapping("/index.html")publicStringhello(){
return"HELLO!";
}4.4.1默认规则如果jar文件以webjars格式打包,则从访问jar文件提供路径为/webjars/**的任何资源。
SpringBoot需要使用webjars,我们可以去搜索一下,如果要使用jQuery,我们只要引入jQuery对应版本的pom依赖即可,如图4-7所示。打开网站可以看到下面有很多前端js组件的maven引入,这里引入jquery3.6.0版本的依赖,代码如下所示:
在chapter04项目中,将这段依赖添加进pom.xml文件,在maven的jar包里面看到该jquery引入。重启项目,在浏览器访问http://localhost:8080/webjars/jquery/3.6.0/jquery.js,就可访问jquery.js文件,如图4-8所示。20<!--webjar引入jquery--><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.6.0</version></dependency>4.4.2自定义规则如果默认的静态资源访问规则不能满足开发需求,也可以自定义规则。例如,可以添加静态资源访问的前缀,自定义静态资源过滤规则有以下两种方法。1.在配置文件中定义默认情况下,资源映射在/**上,可以使用spring.mvc.static-path-pattern属性对其进行调整,在chapter04项目的perties文件中直接定义过滤规则和静态资源位置,代码如下:
重新启动项目,访问http://localhost:8080/hello/index.html,即看到static目录下index.html静态网页文件,如图4-9所示。
21spring.mvc.static-path-pattern=/hello/**spring.web.resources.static-locations=classpath:/static/4.4.2自定义规则
2.Java编码定义除在配置文件中定义外,也可通过Java编码方式来定义,只需要实现WebMvcConfigurer接口即可,然后实现该接口的addResourceHandlers。在chapter04项目的com.yzpc包下,新建一个config包,在该包中新建MyWebMvcConfig类,代码如下所示:重新启动项目,访问http://localhost:8080/hello/index.html,即可看到public目录下的index.html静态网页文件,如图4-10所示。22@Configuration
publicclassMyWebMvcConfigimplementsWebMvcConfigurer{
@Override
publicvoidaddResourceHandlers
(ResourceHandlerRegistryregistry){
registry.addResourceHandler("/hello/**").addResourceLocations("classpath:/public/");}
}4.5Thymeleaf模板引擎4.5.1Thymeleaf简介Thymeleaf是SpringBoot推荐的模板引擎,SpringBoot为之提供了完美的支持,它是一种现代的基于服务器端的Java模板引擎技术,也是一种优秀的面向Java的XML、XHTML、HTML5页面模板。Thymeleaf标准方言中的大多数处理器都是属性处理器,这种页面模板即使在未处理之前,浏览器也可以正确地显示HTML模板文件,因为浏览器会简单地忽略其不认识的属性。
下面包含JSP脚本的HTML片段代码,它不能在模板被解析之前通过浏览器直接显示。23<inputtype="text"name="userName"value="${}"/>4.5.1Thymeleaf简介
下面是一段含有Thymeleaf语句的HTML代码。
在模板被解析之前,浏览器不识别th:value属性,那么该属性就会被直接忽略,这样浏览器照样可以正确显示这些信息,并可打开一个默认值(例如“用户名”)。当该模板被解析之后,th:value属性指定的表达式解析得到的值又会取代原来的value属性值,解析之后th:value属性就消失了,该属性对于浏览器就不存在了。Thymeleaf解决了前端开发人员要和后端开发人员配置一样环境的尴尬和低效。它通过属性进行模板渲染,不需要引入不能被浏览器识别的新的标签。24<inputtype="text"name="userName"value="用户名"th:value="${}"/>4.5.2引入Thymeleaf在SpringBoot项目中使用Thymeleaf模板,首先需要在项目中引入Thymeleaf依赖,直接在pom.xml文件中添加Thymeleaf依赖即可,依赖代码如下:还需要在HTML文件中加入“<htmllang=”en“xmlns:th=”“>”命名空间,这样就能完成Thymeleaf标签的渲染。25<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>4.5.2引入ThymeleafSpringBoot默认的页面映射路径(即模板文件存放位置)为“classpath:/templates/*.html”,静态文件路径为“classpath:/static/”,其中可以存放CSS、JS等模板共用的静态文件。
在全局配置文件perties文件中,可以配置Thymeleaf模板解析器属性,一般Web项目都会使用下列配置,示例代码如下所示。26spring.thymeleaf.cache=false#关闭模板缓存spring.thymeleaf.encoding=UTF-8#模板的编码格式spring.thymeleaf.mode=HTML5#模板的模板模式spring.thymeleaf.servlet.content-type=text/html#指定文档类型spring.thymeleaf.prefix=classpath:/templates/#指定模板页面存放路径spring.thymeleaf.suffix=.html#指定模板页面的后缀名4.5.3Thymeleaf语法规则1.常用标签
在HTML页面上使用Thymeleaf标签,Thymeleaf标签能够动态地替换掉静态内容,动态显示页面内容。为了让大家更直观地认识Thymeleaf,下面我们展示一个在HTML文件中嵌入Thymeleaf的页面文件,示例代码如下。27<!DOCTYPEhtml><htmllang="en"
xmlns:th=""><head>
<metacharset="UTF-8">
<linkrel="stylesheet"type="text/css"media="all"
href="../../css/gtvg.css“th:href="@{/css/gtvg.css}"/>
<title>Title</title>
</head>
<body>
<pth:text="${hello}">您好,欢迎进入Thymeleaf</p>
</body>
</html>4.5.3Thymeleaf语法规则
Thymeleaf模板提供了很多th:标签,具体如表4-1所示。28th:标签使用说明th:id用于id的声明,类似于HTML中的id属性th:insert页面片段包含(类似JSP中include标签)th:replace页面片段包含(类似JSP中include标签)th:each元素遍历(类似JSP中的c:forEach标签)th:if条件判断,条件成立时显示th标签的内容th:unless条件判断,条件不成立时显示th标签的内容th:switch条件判断,进行选择性匹配th:case多路选择配合th:switch使用th:object用于替换对象th:with用于定义局部变量th:标签使用说明th:attr通用属性修改th:attrprepend通用属性修改,将计算结果追加前缀到现有属性值th:attrappend通用属性修改,将计算结果追加后缀到现有属性值th:value属性值修改,指定标签属性值th:href用于设定链接地址th:src用于图片类地址引入th:text用于指定标签显示的文本内容th:utext用于指定标签显示的文本内容,对特殊标签不转义th:fragment声明片段th:remove移除片段4.5.3Thymeleaf语法规则Thymeleaf模板页面虽然与纯HTML页面基本相似,但已经不是一个标准的HTML5页面了,这是因为在Thymeleaf页面中使用的th:*属性是HTML5规范所不允许的。如果我们想要使用Thymeleaf模板进行纯HTML5的页面开发,可以使用data-th-*属性替换th:*属性进行页面开发。例如将上面的示例使用data-th-*属性进行修改,示例代码如下。使用data-th-*属性这种方式,不会出现属性的快捷提示,对于开发者来说不太方便,因此在实际开发中,相对推荐使用引入Thymeleaf标签的形式进行模板引擎页面的开发。29<!DOCTYPEhtml><htmllang="en"><head>
<metacharset="UTF-8">
<linkrel="stylesheet"type="text/css"media="all"
href="../../css/gtvg.css“data-th-href="@{/css/gtvg.css}"/>
<title>Title</title>
</head>1
<body>
<pdata-th-text="${hello}">您好,欢迎进入Thymeleaf</p>
</body>
</html>4.5.3Thymeleaf语法规则2.标准表达式Thymeleaf模板引擎提供了多种标准表达式语法,如表4-2所示。
Thymeleaf还提供了其他更多的语法支持,例如文本表达式、算式表达式、布尔表达式、比较表达式等,可查看具体的官方文档说明,下面对常用的表达式进行讲解。30表达式语法说明${…}变量表达式*{…}选择变量表达式#{…}消息表达式@{…}链接URL表达式~{…}片段表达式4.5.3Thymeleaf语法规则(1)变量表达式变量表达式${…}主要用于获取上下文中的变量值,示例代码如下:
使用了Thymeleaf模板的变量表达式${…}用来动态获取p标签中的内容。Thymeleaf为变量所在域提供了一些内置对象,如下:
如果要在Thymeleaf模板引擎页面中动态获取当前国家信息,可以使用#locale内置对象,示例代码如下:31<pth:text="${title}">标题</p>#ctx:上下文对象。#vars:上下文变量。#locale:上下文区域设置。#request:(仅在Web上下文中)HttpServletRequest对象。#response:(仅在Web上下文中)HttpServletResponse对象。#session:(仅在Web上下文中)HttpSession对象。#servletContext:(仅在Web上下文中)ServletContext对象。Thelocalecountryis:
<spanth:text="${#locale.country}">US</span>.4.5.3Thymeleaf语法规则(2)选择变量表达式
选择变量表达式*{…}和变量表达式${…}用法类似,*{…}一般用于从被选定对象而不是上下文中获取属性值,如果没有选定对象,则和变量表达式一样,示例代码如下:32
<divth:object="${session.user}">
<p>Name:<spanth:text="${#object.firstName}">Zhang</span>.</p>
<p>Surname:<spanth:text="${session.user.lastName}">Sanfeng</span>.</p>
<p>Nationality:<spanth:text="*{nationality}">China</span>.</p>
</div>4.5.3Thymeleaf语法规则(3)消息表达式消息表达式#{…}主要用于Thymeleaf模板页面国际化内容的动态替换和展示,使用消息表达式#{…}进行国际化设置时,还需要提供一些国际化配置文件。(4)链接表达式链接表达式@{…}一般用于页面跳转或资源的引入,在Web开发中占据着非常重要的地位,示例代码如下:(5)片段表达式片段表达式~{…}是一种用来将标记片段移动到模板中的方法。其中,最常见的用法是使用th:insert或th:replace属性插入片段,示例代码如下:33<ahref="details.html"
th:href="@{http://localhost:8080/order/details(orderId=${o.id})}">view</a><ahref="details.html"
th:href=“@{/order/details(orderId=${o.id})}">view</a><divth:insert="~{thymeleafDemo::title}"></div>4.5.4整合Thymeleaf下面通过示例讲解SpringBoot整合Thymeleaf模板引擎。(1)创建SpringBoot项目,引入Thymeleaf依赖(2)编写配置文件(3)创建实体类(4)创建控制器类(5)创建模板页面(6)效果测试
直接用浏览器打开index.html页面,就是前端所能看到的静态效果,如图所示。启动项目,在浏览器访问http://localhost:8080/book/showBooks,进入图书信息列表的页面,运行效果如图所示。344.6错误处理4.6.1异常处理机制SpringBoot的错误处理其实就是对SpringMVC异常处理的自动配置。因此SpringBoot同样可支持两种错误处理:以SpringBoot提供的自动配置为基础,通过提供一些配置信息来改变SpringBoot默认的错误处理行为。使用@ResponseStatus、@ExceptionHandler、@ControllerAdvice等基于AOP的异常处理机制,这是直接基于SpringMVC异常处理机制进行错误处理。SpringBoot默认提供了一个/error映射来处理所有的错误,对于普通浏览器,它会生成一个“whitelabel”错误页面,如请求http://localhost:8080/hello时发生状态值为404的错误,会有默认的页面展示给用户,如图4-14所示。354.6.1异常处理机制虽然SpringBoot为我们提供了默认的错误页面映射,但是在实际应用中,错误页面对用户来说并不友好,要对其进行自定义,添加view解析为error。要完全替代默认行为,可以实现ErrorController并注册该类型的Bean定义,或提供自定义的ErrorAttributes实现类,通过该类中的getErrorAttributes()方法即可向错误属性中添加哪些异常信息。SpringBoot为ErrorAttributes提供的实现类为DefaultErrorAttributes,它生成的错误属性包含如下异常信息。36timestamp:错误发生时间。status:HTTP状态码。error:错误原因。message:异常消息。path:错误发生时请求的URL路径。exception:异常的类名。errors:BindingResult异常里的各种错误(如果这个错误是由异常引起的)。trace:异常跟踪信息(如果这个错误是由异常引起的)。4.6.2自定义错误页SpringBoot可指定自定义的错误页面来代替原有的默认错误页面,只要将错误页面放在/error目录下即可。自定义的错误页面既可是静态的HTML页面,也可是动态的页面模板,应该将静态的HTML错误页面放在静态资源目录(如“classpath:/static/”等)下的/error目录中,而将动态的页面模板放在/resources/templates/error目录下,且动态页面模板的优先级更高。接下来通过实例讲解在SpringBoot中,如何自定义错误页面。1.简单配置2.复杂配置374.6.2自定义错误页1.简单配置
新建chapter04error的项目,在src/main/resources/static目录下创建error目录,在该error目录中创建错误展示页面404.html和500.html,不同的错误直接展示不同的页面,在两个页面的body标签部分,分别显示“404错误!”和“500错误!”。
新建HelloController的控制器类,代码如下:
启动项目,在浏览器中输入一个不存在的路径时,就会展示404.html页面的内容,如图4-14所示。浏览器中输入正确请求,但请求对应的方法会抛出异常,就会展示500.html中的内容,如图4-15所示。38@RestControllerpublicclassHelloController{
@GetMapping("/hello")
publicStringhello(){
inti=1/0; //抛出异常
return"Hello";}}4.6.2自定义错误页
若采用视图模板技术,则可向用户展示更多的错误信息。这里我们以Thymeleaf为例,Thymeleaf页面模板默认位于classpath:/templates/目录下,并在该目录下创建error目录,在该error目录下创建错误展示页面4xx.html、5xx.html,以4xx.html页面为例,代码如下所示。SpringBoot在这里一共返回了6条错误相关信息,分别是timestamp、status、error、message、path和trace。5xx.html的页面内容与4xx.html页面的内容一致。39<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head>
<metacharset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>错误信息</h3>
<tableborder="1">
<tr><td>timestamp</td><tdth:text="${timestamp}">错误</td></tr>
<tr><td>status</td><tdth:text="${status}">错误</td></tr>
<tr><td>error</td><tdth:text="${error}">错误</td></tr>
<tr><td>message</td><tdth:text="${message}">错误</td></tr>
<tr><td>path</td><tdth:text="${path}">错误</td></tr><tr><td>trace</td><tdth:text="${trace}">错误</td></tr>
</table>
</body>
</html>4.6.2自定义错误页在perties配置文件中,添加配置如下。
先删除/resources/static/error目录下的404.html和500.html页面文件。启动chapter04error项目,在浏览器中输入一个不存在的路径,例如http://localhost:8080/hel,如图4-16所示。如果访问一个会抛出异常的请求,例如http://localhost:8080/hello,如图4-17所示。
提示:若定义了多个错误页面,则404.html、500.thml页面的优先级高于4xx.html、5xx.html页面,动态页面的优先级高于静态页面。40#指定启动错误页面(这是默认值)server.error.whitelabel.enabled=true
#指定一直显示message
server.error.include-message=always
#指定包含异常类
server.error.include-exception=true
#指定一致包含BindingErrors
server.error.include-binding-errors=always
#指定一直包含异常跟踪栈
server.error.include-stacktrace=always4.6.2自定义错误页2.复杂配置简单配置的方式不够灵活,只能定义HTML页面,展示SpringBoot默认的返回信息,无法处理JSON的定制,无法返回自定义业务数据,SpringBoot中支持对Error信息定制。(1)自定义Error数据自定义Error数据就是对返回的数据进行自定义。在项目的src/main/java/目录下的com.yzpc包中创建名为customerror的包,并在该包中新建一个MyErrorAttribute类并继承DefaultErrorAttributes,重写getErrorAttributes方法,代码如下所示。41@Component//将该类注册到Spring容器中
publicclassMyErrorAttributeextendsDefaultErrorAttributes{
@Override
publicMap<String,Object>getErrorAttributes(WebRequestwebRequest,ErrorAttributeOptionsoptions){
//获取SpringBoot默认提供的错误信息
Map<String,Object>errorAttributes=
super.getErrorAttributes(webRequest,options);
errorAttributes.put("myerror","程序出错,错误如下");//自定义Error
errorAttributes.remove("error");//移除默认的error
returnerrorAttributes;
}
}4.6.2自定义错误页
修改4xx.html和5xx.html页面,将“错误信息”的标题行,使用自定义的myerror的错误信息提示,代码如下所示:重新启动项目,在浏览器地址栏中访问http://localhost:8080/hel,如图4-18所示。访问一个不存在的路径或者抛出异常的访问请求,就可以看到自定义的标题信息,并且可以看到默认的error的数据被移除了。42
<h3th:text="${myerror}">错误信息</h3>
<!--其余代码一致,此处省略-->
4.6.2自定义错误页(2)自定义Error视图
自定义Error视图是展示给用户的页面。
在项目的src/main/java/目录下的com.yzpc.customerror包中,新建MyErrorViewResolver类,代码如下所示。
在/resources/templates目录下新建error.html页面,页面代码与前面4xx.html的代码一致。将MyErrorAttribute类前的@Component注解注释掉或删除MyErrorAttribute类。
重新启动项目,无论发生的4xx错误,还是发生5xx错误,都是来到的error.html页面。如图4-19所示。43@Component//将该类注册到Spring容器中
publicclassMyErrorViewResolverimplementsErrorViewResolver{
@Override//Map参数是默认的Error信息
publicModelAndViewresolveErrorView(HttpServletRequestrequest,HttpStatusstatus,Map<String,Object>model){
ModelAndViewmav=newModelAndView("error");
mav.addObject("myerror","Error视图,程序出错,错误如下");
mav.addAllObjects(model);
returnmav;
}
}4.6.2自定义错误页(3)完全自定义前面简单配置和复杂配置两种自定义方式都是对BasicErrorController类中的某个环节进行修改。开发者需要更加灵活地对Error视图和数据进行处理,可以提供自己的ErrorController。一种是实现ErrorController接口,该接口只提供了待实现的方法;另一种直接继承BasicErrorController,该类已经实现了一些功能,这里通过继承BasicErrorController来实现自己的ErrorController。在项目的src/main/java/目录下的com.yzpc.customerror包中,新建MyErrorController类,具体实现代码如下所示。44@Controller//将类注册到SpringMVC中
publicclassMyErrorControllerextendsBasicErrorController{
@Autowired//注入所需参数
publicMyErrorController(ErrorAttributeserrorAttributes,ServerPropertiesserverProperties,List<ErrorViewResolver>errorViewResolvers){
super(errorAttributes,serverProperties.getError(),errorViewResolvers);
}
@Override
publicModelAndViewerrorHtml(HttpServletRequestrequest,HttpServletResponseresponse){
HttpStatusstatus=getStatus(request);
Map<String,Object>model=getErrorAttributes(request,getErrorAttributeOptions(request,MediaType.TEXT_HTML));
model.put("myerror","访问出错了!");
ModelAndViewmav=newModelAndView("errorpage",model,status);
returnmav;
}
@Override
publicResponseEntity<Map<String,Object>>error(HttpServletRequestrequest){
Map<String,Object>body=getErrorAttributes(request,getErrorAttributeOptions(request,MediaType.ALL));
body.put("myerror","访问出错啦!");
HttpStatusstatus=getStatus(request);
returnnewResponseEntity<>(body,status);
}
}4.6.2自定义错误页
在resources/templates目录下新建errorpage.html页面,页面代码与前面error.html的代码一致。重新启动项目,访问一个不存在的页面,就可以看到自定义的错误信息了,如图4-20所示。
如果通过postman发起这个请求,那么返回数据为一段JSON,如图4-21所示。SpringBoot虽然提供了非常丰富的自动化配置方案,但是也允许开发者根据实际情况进行完全的自定义,在开发时可以结合具体情况选择合适的Error处理方案。454.6.3在SpringMVC外部映射错误页面对于不使用SpringMVC的应用程序,可以使用errorpageregister接口直接注册ErrorPages。这种抽象直接与底层的嵌入式Servlet容器一起工作,即使没有SpringMVCDispatcherServlet也可以工作,示例代码如下所示。如果注册了一个带有最终由过滤器处理的路径的ErrorPage(这在一些非Springweb框架中很常见,如Jersey和Wicket),那么过滤器必须显式注册为错误调度器,如下例所示。46@Bean
publicErrorPageRegistrarerrorPageRegistrar(){
returnnewMyErrorPageRegistrar();
}
//...
privatestaticclassMyErrorPageRegistrarimplements
ErrorPageRegistrar{
@Override
publicvoidregisterErrorPages(ErrorPageRegistry
registry){
registry.addErrorPages(newErrorPage
(HttpStatus.BAD_REQUEST,"/400"));
}
}@BeanpublicFilterRegistrationBeanmyFilter(){
FilterRegistrationBeanregistration=newFilterRegistrationBean();
registration.setFilter(newMyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf
(DispatcherType.class));
returnregistration;
}4.7CORS支持CORS(Cross-originresourcesharing)即跨域资源共享,是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域请求,它允许浏览器向跨域服务器发送Ajax请求,打破了Ajax只能访问本站内的资源限制,CORS在很多地方都有被使用,微信支付的JS支付就是通过JS向微信服务器发送跨域请求。开放Ajax访问可被跨域访问的服务器大大减少了后台开发的工作,前后台工作也可以得到很好的明确以及分工,下面通过示例来讲解CORS。(1)新建一个SpringBoot工程chapter04cors,Group和Packagename为com.yzpc,选择SpringWeb依赖。
在perties配置文件中设置端口为8081。
47server.port=80814.7CORS支持(2)在chapter04cors工程中,在src/main/java/目录下的com.yzpc包中创建名为controller的包,并在该包下创建一个HelloController的控制器类,代码如下所示。
在项目的src/main/java/目录下的com.yzpc包中,创建名为config的包,并在该包下创建一个MyWebMvcConfig的类,并实现WebMvcConfigurer接口,重写其中的addCorsMappings方法,代码如下所示。
上面两种配置方式@CrossOrigin注解配置和全局配置,选择其中一种即可,启动chapter04cors工程。48@RestControllerpublicclassHelloController{
@GetMapping("/hello")
//使用@CrossOrigin注解允许跨域
@CrossOrigin(origins="http://localhost:8082",maxAge=1800,allowedHeaders="*")
publicStringhello(){
return"hellocors!";}}@ConfigurationpublicclassMyWebMvcConfigimplementsWebMvcConfigurer{
@Override
publicvoidaddCorsMappings(CorsRegistryregistry){
registry.addMapping("/**")
.allowedOrigins("http://localhost:8082")
.allowedHeaders("*")
.allowedMethods("*")
.maxAge(30*1000);
}
}4.7CORS支持(3)选中chapter04cors工程,右键选择New
Module,新建一个名为cors的Module,过程与新建工程类似。在cors中,在src/main/resources/static目录下,新建index.html网页文件和一个js目录,并将jquery-3.6.0.js文件放入js目录下,如图4-22所示。
静态网页文件index.html的代码如下所示。修改perties配置文件,将端口改为8082,如下所示:server.port=8082
启动CorsApplication,在浏览器中输入http://localhost:8082/index.html,页面显示一个“跨域请求”按钮,单击按钮,就能看到“hellocors!”请求结果,如图4-23所示。49<!DOCTYPEhtml><htmllang="en"><head>
<metacharset="UTF-8">
<title>跨域访问示例</title>
<scriptsrc="js/jquery-3.6.0.js"></script>
<script>
functiongetData(){
$.get('http://localhost:8081/hello',function(msg){
$("#app").html(msg);
})
}
</script>
</head>
<body>
<divid="app"></div>
<inputtype="button"value="跨域请求"onclick="getData
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 规章制度检查
- 营业员的实习报告
- 市场营销毕业实习报告15篇
- 从事家政服务公司劳动合同书(3篇)
- 读书分享会发言稿
- DB11T 1499-2017 节水型苗圃建设规范
- 新疆阿勒泰地区(2024年-2025年小学五年级语文)人教版阶段练习(下学期)试卷及答案
- 反比例函数教案文档
- 煤矿人工智能算法评估规范征求意见稿
- 上海市市辖区(2024年-2025年小学五年级语文)统编版开学考试(上学期)试卷及答案
- 创新实践(理论)学习通超星期末考试答案章节答案2024年
- 2024世界精神卫生日共建共治共享同心健心安心宣传课件
- 二十届三中全会知识点试题及答案【200题】
- 大模型应用开发极简入门基于GPT-4和ChatGPT
- 四年级教材《劳动》课件
- 2023《中华人民共和国合同法》
- (通桥【2018】8370)《铁路桥梁快速更换型伸缩缝安装图》
- 超星尔雅学习通《当代大学生国家安全教育》章节测试答案
- 小学一年级上册 综合实践教学课件
- 一年级期中家长会ppt课件(PPT 23页)
- 2021年普通口译服务合同范本word版.doc
评论
0/150
提交评论