2.6 日期类型格式转换
- 声明自定义的转换格式并覆盖系统转换格式
<!--5.启用自定义Converter--> <mvc:annotation-driven conversion-service="conversionService"/> <!--1.设定格式类型Converter,注册为Bean,受SpringMVC管理--> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!--2.自定义Converter格式类型设定,该设定使用的是同类型覆盖的思想--> <property name="formatters"> <!--3.使用set保障相同类型的转换器仅保留一个,避免冲突--> <set> <!--4.设置具体的格式类型--> <bean class="org.springframework.format.datetime.DateFormatter"> <!--5.类型规则--> <property name="pattern" value="yyyy-MM-dd"/> </bean> </set> </property> </bean>
- 日期类型格式转换(简化版)
名称: @DateTimeFormat
类型: 形参注解、成员变量注解
位置:形参前面 或 成员变量上方
作用:为当前参数或变量指定类型转换规则
范例:
public String requestParam12(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){ System.out.println("date="+date); return "page.jsp"; }
@DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday;
- 注意:依赖注解驱动支持 ,这句话永远放在配置文件最上面!!!
<mvc:annotation-driven />
2.7 自定义类型转换器
- 自定义类型转换器,实现Converter接口,并制定转换前与转换后的类型
<!--1.将自定义Converter注册为Bean,受SpringMVC管理--> <bean id="myDateConverter" class="com.itheima.converter.MyDateConverter"/> <!--2.设定自定义Converter服务bean--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!--3.注入所有的自定义Converter,该设定使用的是同类型覆盖的思想--> <property name="converters"> <!--4.set保障同类型转换器仅保留一个,去重规则以Converter<S,T>的泛型为准--> <set> <!--5.具体的类型转换器--> <ref bean="myDateConverter"/> </set> </property> </bean>
//自定义类型转换器,实现Converter接口,接口中指定的泛型即为最终作用的条件 //本例中的泛型填写的是String,Date,最终出现字符串转日期时,该类型转换器生效 public class MyDateConverter implements Converter<String, Date> { //重写接口的抽象方法,参数由泛型决定 public Date convert(String source) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; //类型转换器无法预计使用过程中出现的异常,因此必须在类型转换器内部捕获,不允许抛出,框架无法预计此类异常如何处理 try { date = df.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } }
通过注册自定义转换器,将该功能加入到SpringMVC的转换服务ConverterService中
<!--开启注解驱动,加载自定义格式化转换器对应的类型转换服务--> <mvc:annotation-driven conversion-service="conversionService"/>
注意事项:<mvc:annotation-driven>
标签要放在spring-mvc配置文件的最前面
3 响应
3.1 页面跳转
使用ResponseBody的坑
ResponseBody原理:
3.1.1 返回字符串形式
- 转发(默认)
@RequestMapping("/showPage1") public String showPage1() { System.out.println("user mvc controller is running ..."); return "forward:/WEB-INF/page.jsp"; }
- 重定向
@RequestMapping("/showPage2") public String showPage2() { System.out.println("user mvc controller is running ..."); return "redirect:/WEB-INF/page.jsp"; }
将相同的路径抽取到配置文件中:
展示页面的保存位置通常固定,且结构相似,可以设定通用的访问路径,简化页面配置格式
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> /bean>
public String showPage3() { return "page"; }
原理图
如果未设定了返回值,使用void类型,则默认使用访问路径作页面地址的前缀后缀
//最简页面配置方式,使用访问路径作为页面名称,省略返回值 @RequestMapping("/showPage5") public void showPage5() { System.out.println("user mvc controller is running ..."); }
3.1.2 返回ModelAndView
- 方式一:使用HttpServletRequest类型形参进行数据传递
@RequestMapping("/showPageAndData1") public String showPageAndData1(HttpServletRequest request) { request.setAttribute("name","itheima"); return "page"; }
- 方式二:使用Model类型形参进行数据传递
@RequestMapping("/showPageAndData2") public String showPageAndData2(Model model) { model.addAttribute("name","itheima"); Book book = new Book(); book.setName("SpringMVC入门实战"); book.setPrice(66.6d); model.addAttribute("book",book); return "page"; }
- 方式三:使用ModelAndView类型形参进行数据传递,将该对象作为返回值传递给调用者
//使用ModelAndView形参传递参数,该对象还封装了页面信息 @RequestMapping("/showPageAndData3") public ModelAndView showPageAndData3(ModelAndView modelAndView) { //ModelAndView mav = new ModelAndView(); 替换形参中的参数 Book book = new Book(); book.setName("SpringMVC入门案例"); book.setPrice(66.66d); //添加数据的方式,key对value modelAndView.addObject("book",book); //添加数据的方式,key对value modelAndView.addObject("name","Jockme"); //设置页面的方式,该方法最后一次执行的结果生效 modelAndView.setViewName("page"); //返回值设定成ModelAndView对象 return modelAndView; }
3.2 返回json数据
- 方式一:基于response返回数据的简化格式,返回JSON数据
//使用jackson进行json数据格式转化 @RequestMapping("/showData3") @ResponseBody public String showData3() throws JsonProcessingException { Book book = new Book(); book.setName("SpringMVC入门案例"); book.setPrice(66.66d); ObjectMapper om = new ObjectMapper(); return om.writeValueAsString(book); }
- 使用SpringMVC提供的消息类型转换器将对象与集合数据自动转换为JSON数据
//使用SpringMVC注解驱动,对标注@ResponseBody注解的控制器方法进行结果转换,由于返回值为引用类型,自动调用jackson提供的类型转换器进行格式转换 @RequestMapping("/showData4") @ResponseBody public Book showData4() { Book book = new Book(); book.setName("SpringMVC入门案例"); book.setPrice(66.66d); return book; }
需要手工添加信息类型转换器
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean
- 方式三:使用SpringMVC注解驱动简化配置
<!--开启springmvc注解驱动,对@ResponseBody的注解进行格式增强,追加其类型转换的功能,具体实现由MappingJackson2HttpMessageConverter进行--> <mvc:annotation-driven/>
注意:该标签写在配置文件最上面,扫完包马上写该注解
总结:
4 Servlet相关接口-Servlet相关接口替换方案
HttpServletRequest / HttpServletResponse / HttpSession
- SpringMVC提供访问原始Servlet接口API的功能,通过形参声明即可
@RequestMapping("/servletApi") public String servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session){ System.out.println(request); System.out.println(response); System.out.println(session); request.setAttribute("name","itheima"); System.out.println(request.getAttribute("name")); return "page.jsp"; }
- Head数据获取
名称: @RequestHeader
类型: 形参注解
位置:处理器类中的方法形参前方
作用:绑定请求头数据与对应处理方法形参间的关系
范例:
@RequestMapping("/headApi") public String headApi(@RequestHeader("Accept-Language") String head){ System.out.println(head); return "page.jsp"; }
- Cookie数据获取
名称: @CookieValue
类型: 形参注解
位置:处理器类中的方法形参前方
作用:绑定请求Cookie数据与对应处理方法形参间的关系
范例:
@RequestMapping("/cookieApi") public String cookieApi(@CookieValue("JSESSIONID") String jsessionid){ System.out.println(jsessionid); return "page.jsp"; }
- Session数据获取
名称: @SessionAttribute
类型: 形参注解
位置:处理器类中的方法形参前方
作用:绑定请求Session数据与对应处理方法形参间的关系
范例:
@RequestMapping("/sessionApi") public String sessionApi(@SessionAttribute("name") String name){ System.out.println(name); return "page.jsp"; }
Session数据设置(了解)
名称: @SessionAttributes
类型: 类注解
位置:处理器类上方
作用:声明放入session范围的变量名称,适用于Model类型数据传参
范例:
@Controller @SessionAttributes(names={"name"}) public class ServletController { @RequestMapping("/setSessionData2") public String setSessionDate2(Model model) { model.addAttribute("name", "Jock2"); return "page.jsp"; } }
注解式参数数据封装底层原理
数据的来源不同,对应的处理策略要进行区分
Head
Cookie
Session
- SpringMVC使用策略模式进行处理分发
顶层接口: HandlerMethodArgumentResolver
实现类: ……
5 面试题
MVC是什么
MVC全名是Model View Controller,是一种软件设计模式。其中可分为模型(model)-视图(view)-控制器(controller)三要素
SpringMVC的执行流程