准备工作
1.配置web.xml
(也可以设置不全拦截,加上这两句: <mvc:default-servlet-handler/> <mvc:annotation-driven></mvc:annotation-driven> 加上之后SpringMVC会对请求进行筛查,如果确实有对该映射的处理,就正常跳转,如果没有则由默认的 Servlet处理) 2.配置mvc的配置文件 2.1 配置自动扫描的包 2.2 配置视图解析器 (InternalResourceViewResolver是将方法返回的值和prefix和suffix拼接成实际的物理视图) (BeanNameViewResolver:若方案的返回值是一个bean名(就是类名首字母小写),就会直接返回这个类的实例) 一. @RequestMapping Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求 @RequestMapping可以在两个位置进行标注
- 类定义的上面:提供初步请求映射,相当与从根目录开始
- 方法的上面:进一步细分映射,若类定义处标注了@RequestMapping,则方法出标注的映射就是接着类之后的映射,若类没有标注,则相当与从根目录开始
- 基本数据类型传递
- @PathVariable
- @RequestParam
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
五. 处理模型数据 有ModleAndView和Map种选择
- ModelAndView
- Map(Model,ModelMap)
(那么在jsp中写${requestScope.names}就可以在页面上显示[Tom,Jerry,Mike]) ModelAndView和Map区别? 答: ModelAndView的实例是需要我们手动new的,并且ModelAndView 可以自己寻址(因为setViemName方法设置了他指向的文件名),只需要return 返回其对象即可。而Map 的实例都是spirng mvc框架来自动创建并作为控制器方法参数传入,不用自己创建。需要return 返回指定的页面路径. 六. REST 浏览器 form 表单只支持 GET与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与DELETE 请求。 配置过程: 1.在web.xml文件中配置HiddenHttpMethodFilter,可将post请求转为put和delete <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 然后在
(发送post请求时携带一个name=_method的隐藏域,hiddenfilter会识别这个名字,并把其隐藏域对应的value值转为对应的请求方法发出去,这里发的就是put类型的请求) 七. ModelAttribute @ModelAttribute最主要的作用是将数据添加到模型对象中(可用来完成从表单将数据传递给model对象的功能) 注:在方法定义上使用 @ModelAttribute 注解:Spring MVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。 运行流程: 1. 执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中. 键为: user @ModelAttribute public void getUser(@RequestParam(value="id",required=false) Integer id, Map<String, Object> map){ System.out.println("modelAttribute method"); if(id != null){ //模拟从数据库中获取对象 User user = new User(1, "Tom", "123456"); System.out.println("从数据库中获取一个对象: " + user); map.put("user", user); } } (原始数据:1 Tom 123456) 2. SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性. (表单中输入了密码,输入值为56789)[方法是入参:在进行数据绑定之前,先到请求范围当中查找指key(POJO类的首字母小写)对应的value值对象,就是下面对应的user] 3. SpringMVC 把上述对象传入目标方法的参数. @RequestMapping("/testModelAttribute") public String testModelAttribute(User user){ System.out.println("修改: " + user); return SUCCESS; } (输出数据:1 Tom 56789) 例2: ——————————————————————————————— * 源代码分析的流程 * 1. 调用 @ModelAttribute 注解修饰的方法. 实际上把 @ModelAttribute 方法中 Map 中的数据放在了 implicitModel 中. * 2. 解析请求处理器的目标参数, 实际上该目标参数来自于 WebDataBinder 对象的 target 属性 * 1). 创建 WebDataBinder 对象: * ①. 确定 objectName 属性: 若传入的 attrName 属性值为 "", 则 objectName 为类名第一个字母小写. * *注意: attrName. 若目标方法的 POJO 属性使用了 @ModelAttribute 来修饰, 则 attrName 值即为 @ModelAttribute * 的 value 属性值 * * ②. 确定 target 属性: * > 在 implicitModel 中查找 attrName 对应的属性值. 若存在, ok * > *若不存在: 则验证当前 Handler 是否使用了 @SessionAttributes 进行修饰, 若使用了, 则尝试从 Session 中 * 获取 attrName 所对应的属性值. 若 session 中没有对应的属性值, 则抛出了异常. * > 若 Handler 没有使用 @SessionAttributes 进行修饰, 或 @SessionAttributes 中没有使用 value 值指定的 key * 和 attrName 相匹配, 则通过反射创建了 POJO 对象 *(简单来说attrName属性为名字,target属性为对应的值或者对象) * 2). SpringMVC 把表单的请求参数赋给了 WebDataBinder 的 target 对应的属性. *(会用表单传来的值对原来的target属性对应的值进行更新) * 3). *SpringMVC 会把 WebDataBinder 的 attrName 和 target 给到 implicitModel. * 近而传到 request 域对象中. * 4). 把 WebDataBinder 的 target 作为参数传递给目标方法的入参. ——————————————————————————————— 八. 重定向和转发
- 一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理
- 如果返回的字符串中带 forward: 或者 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和redirect: 当成指示符,其后的字符串作为 URL 来处理
https://blog.csdn.net/sinat_35626559/article/details/79374590 九. <mvc:annotation-driven/> 配置mvc:annotation-driven就是开启了注解驱动,Spring知道了我们开启了注解驱动后就可以通过context:component-scan/标签的配置,会自动为我们将扫描到的@Component,@Controller,@Service,@Repository等注解标记的组件注册到工厂中,来处理我们的请求。 他其中的一些标签:
- <mvc:default-servlet-handler />
- <mvc:view-controller />
- 数据格式化(配置<mvc:annotation-driven/>就可以)
- @Vaild——数据校验
—————————————————————————————————— 例: public class User implements Serializable { @NotNull(message = "uid不能为空") @Min(value = 1, message = "pid必须为正整数") private Long uid; @NotBlank(message = "userName不能为空") private String userName; @NotBlank(message = "address 不能为空") private String address; // getter/setter } @RequestMapping("/user/saveUser") public String saveUser(@Valid User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { // 打印全部的错误信息 for (ObjectError error : bindingResult.getAllErrors()) { System.out.println(error.getDefaultMessage()); } } // 返回第一条的错误信息 if (bindingResult.hasErrors()) { String msg=bindingResult.getAllErrors().get(0).getDefaultMessage(); return msg; } }
并且,校验的结果会被保存在被校验入参对象(上文对应的是user)之后的 BindingResult 或Errors 入参中(需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参) — Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或getFieldErrors(String field) —BindingResult 扩展了 Errors 接口 其常用方法: -getAllErrors(返回的是error数组) -getDefaultMessage()(返回的是设置的错误提示信息) 错误信息不仅可以存在Error或BindingResult对象中,还会保存到“隐含模型”,隐含模型会暴露给JSP,所以在JSP中可以获取错误信息 通过: <form:errors path=“xxx”>显示错误消息 例:
<style></style>