请求与响应
参数绑定
可以被注入的类型: HttpServletRequest, HttpServletResponse, HttpSession, Principal, Locale, InputStream, Reader, OutputStream, Writer, String, StringBuffer, Pojo, Date, List, Map, Array, Model, ModelMap等等
转换服务
转换服务为参数绑定时,处理数据类型的转换。
DefaultConversionService:默认的类型转换服务实现
DefaultFormattingConversionService:带数据格式化支持的类型转换服务实现,一般使用该服务实现即可。
springmvc在开启注解驱动,注册了很多Converter的实现类,但是如果不能满足需求,可以自定义转换器。具体如下:
//实现Converter接口
public class MyDateConverter implements Converter<String, Date>{
//重写convert方法
@Override
public Date convert(String str) {
SimpleDateFormat sdf;
Pattern pattern1=Pattern.compile("^\\d{4}年\\d{1,2}月\\d{1,2}日$");
Pattern pattern2=Pattern.compile("^\\d{1,2}-\\d{1,2}-\\d{4}$");
try {
if(pattern1.matcher(str).matches()){
sdf=new SimpleDateFormat("yyyy年MM月dd日");
return sdf.parse(str);
}
if(pattern2.matcher(str).matches()){
sdf=new SimpleDateFormat("MM-dd-yyyy");
return sdf.parse(str);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
将自定义的转换器添加到springmvc转换服务中
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.hemi.controller.converter.MyDateConverter"/>
</list>
</property>
</bean>
注意:
1、如果是单纯的日期格式转换可以使用@DateTimeFormat来实现
@DateTimeFormat(pattern="yyyy年MM月dd日")
private Date date;
2、上面的转换只能处理url参数和请求体参数,如果是json中的日期格式转换,请使用@JsonFormat注解,请看下面的json部分。
json
1、json数据发送
后台:
1、@RequestBody
2、jackson的3个jar包
@RequestMapping("jsonToBean")
@ResponseBody
public User jsonToBean(@RequestBody User user){
return user;
}
前台:
1、contentType:appliation/json;charset=utf-8
2、JSON.stringify(json),
var json={username:"lisi",password:"123"};//定义json对象
$(function(){
$("#btn").click(function(){
$.ajax({
url:"/springmvc/jsonToBean",
type:"post",
contentType:"application/json;charset=utf-8",
//js原生的一个将json对象转成json字符串的工具类
data:JSON.stringify(json),
dataType:"text",
success:function(data){
$("#content").html(data);
}
});
});
});
2、解决json日期格式化问题
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date date;
3、解决json写入@ResponseBody后出现中文乱码的问题
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
视图与模型
视图
springmvc.xml配置
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
//返回的字符串就是视图名称,提前是在springmvc.xml中配置了后缀名
@RequestMapping("view1")
public String view1(){
return "formString";
}
//如果返回返回值,那么默认视图名为请求地址(约定优于配置原则)
@RequestMapping("formString")
public void view2(){}
数据模型
//Model的本质就是map集合,视图解析器会将Model中的数据放到request域对象中
//原始的写法,使用ModelAndView
@RequestMapping("model1")
public ModelAndView model1(){
ModelAndView mav=new ModelAndView();
mav.addObject("user", new User("lisi","123"));
mav.setViewName("model1");//如果这句不写,那么使用约定的视图名
return mav;
}
//简化了上面的写法
@RequestMapping("model2")
public String model2(Model model){
model.addAttribute("username", new User("lisi","123"));
return "model1";
}
//再简化了上面的写法,如果没有返回视图名,那么默认使用请求地址作为视图名
@RequestMapping("model3")
public void model3(Model model){
model.addAttribute("user", new User("lisi","123"));
}
//------------------综合--------------------
@RequestMapping("model4")
public void model4(Model model,User user){
//将user添加到Model中
model.addAttribute("user", user);
}
//简化上面的写法
@RequestMapping("model5")
public void model5(@ModelAttribute User user){//直接将参数绑定好后的user添加到Model中
}
@ModelAttribute("user")
//将返回值暴露为模型数据,因为没有@RequestMapping注解,所以该方法不是处理器,它在每个处理器之前执行
public User getUser(){
return new User("zhangsan", "123");
}
文件上传下载
文件上传
1、基本步骤
1、handler参数添加@RequestParam MultipartFile multipart
@RequestParam(name="user_photo",required=false) MultipartFile multipart
2、调用MultipartFile的transforTo(file)的方法,将文件写入到本地
3、springmvc.xml文件配制CommonsMultipartResolver视图
4、配置静态资源文件访问路径
方式一:
<mvc:resources location="/statics/" mapping="/statics/**"></mvc:resources>
方式二:使用servlet容器默认的DefaultServlet
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
方式三:原理与方式二一致
<mvc:default-servlet-handler />
5、上传文件的jsp
2、注意问题
一、配置静态资源文件访问路径
如果不配置,会出现404异常
二、上传文件的路径
String path = req.getServletContext().getRealPath("statics" + File.separator + "uploadfile");
如果项目没有发布到tomcat服务器中,那么默认是在eclipse的对应项目目录中,这样导致图片找不到路径
解决方法:
1、将项目发布到tomcat,但是每次重新加载项目或者重启服务器就会删除已上传的文件
2、上传到一个统一的文件夹,项目引用该文件夹下的文件,这样不会被迫删除已有文件
<Context path="/statics" docBase="E:/download" reloadable="true" crossContext="true" />
<param-name>listings</param-name>
<param-value>true</param-value>
3、上传到其他http服务器上,例如nginx服务器,推荐!
文件下载
resp.setContentType("application/force-download");
resp.addHeader("Content-Disposition", "attachment;filename=" + filename);
byte[] byteArray = FileUtils.readFileToByteArray(file);
resp.getOutputStream().write(byteArray);
拦截器
自定义拦截器,实现HandlerInterceptor接口,并重写三个方法
public class MyInterceptor implements HandlerInterceptor {
preHandle(){}//执行Handler之前,返回true,则继续进行,返回false则中断请求
postHandle(){}//执行Handler时
afterCompletion(){}//执行Handler之后
}
将自定义拦截器,添加到springmvc的拦截体系中
<mvc:interceptors>
<mvc:interceptor>
<!--拦截器的请求-->
<mvc:mapping path="/**"/>
<!--放行的请求,即公开的地址-->
<mvc:exclude-mapping path="/login/**"/>
<bean class="com.hemi.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>