配置页面直接跳转

前面所讲的都是将请求发到controller中,然后在controller中进行转发,但是有时候想要从一个页面直接跳转到另外一个页面,但是也想要经过SpringMVC,而不是直接通过一个链接去跳转。这时候就不需要使用controller了,但是需要在springMVC.xml配置文件中配置,具体配置如下:

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/views/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>
<mvc:view-controller path="testModelMap" view-name="success"/>

上面配置的path是我们的请求路径,view-name是视图地址(是会被视图解析器加上前缀和后缀)

需要注意的是加上了这个注解之后所有想controller都会失效,都会使用这种方式类查找我们的请求路径,如果想要让controller与这种请求方式共存,那么在springMVC配置文件中还需要加上下面的配置才可以

<!-- 此配置是springMVC的基础配置,很多的功能都是需要通过该注解来协调 -->
<mvc:annotation-driven></mvc:annotation-driven>

jsp页面

<form action="testModelMap" method="get">
	<input type="hidden" name="id" value="11">
	<input type="text" name="name" value="">
	<input type="submit">
</form>

可以看到在jsp页面中与之前的请求没有什么区别,但是有一点需要注意的是这里使用的是get请求,如果使用的是post请求后台会报错。

像上面这样配置之后不需要controller层就可以直接跳转了。

设置跳转方式

springMVC中默认使用的请求转发,也就是是地址栏不变,但是数据变了,如果我们想要自己配置跳转方式,可以在返回时加上forward:或者是redirect:前缀。

@RequestMapping(value="testModelMap")
	public String testModelMap(@ModelAttribute("stu")Student student) {
		student.setName(student.getName());
		System.out.println(student.getName());
		return "forward:/views/success.jsp";
//		return "redirect:/views/success.jsp";
	}

如果是自己配置跳转方式需要注意的是在springMvc.xml配置文件中视图解析器配置的自动加上前缀和后缀的功能就会失效,所以需要自己写上文件的全路径以及后缀

设置SpringMVC访问静态资源

所谓的静态资源就是类似于html,css,js以及图片,视频等资源。这些静态资源在SpringMVC中如果想要直接根据路径去寻找,结果是会报404错误,因为在web.xml进项了如下的配置:

<!-- 配置前端控制器 -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<!-- 加载spring核心配置文件 -->
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc.xml</param-value>
  	</init-param>
  </servlet>
  
  <!-- 配置拦截路径 -->
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>                                        
  	<url-pattern>/</url-pattern>
  </servlet-mapping>

servlet-mappingurl-pattern配置了/,也就是意味中springMVC会拦截一切请求,拦截所有的请求之后会将这些请求让DispatcherServlet进行处理,也就是回去找@RequestMapping中配置的路径,显然对于那些静态资源是不会有@RequestMapping路径的,所以就会显示404,出现这个问题的解决办法就是当SpringMVC拦截到的请求有@RequestMapping路径时就交给SpringMVC去处理,但是如果没有匹配到这些路径的时候就交给服务器(tomcat)默认配置的servlet来进行处理即可,因为tomcat中默认的servlet处理的方式是如果能匹配到路径就按照匹配的路径去访问,如果不能匹配到就按照请求的路径去寻找。

具体配置是在SpringMVC.xml配置文件中加上下面的代码:

<!-- 此配置是springMVC的基础配置,很多的功能都是需要通过该注解来协调 -->
	<mvc:annotation-driven></mvc:annotation-driven>
	
	<mvc:default-servlet-handler></mvc:default-servlet-handler>

上面已经说过第一个注解主要是协调作用,如果只是加上了第二个注解,那么就只能访问静态资源,如果想要静态资源和动态资源都可以访问就还需要加上第一个注解。

自定义转换类

student类

package top.twolovelypig.entity;
public class Student {
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return this.id + "," + this.name + ",";
	}
}

之前说只要form表单中name属性值与对象的属性名一致就可以将数据自动保存到一个对象中,其实这里面就有spring内置的类型转换,如果自己想要进行转换就需要通过自定义类来实现。

自定义转换类需要实现Converter

转换类

public class MyConverter implements Converter<String, Student>{
	@Override
	public Student convert(String source) {
		String[] arrStudent = source.split("-");
		Student student = new Student();
		student.setId(Integer.parseInt(arrStudent[0]));
		student.setName(arrStudent[1]);
		return student;
	}
}

jsp代码

<form action="testModelMap" method="get">
	<input type="text" name="studentInfo" >
	<input type="submit">
</form>

需要注意的是这里输入的格式是数字-字符串,因为在转换类中是通过-进行分割的。

SpringMVC.xml

自定义转换类除了需要实现Converter类之外还需要在springMvc.xml配置文件中进行配置。具体配置如下:

<!--1.将自定义的转换器纳入到springIoc容器中  -->
	<bean id="myConverter" class="top.twolovelypig.converter.MyConverter"></bean>
	<!--2.将myConverter纳入SpringMVC提供的转换器Bean  -->
	<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
		<property name="converters">
			<set>
				<ref bean="myConverter"/>
			</set>
		</property>
	</bean>
	<!--3.将conversionService注册到annotation-driven中  -->
	<!-- 此配置是springMVC的基础配置,很多的功能都是需要通过该注解来协调 -->
	<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

controller

@RequestMapping(value="testModelMap")
	public String testModelMap(@RequestParam("studentInfo")Student student) {
		System.out.println(student.getName() + "," + student.getId());
		return "success";
	}

因为name的属性值为studentInfo,与student对象中的属性名称没有相符合的,所以这里是不会自动映射,需要通过@RequestParam注解来显示的配置一下。

数据格式化

比如下面的一句代码就是数据格式化:

SimpleDateForamt sdf = new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss");

SPringMVC提供了很多注解,方便我们数据格式化。
实现步骤:

  • .在SPringMVC.xml配置文件中进行配置
<!-- 配置 数据格式化 注解 所依赖的bean -->
	<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
	</bean>
  • 通过注解使用,这里的注解是加在实体上面的,比如Student实体
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
@NumberFormat(parttern="###,#") 
private int money;

需要注意的是这里所说的数据格式化是对前端页面的数据格式化,比如上面的birthday日期格式化的样式是yyyy-MM-dd形式的,那么从前端穿过的数据如果是类似于2019-01-20那么后台是可以正常接收的,但是如果传过来的是2019/01/20那么后台就会报错,因为不是规定的格式。

错误信息

对于有格式化的字段,可能会出现一些错误,这些错误默认是不在前台展示的,如果想要在前端展示这些错误信息就需要将信息传递到前端进行显示,此时可以使用BindingResult对象,但是需要注意的是该参数的位置必须是在进行了格式化的对象的后面。

public Sting testDateTimeFormat(Student student, BingingResult result, Map<String, Object> map){
    ....
}

假如需要验证的是Student中的birthday字段,SPringMVC要求是如果校验失败,则将错误信息自动放入该对象之后紧挨着的BingingResult对象之中,也就是Student student, BingingResult result之间不能有其他参数。如果需要将错误信息放在jsp显示,则可以将错误信息放入在request中,这里也就是使用第三个参数来实现,因为map中的值会自动被放入在request域中。

SpringMVC通过ajax处理json数据

一般我们通过ajax请求后获取的数据可能是list格式,或者对象,一般都是需要将这些格式转换为json格式后使用,如果是使用SpringMVC的话可以直接通过@ResponseBody注解在解决这个问题,在后台的方法中加上上面所说的注解即可,但是使用这个这个功能需要使用三个jar包,分别是:

  • jackson-annotations.jar
  • jackson-core.jar
  • jackson-databind.jar