1. 返回json数据
默认实现


2. 自定义转换器
1.使用Gson
先导入依赖

springboot默认提供了Gson的自动转换类 GsonHttpMessageConvertersConfiguration。所以Gson添加成功之后,可以像使用jackson-databind一样直接使用Gson。但是这里不支持对日期数据格式化。
如果想日期数据格式化,需要自定义HttpMessageConverter
不格式化

格式化
@Configurationpublic class GsonConfig {@Bean // 自己提供一个GsonHttpMessageConverter实例GsonHttpMessageConverter gsonHttpMessageConverter() {GsonHttpMessageConverter convert = new GsonHttpMessageConverter();GsonBuilder builder = new GsonBuilder();// 设置Gson解析时日期的格式builder.setDateFormat("yyyy-MM-dd");// 设置Gson解析时修饰符为protected的字段被过滤掉builder.excludeFieldsWithModifiers(Modifier.PROTECTED);// 创建Gson对象放入GsonHttpMessageConverter实例中并返回convertGson gson = builder.create();convert.setGson(gson);return convert;}}

2. 使用json
配置1
@Configurationpublic class MyFastJsonConfig {@BeanFastJsonHttpMessageConverter fastJsonHttpMessageConverter() {FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();FastJsonConfig config = new FastJsonConfig();config.setDateFormat("yyyy-MM-dd");config.setCharset(Charset.forName("utf-8"));config.setSerializerFeatures(SerializerFeature.WriteClassName,SerializerFeature.WriteMapNullValue,SerializerFeature.PrettyFormat,SerializerFeature.WriteNullListAsEmpty,SerializerFeature.WriteNullStringAsEmpty);converter.setFastJsonConfig(config);return converter;}}

MyFastJsonConfig配置完成后,还有配置一下响应编码,否则返回json会出现中文乱码。
配置2
除了上述配置,还有一种配置方法,就是继承WebMVCAutoConfiguration,然后重写里面的特定方法
3. 静态资源目录及其优先级


优先级:即先去找 /META-INF/resources下的p1,找不到去找resources下的
4. 文件上传


总结,一共有2个文件上传组件
CommonsMultipartResolver 使用commons-fileupload来初始multipart请求
StandardServletMultipartResolver使用Servlet3.0来处理。
springboot默认使用第二个。
相关配置

5. @ControllerAdvice:全局数据、异常、请求参数处理
5.1、全局异常处理 @ControllerAdvice + @ExceptionHandler
@ControllerAdvicepublic class CustomExceptionHandler {@ExceptionHandler(ArithmeticException.class)public void arithException(ArithmeticException e, HttpServletResponse resp) throws IOException {resp.setContentType("text/html;charset=utf-8");PrintWriter out = resp.getWriter();out.write("运算异常!");out.flush();out.close();}@ExceptionHandler(NullPointerException.class)public ModelAndView arithException2(NullPointerException e) {ModelAndView mv = new ModelAndView();mv.addObject("msg","空指针异常!");mv.setViewName("error");// mv.setViewName("handle");return mv;}}
control层
@RequestMapping("/exception")public int testExe() {int c = 20/0;return c;}@RequestMapping("/exception2")public String[] testExe2() {String[] arr = new String[2];String[] split = arr[1].split(",");return split;}


5.2、添加全局数据 @ControllerAdvice + @ModelAttribute

5.3、请求参数处理 @ControllerAdvice+@ModelAttribute+@InitBinder
来看一种情况


(其实这里参数user、author前隐含了 @ModelAttribute)
怎么解决这种情况呢?


如上,问题得以解决。
解释一下上面的代码。上面的@ModelAttribute把对象a和对象b封装到了model里。然后在全局配置页面上,有InitBinder 为model里a和b对象做了一些改动,即给对象的所有的属性字段增加了 前缀。这样就能区分出name了。
在WebDataBinder对象中,还可以设置允许的字段、禁止的字段、必填字段以及验证器等。
6. CORS支持
6.1、什么是跨域?





如果一个服务是91端口,这个服务又调用其他的服务。而这个服务是90端口,这就会出现跨域

6.2、跨域怎么解决?
1、jsonp,
缺点:只支持Get,而且是把远程的函数拉过来本地运行。和开发流程不符合。所以最好使用CROS
2、CROS
比如:
对8080:当前服务是在8080端口,而我的前端想访问8081端口里的服务(添加、删除),请求8081
对8081:如果8081端口的服务里这两个方法没有开启跨域支持8080,那么就会访问失败(没有解决跨域)
总结,当8080端口的前端页面需要去8081端口拿数据(而不是8080自身),就会出现跨域。解决办法是让8081端口允许被跨域。
注意:跨域指的不是自身前端页面解决,而是被请求的后端资源去解决。被请求的服务要允许自己被其他人访问,而不是仅仅是自身才能访问。
服务端支持跨域

完整的跨域流程



跨域解决
有两种办法:一种在方法上加@CrossOrigin、一种在全局进行配置
下面创建两个工程
8081工程提供后端服务。这里配置跨域,表示自己的资源可以被跨域取到。
8080工程负责前端请求。这里发起ajax请求,去拿8081端口的服务。
8081工程:这里是写在了方法上。
@RestController@RequestMapping("/book")public class CROSController {@PostMapping("/")@CrossOrigin(value="http://localhost:8080",maxAge = 1800,allowedHeaders = "*")public String addBook(String name) {return "receive:"+name;}@DeleteMapping("/{id}")@CrossOrigin(value="http://localhost:8080",maxAge = 1800,allowedHeaders = "*")public String deleteById(@PathVariable Long id) {return String.valueOf(id);}}


还可以写在全局中
@Configurationpublic class MyWebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/book/**").allowedHeaders("*").allowedMethods("*").maxAge(1800).allowedOrigins("http://localhost:8080");}}

配置文件把端口改成8081
8080工程:
resources/static文件下创建index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script></head><body><div id="contentDiv"></div><div id="deleteResult"></div><input type="button" value="提交数据" onclick="getData()"><br><input type="button" value="删除数据" onclick="deleteData()"><br><script>function deleteData() {$.ajax({url: 'http://localhost:8081/book/99',type: 'delete',success: function(msg) {$("#deleteResult").html(msg);}})}function getData() {$.ajax({url: 'http://localhost:8081/book/',type: 'post',data: {name: '三国演义'},success: function(msg) {$("#contentDiv").html(msg);}})}</script></body></html>
然后运行两个服务。运行结果如下:
如果我把跨域代码注释,运行结果变成了:
7. 配置类与xml配置
springboot一般建议写成配置类的形式来取代xml配置文件。
如果实在想用xml文件,也可以通过@ImportResource进行导入。
比如我创建了一个bean.xml,里面注册了一个组件hello。
然后我想引入,此时我可以创建一个Beans配置类。
8. 注册拦截器
这里具体怎么创建的,已经用过很多次了,不再介绍了。下面给出一些注意事项。
9. 启动系统任务
9.1 CommandLineRunner
代码:

Order可以看成前后,而不是大小,1,2,3都是序号,序号越靠前的越先执行。
运行结果:
在idea启动器上加上参数:三国演义 罗贯中,然后运行,看看控制台

9.2 ApplicationRunner





10. 整合Servlet、Filter和Listener




11. 路径映射

12. 配置AOP
如果想给某个包下所有类、某个类、类中的某个方法配置切面。
创建切面类,通过切入点指定你想切入的地方。
配置各种通知。
然后通过@Component注册到容器里。然后直接就可以使用了


13. 放弃某些自动配置类


