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—— 视图视图解析器自定义转换器格式化转换的主要内容,如果未能解决你的问题,请参考以下文章

配置视图解析器

Javaweb学习之SpringMVC视图解析器的分析

Javaweb学习之SpringMVC视图解析器的分析

SpringMvc:视图和视图解析器

学习笔记——springMVC中视图及视图解析器对象;视图控制器

SpringMVC视图解析器