SpringMVC—— 视图视图解析器自定义转换器格式化转换
Posted Johnny*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC—— 视图视图解析器自定义转换器格式化转换相关的知识,希望对你有一定的参考价值。
视图
先前返回String类型只能返回单个视图,没有数据。如果想要返回的页面带有数据。可以使用ModelAndView、Model、Map、ModelMap。此类将数据放在了request域中。
带有数据的视图
package com.johnny.controller;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.johnny.entity.Student;
@Controller
public class MVController {
@RequestMapping("testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView mv = new ModelAndView("result"); //设置视图: 视图解析器会自动解析成 /views/result.jsp
Student student = new Student();
student.setId(1);
student.setName("johnny");
mv.addObject("student1", student);
return mv;
}
@RequestMapping("testModel")
public String testModel(Model model) {
Student student = new Student();
student.setId(2);
student.setName("feizai");
model.addAttribute("student2", student);
return "result";
}
@RequestMapping("testMap")
public String testMap(Map<String,Object> m) {
Student student = new Student();
student.setId(3);
student.setName("zs");
m.put("student3", student);
return "result";
}
@RequestMapping("testModelMap")
public String testModelMap(ModelMap mm) {
Student student = new Student();
student.setId(4);
student.setName("ww");
mm.addAttribute("student4", student);
return "result";
}
/*
@RequestMapping("testModelAttribute")
public String testModelMap(ModelMap mm) {
Student student = new Student();
student.setId(4);
student.setName("ww");
mm.addAttribute("student4", student);
return "result";
}*/
}
SessionAttributes注解
@SessionAttributes(value="student4") //如果要在request中存放student4对象,则同时将该对象 放入session域中
@SessionAttributes(types= {Student.class,Address.class}) //如果要在request中存放Student类型的对象,则同时将该类型对象 放入session域中
@Controller
public class MVController {
@RequestMapping("testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView mv = new ModelAndView("result"); //设置视图: 视图解析器会自动解析成 /views/result.jsp
Student student = new Student();
student.setId(1);
student.setName("johnny");
mv.addObject("student1", student);//框架自动帮我们将该对象放入 request域中
return mv;
}
}
ModelAttribute 注解
该注解通常在更新操作时使用
//在任何一次请求前都会先执行@ModelAttribute修饰的方法
@ModelAttribute
public void queryStudentById(Map<String,Object> m) {
//模拟后端查询到的数据
Student student = new Student();
student.setId(4);
student.setName("ww");
student.setAge(28);
m.put("student", student); //约定:map的可以是该类首字母小写
//也可以通过@ModelAttribute("指定对象名字")
//@ModelAttribute修饰的方法 将map中的对象赋值给@ModelAttribute()修饰的方法
}
@RequestMapping("testModelAttribute")
public String testModelAttribute(@ModelAttribute()Student student) {
System.out.println( student.getId()+" "+student.getName()+" "+student.getAge());
return "result";
}
前端testMV.jsp
<form action="testModelAttribute">
id:<input name="id" >
name:<input name="name" >
age:<input name="age" >
<input type="submit" value="提交">
</form>
视图解析器
视图的顶级接口:View
对应视图解析器:ViewResolver
常见的视图和视图解析器:
InternalResourceView、InternalResourceViewResolver
springMVC解析jsp时 会默认使用InternalResourceView,
如果发现Jsp中包含了jstl语言相关的内容,则自动转为JstlView。
如果想要SpringMVC实现一个jsp页面直接跳转到另一个jsp而不用通过controller。 例如从index.jsp 到 succes.jsp :在springmvc.xml文件中加入:
<!--view-name会被视图解析器 加上前缀、后缀 -->
<mvc:view-controller path="testJspWithoutController" view-name="success"/>
以上注解 ,会让所有的请求转入mvc:..中匹配映射地址(testJspWithoutController),而会忽略掉@RequsetMapping注解。如果想让 @RequsetMapping(“a”) 和<mvc:view-controller path=“testJspWithoutController” view-name=“success”/>共存,则需要加入一个注解:
<!-- 开启SpringMVC注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
指定跳转方式
指定跳转方式,转发到/views/success.jsp视图。
return "forward:/views/success.jsp";
注意:如果是 return “forward:success”,SpringMvc会去匹配RequestMapping值为success的方法。
forward: redirect: ,需要注意 此种方式,不会被视图解析器加上前缀(/views)、后缀(.jsp)
处理静态资源
静态资源包括: html css js 图片 视频
在SpringMVC中如果直接链接请求静态资源会发生404错误,因为之前将所有的请求 通过通配符“\\” 拦截,进而交给 SPringMVC的入口DispatcherServlet去处理,SpringMVC会去匹配相应controller的requestMapping方法。找不到自然是404.
解决方案:
如果是 需要mvc处理的,则交给@RequsetMapping("")对应的方法处理;如果不需要springmvc处理,则使用 tomcat默认的Servlet(DefaultServlet)去处理。
tomcat默认的Servlet去处理:如果有 对应的请求拦截,则交给相应的Servlet去处理;如果没有对应的servlet,则直接访问。
实现方法,springmvc.xml中增加两个注解配置:
<!-- 开启SpringMVC注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 默认servlet:SpringMVC没有相应requestMapping时会转交给Tomcat默认的servlet处理 -->
<mvc:default-servlet-handler/>
自定义转换器
自定义转换器类实现Converter的convert方法
package com.johnny.controller;
import org.springframework.core.convert.converter.Converter;
import com.johnny.entity.Student;
public class MyConverter implements Converter<String,Student>{
/**
* 实现Convert接口的convert方法
* 该方法将String类型参数 封装为Student
*/
public Student convert(String source) {
String[] strings = source.split("-");
Student student = new Student();
student.setId(Integer.parseInt(strings[0]));
student.setAge(Integer.parseInt(strings[1]));
student.setName(strings[2]);
return student;
}
}
springmvc.xml文件中增加如下配置:
<!-- 自定义类型转换器 -->
<!-- 1、将自定义类型转换器纳入SpringIOC容器中 -->
<bean id="myConverter" class="com.johnny.controller.MyConverter"/>
<!-- 2、将myConverter在纳入SpringMVC提供的转换器中 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="myConverter"/>
</set>
</property>
</bean>
<!-- 3、将conversionService注册到annotation-driven-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
Controller方法
@RequestMapping("testMyConverter")
public String testMyConverter(@RequestParam("studentInfo") Student student) {
System.out.println(student.getId() +" "+student.getName()+" "+student.getAge());
return "success";
}
测试页面testConverter.jsp
<form action="testMyConverter">
<input name="studentInfo">
<input type="submit" value="提交">
</form>
前端请求testMyConverter与controller的requestMapping 匹配,@RequestParam(“studentInfo”)接受的数据 接受的是前端传递过来的参数:1-22-zs。但是在将该数据赋值给修饰的目的对象Student时,发现类型不匹配。并且两种数据类型刚好是String和Student,正好符合MyConverter 转换器类。
数据格式化
FormattingConversionServiceFactoryBean:既可以实现格式化、又可以实现类型转换
1、 在要格式化的实体类属性上加上注解
该注解保证前端以yyyy-MM-dd形式传值
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
2、 配置
<!-- 自定义类型转换器 -->
<!-- 1、将自定义类型转换器纳入SpringIOC容器中 -->
<bean id="myConverter" class="com.johnny.controller.MyConverter"/>
<!-- 2、将myConverter在纳入SpringMVC提供的转换器中
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="myConverter"/>
</set>
</property>
</bean>
-->
<!-- FormattingConversionServiceFactoryBean类既可完成类型转换也可以实现格式化 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="myConverter"/>
</set>
</property>
</bean>
<!-- 3、将conversionService注册到annotation-driven
-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
3、 controller层
@RequestMapping("testFormatConverter")
public String testFormatConverter(Student student) {
System.out.println(student.getId() +" "+student.getName()+" "+student.getAge()+" "+ student.getBirthday());
return "success";
}
错误信息处理:
public String testFormatConverter(Student student, BindingResult result ,Map<String,Object> map) {
需要验证的数据是 Student中的birthday, SPringMVC要求 如果校验失败 则将错误信息 自动放入 该对象之后紧挨着的 BindingResult中。
即Student student, BindingResult result之间 不能有其他参数。如果要将控制台的错误消息 传到jsp中显示,则可以将 错误消息对象放入request域中,然后 在jsp中 从request中获取。
以上是关于SpringMVC—— 视图视图解析器自定义转换器格式化转换的主要内容,如果未能解决你的问题,请参考以下文章