有两方面功能:
1.将服务端的对象序列化成字符串
2.将前端传过来的json字符串反序列化成java对象SpringMvc配置了Jackson和Gson的HttpMessageConverter,springboot中又做了自动化配置,如果用户使用两者,只需要添加相应的依赖即可,不需要额外配置。具体可查看源码JacksonHttpMessageConvertersConfiguration和GsonAutoConfiguration。
pom.xml配置如下
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot<</groupId> <artifactId>spring-boot-starter-json</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency>springboot对fastjson没有实现自动化配置,因此使用fastjson相对麻烦些。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot<</groupId> <artifactId>spring-boot-starter-json</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency>编写配置类
@Configuration public class WebMvcConfig { @Bean FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){ FastJsonHttpMessageConverter converter=new FastJsonHttpMessageConverter(); return converter; } }<mvc: resource mapping="/js/**" location="/js/">
springboot 提供了自动化的配置。参考源码WebMvcAutoConfigration.java、ResourceProperties.java
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};静态资源默认位置(5个,有优先级 从高到低如下):
1.classpath:/META-INF/resources/
2classpath:./resources/
3.classpath:/static/
4.classpath:/public/
5./(斜杠指向webapp下面)
有两种方式
1.在application.properties中
##相当于<mvc: resource mapping="/feiyu/**" location="/feiyu/">中的location spring.resources.static-locations=classpath:/feiyu/ ##相当于<mvc: resource mapping="/feiyu/**" location="/feiyu/">中的mapping spring.mvc.static-path-pattern=/feiyu2.java配置方式
@Configuration public class WebConfig implements WebMvcConfigurer { /** * 添加静态资源文件,外部可以直接访问地址 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //如下配置则能可以访问src/main/resources/feiyu下面的文件 registry.addResourceHandler("/feiyu/**").addResourceLocations("classpath:/feiyu/"); } }源码:MultipartResolver.java 使用idea快捷键ctrl+H 发现MultipartResolver有两个实现类 StandardServletMultipartResolver和CommonsMultipartResolver(支持低版本的servlert)。springboot中使用的是StandardServletMultipartResolver,在springmvc中该类不支持serverlet 2.5,在springboot是支持的。
2 .html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="提交"> </form> </body> </html> 配置类添加静态资源映射,以便能使用url访问上传的文件
@Configuration public class WebConfig implements WebMvcConfigurer { /** * 添加静态资源文件,外部可以直接访问地址 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/img/**").addResourceLocations("file:E:/test/"); } } application.properties配置属性 例如 允许上传的最大文件大小
#允许上传文件上限 spring.servlet.multipart.max-file-size=1KB运行项目,浏览器访问http://localhost:8080/index.html
选择文件,提交,上传成功后返回下面链接
http://localhost:8080/img/2020-09-21/26603170-ddc3-45c9-b0e1-53030a8596e7.jpg
使用该链接可以查看刚刚上传的图片。
1.controller代码
@PostMapping("/uploads") public String uploads(MultipartFile[] files, HttpServletRequest req) throws IOException { String format = sdf.format(new Date()); String realPath = "E:/test/" + format; File folder = new File(realPath); if(!folder.exists()){ folder.mkdir(); } for (MultipartFile file : files) { String oldName=file.getOriginalFilename(); String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf(".")); // file.transferTo(new File(folder,newName)); String p=folder.getAbsolutePath()+File.separator+newName; file.transferTo(new File(p)); String url=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/img/"+format+"/"+newName; System.out.println(url); } return "success"; }2.html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/uploads" method="post" enctype="multipart/form-data"> <input type="file" name="files" multiple> <input type="submit" value="提交"> </form> </body> </html>借助jquery来实现文件上传
1.html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="jquery3.3.1.js"></script> </head> <body> <div id="result"></div> <input type="file" id="file"> <input type="button" value="上传" onclick="uploadFile()"> <input type="file" id="files" multiple> <input type="button" value="批量上传" onclick="uploadFiles()"> <script> function uploadFile() { var file=$("#file")[0].files[0]; var formData=new FormData(); formData.append("file",file); $.ajax({ type:'post', url:'/upload', processData:false,//processData默认为true(该方法为jQuery独有的)默认情况下会将发送的数据序列化以适应默认的内容类型application/x-www-form-urlencoded contentType:false, data:formData, success:function (msg) { $("#result").html(msg); } }) } function uploadFiles() { var files=$("#files")[0].files; var formData=new FormData(); for (var i=0;i<files.length;i++) { formData.append("files",files[i]); } //formData.append("files",files); //这样写后台收不到 $.ajax({ type:'post', url:'/uploads', processData:false,//processData默认为true(该方法为jQuery独有的)默认情况下会将发送的数据序列化以适应默认的内容类型application/x-www-form-urlencoded contentType:false, data:formData, success:function (msg) { $("#result").html(msg); } }) } </script> </body> </html>2.controller代码同3.1和3.2
该注解是spring注解,不是springboot专有的。
这里讲三个用法。
1.处理全局异常。
2.预设全局数据。
3.请求参数预处理。
此时使用3.1文件上传,选择超出范围的文件后,页面输出“ 上传文件大小超出上限”。
@ControllerAdvice配合 @ModelAttribute使用。该数据可以在任意Controller里获得。
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ModelAttribute; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class GlobalData { @ModelAttribute(value="info") public Map<String,Object> mydata(){ Map<String,Object> map=new HashMap(); map.put("name","feiyu"); return map; } }编写controller
@RestController public class HelloController { @GetMapping("/hello") public String hello(Model m){ Map<String, Object> map = m.asMap(); Map info = (Map) map.get("info"); return (String) info.get("name"); } }postman访问,数据能正确的映射到对象里。
在resource/static 新建error文件夹,创建404.html和500.html
404.html如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>404</h1> </body> </html>编写controller,制造一个异常
@RestController public class HelloController { @GetMapping public String hello(){ int i=1/0; return "hello"; } }访问http://localhost:8080/hello,跳转到404.html
支持模糊匹配,创建4xx.html5
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>4xx</h1> </body> </html>404.html和4xx.html页面同时存在优先使用404.html
在error下面新建4xx.html
引入theamleaf依赖
优先使用templates下的错误页面,优先使用具体的html。
templates.error.404.html>templates.error.4xx.html>static.error.404.html>static.error.4xx.html
自动配置源码在ErrorMvcAutoConfiguration.java和DefaultErrorViewResolver.java中。
编写 5xx.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>template 5xx</h1> <table BORDER="1"> <tr> <td>path</td> <td th:text="${path}"></td> <!--默认的--> </tr> <tr> <td>timestamp</td> <td th:text="${timestamp}"></td><!--默认的--> </tr> <tr> <td>message</td> <td th:text="${message}"></td><!--默认的--> </tr> <tr> <td>status</td> <td th:text="${status}"></td><!--默认的--> </tr> <tr> <td>myError</td> <!--自定义异常--> <<td th:text="${myError}"></td> </tr> </table> </body> </html>定义继承DefaultErrorAttributes的类,重写getErrorAttributes方法
@Component public class MyErrorAttribute extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace); map.put("myError","自定义异常"); return map; } }发生异常会跳转feiyu.html
同源策略:相同的协议、域名、端口号。
CORS: 跨域资源共享
传统方案是JSONP,CORS是另外一种方案。比前者更现代。
允许来自http://localhost:8081的请求。@CrossOrigin也可以放在类名上
在系统启动的时候执行的任务
args参数 可以在使用java -jar 启动项目时指定
例如 java -jar commondlinerunner-0.0.1-SNAPSHOT.jar feiyu java 指定2个参数 feiyu和java
打包后 运行命令
java -jar applicationrunner-0.0.1-SNAPSHOT.jar --name=feiyu --address=china 男
运行结果
[--name=feiyu, --address=china, 男] [男] [address, name] [china] [feiyu]两种方式主要是支持的参数不同
一些简单的访问不需要通过controller访问页面模板,通过路径映射访问也可以
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/hello").setViewName("hello"); } }访问http://localhost:8080/hello即可找到hello.html,不需要编写controller
访问http://localhost:8080会自动转去执行 http://localhost:8080/index
https://tool.lu/favicon 使用该网站制作ico文件,将文件放在resource或者static下面即可
第二种方式在application.properties里配置
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration