假如页面报404,主要原因是因为我们在使用矩阵注解的时候,没有使用@PathVablied注解获取路径所以报404的错误。分号
的前面是路径
。分号前面的路径一定要使用@PathVabiled()
java
package com.jsxs.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.Cookie; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Author Jsxs * @Date 2023/7/3 16:14 * @PackageName:com.jsxs.controller * @ClassName: ParamterTestController * @Description: TODO * @Version 1.0 */ @Controller @ResponseBody public class ParameterTestController { // 6. @MatrixVariable // /car/{path;low=10,brand=byd} // 面试题: cookie被静用了,session里面存放的值怎么获取? // 正常流程: session->(生成)sessionID(会保存在cookie中)->cookie(需要携带SessionID)才能进行获取具体session // cookie被禁用怎么处理?: url重写,使用矩阵变量进行传递(把Session的值使用矩阵变量的方式进行传递) // /cars/sell;low=34;brand=byd,audi,yd // 我们访问的时候发现页面报400 请求异常的错误,主要原因是SpringBoot禁用了矩阵变量 // 我们需要手动的进行开启 : 原理对路径的处理都是 WebMvcAutoConfiguration类下 -> configurePathMatch()方法体中 -> UrlPathHelper类中 -> removeSemicolonContent属性默认为(true) // 1.成功配置开启之后,我们访问的页面是404.因为我们矩阵变量有格式 @GetMapping("/cars/{path}") public Map<String, Object> carsSell(@MatrixVariable("low") Integer low, @MatrixVariable("brand") List<String> brand, @MatrixVariable Map<String, String> mv, @PathVariable("path") String path ) { HashMap<String, Object> map = new HashMap<>(); map.put("low", low); map.put("brand", brand); map.put("path", path); map.put("mv", mv); return map; } // 非紧密性矩阵, ;之前的路径一定要使用Rest 风格 @GetMapping("/cars/{path}/{a}") public Map<String, Object> carsSell2(@MatrixVariable("low") Integer low, @MatrixVariable("brand") List<String> brand, @MatrixVariable Map<String, String> mv, @PathVariable("path") String path, @PathVariable("a") String a ) { HashMap<String, Object> map = new HashMap<>(); map.put("low", low); map.put("brand", brand); map.put("path_1", path); map.put("path_2", a); map.put("mv", mv); return map; } // 7. 紧密型矩阵 : 查询是1号的且年龄等于20的老板手下员工2号且员工年龄是10岁的 // /boss/1;age=20/2;age=10 @GetMapping("/boss/{bossID}/{empID}") public Map<String, Object> Boss( @MatrixVariable(value = "age", pathVar = "bossID") Integer BossAge, @MatrixVariable(value = "age", pathVar = "empID") Integer empAge, @PathVariable("bossID") String path_bossID, @PathVariable("empID") String path_empID, @MatrixVariable Map<String, String> mv ) { Map<String, Object> map = new HashMap<>(); map.put("path_boss_id",path_bossID); map.put("path_emp_id",path_empID); map.put("boss_age",BossAge); map.put("empAge",empAge); map.put("mv",mv); return map; } }
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> <a href="http://localhost:8080/cars/sell;low=34;brand=byd,bmw,mi">@MatrixVariable注解 (数组不分开)</a> </ul> <ul> <a href="http://localhost:8080/cars/sell;low=34;brand=byd;bmw;mi">@MatrixVariable注解 (数组分开)</a> </ul> <ul> <a href="http://localhost:8080/cars/sell/a;low=34;brand=byd;bmw;mi">@MatrixVariable注解 (非紧密双矩阵)</a> </ul> <ul> <a href="http://localhost:8080/boss/1;age=20/2;age=10">@MatrixVariable注解 (紧密双矩阵)</a> </ul> </body> </html>
(1.2)、Servlet API
WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId
ServletRequestMethodArgumentResolver
以上的部分参数
@Override public boolean supportsParameter(MethodParameter parameter) { Class<?> paramType = parameter.getParameterType(); return (WebRequest.class.isAssignableFrom(paramType) || ServletRequest.class.isAssignableFrom(paramType) || MultipartRequest.class.isAssignableFrom(paramType) || HttpSession.class.isAssignableFrom(paramType) || (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) || Principal.class.isAssignableFrom(paramType) || InputStream.class.isAssignableFrom(paramType) || Reader.class.isAssignableFrom(paramType) || HttpMethod.class == paramType || Locale.class == paramType || TimeZone.class == paramType || ZoneId.class == paramType); }
(1.5)、自定义对象参数
可以自动类型转换与格式化,可以级联封装。
(3).POJO封装过程
我们自定义的类在SpringMVC中是由下面的类进行封装的
ServletModelAttributeMethodProcessor 类进行封装的
这里我们使用级联数据绑定 pet.name 这个就叫级联
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/saveuser" method="post"> 姓名: <input name="userName" value="jsxs"> 年龄: <input name="age" value="18"> 生日: <input name="birth" value="2019/12/17"> 宠物姓名: <input name="pet.name" value="阿猫"> 宠物年龄: <input name="pet.age" value="5"> <input type="submit" value="保存"> </form> </body> </html>
package com.jsxs.bean; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Data; import java.util.Date; /** * @Author Jsxs * @Date 2023/7/5 11:39 * @PackageName:com.jsxs.bean * @ClassName: Person * @Description: TODO * @Version 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor public class Person { private String userName; private Integer age; private Date birth; private Pet pet; }
package com.jsxs.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author Jsxs * @Date 2023/7/5 11:40 * @PackageName:com.jsxs.bean * @ClassName: Pet * @Description: TODO * @Version 1.0 */ @Data @AllArgsConstructor @NoArgsConstructor public class Pet { private String name; private String age; }
// 数据绑定: 页面提交的请求数据(GET、POST)都可以和对象属性进行绑定 @PostMapping("/saveuser") // 我们的想法是: 因为传递过来的都是实体类的数据 public Person saveUser(Person person,@RequestBody String content){ return person; }
结果我们发现我们提交的数据不仅进行了自动类型转换,而且还赋值了数据。
(1.4)、复杂参数
Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder
- Map和Model (会转储到HttpRequest中)
假如说我们在方法种放的参数是: Map类型和Model类型。那么Map和Model中添加的值相当于(HttpRequest)request.setAttribute()中放置数据。
我们在传地方设置两个参数Map和Model类型,转发到
// 接受方 @ResponseBody @GetMapping("/success") public Map<String, Object> SuccessPage(HttpServletRequest httpServletRequest, @RequestAttribute(name = "msg",required = false) String name, HttpServletRequest request ) { Object hello = request.getAttribute("hello"); Object world = request.getAttribute("world"); Object message = request.getAttribute("message"); String info = (String) httpServletRequest.getAttribute("info"); System.out.println(info + " " + name); HashMap<String, Object> map = new HashMap<>(); map.put("info_代码方式", info); // 假如说是: 通过/params转发过来的就会为空 -》 (因为这个属于二次请求过来的) map.put("msg_注解方式", name); // 假如说是: 通过/params转发过来的就会为空 map.put("hello",hello); map.put("world",world); map.put("message",message); return map; } // 传地方 @GetMapping("/params") public String testParam(Map<String, Object> map, Model model, HttpServletRequest request, HttpServletResponse response) { map.put("hello", "world666"); model.addAttribute("world", "hello666"); request.setAttribute("message", "hello world"); Cookie cookie = new Cookie("cookie_self", "88888888888"); cookie.setDomain("localhost"); // 作用域设置为 本机 response.addCookie(cookie); return "forward:/success"; }
MapMethodProcessor 类下
Map、Model类型的参数,会返回 mavContainer.getModel();—> BindingAwareModelMap 是Model 也是Map
下面是Model和Map的对象,我们发现对象是一样的。所以Model是等于Map的。