👨🏻🎓博主介绍:大家好,我是芝士味的椒盐,一名在校大学生,热爱分享知识,很高兴在这里认识大家🌟
🌈擅长领域:Java、大数据、运维、电子
🙏🏻如果本文章各位小伙伴们有帮助的话,🍭关注+👍🏻点赞+🗣评论+📦收藏,相应的有空了我也会回访,互助!!!
🤝另本人水平有限,旨在创作简单易懂的文章,在文章描述时如有错,恳请各位大佬指正,在此感谢!!!
@[TOC]
SpringBoot核心功能
配置文件(yaml)
- 适合用来做以数据为中心的配置文件
基本语法
- key: value;kv之间有空格
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
- 字符串无需加引号,如果要加,'hello \n hello'表示字符串内容 会被转义,变成"hello \n hello"
数据类型
字面量:单个的、不可再分的值。date、boolean、string、number、null
k: v
对象:键值对的集合。map、hash、set、object
行内写法: k: {k1:v1,k2:v2,k3:v3} #或 k: k1: v1 k2: v2 k3: v3
数组:一组按次序排列的值。array、list、queue
行内写法: k: [v1,v2,v3] #或者 k: - v1 - v2 - v3
例子
Person.java
@ToString @EqualsAndHashCode @Data @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor @Component @ConfigurationProperties(prefix = "myself") public class Person { private String userName; private Boolean boss; private Date birth; private Integer age; private Pet pet; private String[] interests; private List<String> animal; private Map<String, Object> score; private Set<Double> salarys; private Map<String, List<Pet>> allPets; }
application.yml
myself: username: 宋江 boss: false birth: 1999/07/09 age: 21 pet: name: 小狗 color: red interests: [篮子,箩筐] animal: [cat,dog] # score: # chinses: # first: 90 # secode: 88 # meth: # first: 99 # secode: 57 score: {chinse: 19,math: 20} salarys: [199.00,889.76] all-pets: marry: [{name: cat,color: red}] jack: [{name: dog,color: blue}] # salarys: {17.09,98.22} # allPats: # marray: # - {name:tom} # - {name:dog,color:yellow}
Web开发
静态资源访问
只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
改变默认的静态资源映射路径
spring: mvc: static-path-pattern: /res/** #改变静态资源的目录 resources: static-locations: [classpath:/haha/]
- webjar
自动映射 /webjars/**
- webjar
静态资源反问前缀
spring: mvc: static-path-pattern: /res/**
访问 : 当前项目根路径/ res/+ 静态资源名
欢迎页面支持
- 静态资源路径下 index.html
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
- controller能处理/index
自定义Favicon
- favicon.ico 放在静态资源目录下即可。
静态资源配置原理(收录)
- ⚠️ 注意:
spring: resources: add-mappings: false 禁用所有静态资源规则,即所有默认的静态映射规则失效
请求参数处理(已收录)
rest使用与原理
- 以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户
- 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
- 核心Filter;HiddenHttpMethodFilter
- 用法: 表单method=post,隐藏域 _method=put
SpringBoot中手动开启
spring: mvc: hiddenmethod: filter: enabled: true #开启表单的Rest功能
Rest原理(表单提交要使用REST的时候)
- 表单提交会带上_method=PUT
- 请求过来被HiddenHttpMethodFilter拦截
- 请求是否正常,并且是POST
- 获取到_method的值。
- 兼容以下请求;PUT.DELETE.PATCH
- 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
- 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。
修改_method为自己所要设置的值
@Configuration(proxyBeanMethods = false) public class WebConfig { //设置接受参数的方法名 @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter(){ HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); hiddenHttpMethodFilter.setMethodParam("_mymethod"); return hiddenHttpMethodFilter; } }
例子:
index.html
<form action="/user" method="get"> <input value="发送Get请求!" type="submit"> </form> <form action="/user" method="post"> <input value="发送Post请求!" type="submit"> </form> <form action="/user" method="post"> <input name="_mymethod"" value="put" type="hidden"> <input value="发送Put请求!" type="submit"> </form> <form action="/user" method="post"> <input name="_mymethod"" value="delete" type="hidden"> <input value="发送Delete请求!" type="submit"> </form>
Controller.java
@GetMapping("/user") public String get(){ return "客户端发送Get请求!"; } @PutMapping("/user") public String put(){ return "客户端发送Put请求!"; } @PostMapping("/user") public String post(){ return "客户端发送Post请求!"; } @DeleteMapping("/user") public String delete(){ return "客户端发送Delete请求!"; }
- ⚠️ 注意:@RequestMapping(value = "/user", method = RequestMethod.DELETE)等于@DeleteMapping("/user")
WebConfig.java
//设置接受参数的方法名 @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter(){ HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); hiddenHttpMethodFilter.setMethodParam("_mymethod"); return hiddenHttpMethodFilter; }
- 请求映射原理(已收录)
普通参数和基本注解
@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody、@RequestAttribute
代码实现:
WebController.java
@GetMapping("/car/{id}/owner/{username}") public Map<String,Object> getCar( //从上面路径中获取{}中的参数,也就是路径参数 @PathVariable("id") String id, @PathVariable("username") String username, //获取全部的参数 @PathVariable Map<String,String> map, //获取响应头的参数 @RequestHeader("User-Agent") String user_Agent, @RequestHeader Map<String,String> header, //从page获取xxx=vaue中的value @RequestParam("age") String age, @RequestParam("sex") String sex, @RequestParam Map<String,String> infomap){ HashMap<String, Object> infoMap = new HashMap<>(); infoMap.put("id",id); infoMap.put("usernaem",username); infoMap.put("allInfo",map); infoMap.put("user_agent",user_Agent); infoMap.put("header",header); infoMap.put("age",age); infoMap.put("sex", sex); infoMap.put("infomap",infomap); return infoMap; } /** * 用于表单提交获取参数 * @param context * @return */ @PostMapping("/save") public Map infoUser(@RequestBody String context){ HashMap<String,Object> contextMap = new HashMap<>(); contextMap.put("context", context); return contextMap; }
index.html
<div> <a href="/car/1/owner/gcq?age=12&sex=男">/car/1/owner/gcq?age=12&sex=男</a> </div>
@RequestAttribute代码实现
@Controller public class RequestController { /** * 接受/goto请求 * @param request * @return */ @GetMapping("/goto") public String gotoPage(HttpServletRequest request){ request.setAttribute("msg","转发成功!"); request.setAttribute("code",200); return "forward:/success"; } /** * 接受forward:/success的转请求 * @param msg * @param code * @param request * @return */ @ResponseBody @GetMapping(value = "/success",produces = "application/json;charset=utf-8") public Map reviceSuccess(@RequestAttribute("msg") String msg, @RequestAttribute("code") String code, HttpServletRequest request){ //从请求域中获取获取msg Object msg1 = request.getAttribute("msg"); HashMap<String, Object> result = new HashMap<>(); //通过注获取msg result.put("anno_msg",msg); result.put("anno_code",code); result.put("anno_request",msg1); return result; } }
@MatrixVariable和UrlPathHelper()矩阵变量
代码实现
config.java
// /** // * 定制路径映射规则,使配置类实现WebMvcConfigurer接口 // * @param configurer // */ // @Override // public void configurePathMatch(PathMatchConfigurer configurer) { // UrlPathHelper urlPathHelper = new UrlPathHelper(); // //使不移除;后的内容,矩阵变量功能生效 // urlPathHelper.setRemoveSemicolonContent(false); // configurer.setUrlPathHelper(urlPathHelper); // } /** * 使用内部类的方式进行创建 * @return */ @Bean public WebMvcConfigurer webMvcConfigurer(){ return new WebMvcConfigurer() { @Override public void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false); configurer.setUrlPathHelper(urlPathHelper); } }; }
controller.java
@ResponseBody @GetMapping(value = "/id/{path}/{path2}",produces = "application/json;charset=utf-8") public Map careSell(@MatrixVariable(value = "age",pathVar = "path") Integer age, @MatrixVariable(value = "age",pathVar = "path2") Integer age2, @MatrixVariable(value = "sex",pathVar = "path") String sex, @MatrixVariable(value = "sex",pathVar = "path2") String sex2, @PathVariable String path){ Map<String,Object> result = new HashMap<>(); result.put("anno_age",age); result.put("anno_age2",age2); result.put("anno_sex",sex); result.put("anno_sex2",sex2); result.put("all_info",path); return result; }
index.html
<div> <a href="/id/1;age=99;sex=男/3;age=88;sex=女">/cars/sell;low=34;brand=byd,audi,yd</a> </div>
复杂参数
Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder
Map<String,Object> map, Model model, HttpServletRequest request 都是可以给request域中放数据, request.getAttribute();
代码实现:
controller.java
/** * 接受forward:/success的转请求,从请求域中获得参数 * @param msg * @param code * @param request * @return */ @ResponseBody @GetMapping(value = "/success",produces = "application/json;charset=utf-8") public Map reviceSuccess(@RequestAttribute(value = "map's",required = false) String msg, @RequestAttribute(value = "msg",required = false) String code, @RequestAttribute(value = "msgs",required = false) String msgs, //请求头中获取cookie @RequestHeader("cookie") String cookies, HttpServletRequest request){ HashMap<String, Object> result = new HashMap<>(); Object msgs1 = request.getAttribute("msgs"); //通过注获取msg result.put("anno_msg's",msg); result.put("anno_msg",code); result.put("anno_msgs",msgs); result.put("cookies",cookies); result.put("getmsgs1",msgs1); return result; } /** * 接受/param的请求封装到请求域中 * @param map * @param model * @param request * @param response * @return */ @GetMapping("/param") public String careParam(Map<String,Object> map, Model model, HttpServletRequest request, HttpServletResponse response){ map.put("map's","coders"); model.addAttribute("msg","hello"); request.setAttribute("msgs","helloreq"); Cookie cookie = new Cookie("cookie1","value1"); cookie.setDomain("localhost"); response.addCookie(cookie); return "forward:/success"; }
required = false表示该参数不是必须的,默认是必须得
自定义对象参数
- 可以自动类型转换与格式化,可以级联封装。
代码实现:
Controller.java
/** * 表单传递参数封装为对象 * * @param humans * @return */ @ResponseBody @PostMapping(value = "/saveuser", produces = "application/json;charset=utf-8") public Humans biandOp(Humans humans) { return humans; }
index.html
<form action="/saveuser" method="post"> 用户名:<input name="name" value="宋江"> 年龄:<input name="age" value="66"> 性别:<input name="sex" value="男"> 宠物名称:<input name="pet.name" value="coco"> 宠物颜色:<input name="pet.color" value="yellow"> <input value="提交" type="submit"> </form>
Humans.java
@AllArgsConstructor @NoArgsConstructor @Data @Accessors(chain = true) @EqualsAndHashCode @ToString public class Humans { private String name; private int age; private String sex; private Pet pet; }
POJO封装过程(已收录)
- ServletModelAttributeMethodProcessor
数据响应与内容协商
- 响应JSON
jackson.jar+@ResponseBody
SpringMvc支持的返回值
ModelAndView Model View ResponseEntity ResponseBodyEmitter StreamingResponseBody HttpEntity HttpHeaders Callable DeferredResult ListenableFuture CompletionStage WebAsyncTask 有 @ModelAttribute 且为对象类型的 @ResponseBody 注解 ---> RequestResponseBodyMethodProcessor;
内容协商
根据客户端接收能力不同,返回不同媒体类型的数据。
- 首先引入xml依赖
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
- 开启自动协商,可以使用API测试工具对其进行测试,更改Accept的值为json或是xml
spring: mvc: contentnegotiation: favor-parameter: true
发送请求:http://localhost:8080/person?format=json或者http://localhost:8080/person?format=xml
自定义协商(application/aux-aitu)
实现HttpMessageConverter接口,并重写一系列方法
@Override public boolean canWrite(Class<?> aClass, MediaType mediaType) { return aClass.isAssignableFrom(Person.class); } /** * 自定义协商规则遵从aux-aitu * @return */ @Override public List<MediaType> getSupportedMediaTypes() { return MediaType.parseMediaTypes("application/aux-aitu"); } /** * 自定数据返回的格式 * @param person * @param mediaType * @param httpOutputMessage * @throws IOException * @throws HttpMessageNotWritableException */ @Override public void write(Person person, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException { String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth(); OutputStream body = httpOutputMessage.getBody(); body.write(data.getBytes()); }
并在WebMvcConfiguration中重写extendMessageConverters,
public WebMvcConfigurer webMvcConfigurer(){ return new WebMvcConfigurer() { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new GuiConverter()); }
- 响应JSON