本文主要讲解的知识点以下:html
咱们在Controller使用方法参数接收值,就是把web端的值给接收到Controller中处理,这个过程就叫作参数绑定...java
从上面的用法咱们能够发现,咱们可使用request对象、Model对象等等,实际上是不是能够随便把参数写上去都行???其实并非的...web
Controller方法默认支持的参数类型有4个,这4个足以支撑咱们的平常开发了spring
通常地,咱们要用到自定义的参数绑定就是上面所讲的日期类型转换以及一些特殊的需求....对于日常的参数绑定,咱们是无需使用转换器的,SpringMVC就已经帮咱们干了这个活了...微信
在上一篇咱们已经简单介绍了怎么把字符串转换成日期类型了【使用的是WebDataBinder方式】...其实那是一个比较老的方法,咱们可使用SpringMVC更推荐的方式...session
在上次把字符串转换成日期类型,若是使用的是WebDataBinder方式的话,那么该转换仅仅只能在当前Controller使用...若是想要所有的Controller都可以使用,那么咱们可使用WebBindingInitializer方式mvc
若是想多个controller须要共同注册相同的属性编辑器,能够实现PropertyEditorRegistrar接口,并注入webBindingInitializer中。app
实现接口编辑器
public class CustomPropertyEditor implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"), true));
}
}
复制代码
注入到webBindingInitializer中ide
<!-- 注册属性编辑器 -->
<bean id="customPropertyEditor" class="cn.itcast.ssm.controller.propertyeditor.CustomPropertyEditor"></bean>
<!-- 自定义webBinder -->
<bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<!-- propertyEditorRegistrars用于属性编辑器 -->
<property name="propertyEditorRegistrars">
<list>
<ref bean="customPropertyEditor" />
</list>
</property>
</bean>
<!-- 注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!-- 在webBindingInitializer中注入自定义属性编辑器、自定义转换器 -->
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
复制代码
上面的方式是对象较老的,如今咱们通常都是实现Converter接口来实现自定义参数转换...咱们就来看看实现Converter比上面有什么好
配置日期转换器
public class CustomDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
//进行日期转换
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
复制代码
配置去除字符串转换器
public class StringTrimConverter implements Converter<String, String> {
@Override
public String convert(String source) {
try {
//去掉字符串两边空格,若是去除后为空设置为null
if(source!=null){
source = source.trim();
if(source.equals("")){
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return source;
}
}
复制代码
从上面能够得出,咱们想要转换什么内容,就直接实现接口,该接口又是支持泛型的,阅读起来就很是方便了...
<!-- 转换器 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
<bean class="cn.itcast.ssm.controller.converter.StringTrimConverter"/>
</list>
</property>
</bean>
<!-- 自定义webBinder -->
<bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<!-- 使用converter进行参数转 -->
<property name="conversionService" ref="conversionService" />
</bean>
<!-- 注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!-- 在webBindingInitializer中注入自定义属性编辑器、自定义转换器 -->
<property name="webBindingInitializer" ref="customBinder"></property>
</bean>
复制代码
若是是基于<mvc:annotation-driven>
的话,咱们是这样配置的
<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
<!-- conversionService -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 转换器 -->
<property name="converters">
<list>
<bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
<bean class="cn.itcast.ssm.controller.converter.StringTrimConverter"/>
</list>
</property>
</bean>
复制代码
咱们通常使用的参数绑定都有遵循的规则:方法参数名要与传递过来的name属性名相同。
在默认的状况下,只有名字相同,SpringMVC才会帮咱们进行参数绑定...
若是咱们使用@RequestParam注解
的话,咱们就可使方法参数名与传递过来的name属性名不一样...
该注解有三个变量
例子:咱们的方法参数叫id,而页面带过来的name属性名字叫item_id,必定须要该参数
public String editItem(@RequestParam(value="item_id",required=true) String id) {
}
复制代码
Controller方法的返回值其实就几种类型,咱们来总结一下....
其实数据回显咱们如今的话就一点也不陌生了....咱们刚使用EL表达式的时候就已经学会了数据回显了,作SSH项目的时候也有三圈问题的数据回显...
在页面上数据回显本质上就是获取reqeust域的值..
而在咱们SpringMVC中,咱们是使用Model来把数据绑定request域对象中的
通常地咱们都是使用model.addAttribute()的方式把数据绑定到request域对象中...其实SpringMVC还支持注解的方式
@ModelAttribute
注解咱们能够将请求的参数放到Model中,回显到页面上
上面这种用法和model.addAttribute()的方式是没啥区别的,也体现不了注解的方便性...
而若是咱们要回显的数据是公共的话,那么咱们就可以体会到注解的方便性了,咱们把公共须要显示的属性抽取成方法,将返回值返回就好了。
那咱们就不用在每个controller方法经过Model将数据传到页面。
咱们使用Struts2的时候,以为Struts2的文件上传方式比传统的文件上传方式好用多了...
既然咱们正在学习SpringMVC,那么咱们也看一下SpringMVC到底是怎么上传文件的...
在此次,咱们并非把图片上传到咱们的工程目录中...
那为啥不将图片直接上传到咱们的工程目录中呢???咱们仔细想一想,按照咱们以前的作法,直接把文件上传到工程目录,而咱们的工程目录是咱们写代码的地方 ...每每咱们须要备份咱们的工程目录。
若是把图片都上传到工程目录中,那么就很是难以处理图片了...
所以,咱们须要配置Tomcat的虚拟目录来解决,把上传的文件放在虚拟目录上...
又值得注意的是,Idea使用的Tomcat并不能使用传统的配置方式,也就是修改server.xml方式来配置虚拟目录,在Idea下好像不支持这种作法...
有兴趣的同窗能够去测试一下:
那么我在网上已经找到了对应的解决办法,就是若是在idea上配置虚拟目录
检测是否配置成功:
在SpringMVC中文件上传须要用到的jar包
配置文件上传解析器
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
复制代码
测试的JSP
<%-- Created by IntelliJ IDEA. User: ozc Date: 2017/8/11 Time: 9:56 To change this template use File | Settings | File Templates. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试文件上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload.action" method="post" enctype="multipart/form-data" >
<input type="file" name="picture">
<input type="submit" value="submit">
</form>
</body>
</html>
复制代码
值得注意的是,在JSP的name属性写的是picture,那么在Controller方法参数的名称也是要写picture的,不然是获取不到对应的文件的..
@Controller
public class UploadController {
@RequestMapping("/upload")
//MultipartFile该对象就是封装了图片文件
public void upload(MultipartFile picture) throws Exception {
System.out.println(picture.getOriginalFilename());
}
}
复制代码
若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y