传到controller层中的数据 如果是list集合不能直接放到形参
数组可以
参数如果是日期类型需要进行参数的转换
springmvc.xml中
<!-- 开启注解驱动 -->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
<!-- 配置conveter转换工厂 -->
<bean id="conversionServiceFactoryBean"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<!-- 日期转换器 -->
<bean class="com.wind.conversion.DateConverter"></bean>
</list>
</property>
</bean>
添加一个类
//日期转换器
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String arg0) {
if(null!=arg0){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return df.parse(arg0);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
这样就完成了不同类型的转换
springmvc与struts2的不同
1.springmvc的入口是一个servlet前端控制器,struts2入口是一个filter过滤器。
2.springmvc是基于方法开发的,一个方法对应一个url,一般是单例模式,参数在方法的形参上,struts2基于类开发,多例 参数在类的成员变量
3.springmvc没有值栈
关于@RequestMapping()的使用
1.添加前缀
@Controller
@RequestMapping("item")
//添加前缀
public class ItemController {
@RequestMapping(value="updateItems.action")
public String updateItems(QueryVo vo){
service.updateItems(vo);
return "success";
}
}
地址:http://127.0.0.1:8080/springmvc/item/updateItems.action
2.添加请求方法限定
@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})
controller的方法返回值
一般用两个一个是String 最常用的方法
另一个是ajax时候用的 返回值是void 也就是说不用跳转
不过ajax的话会有具体的做法
// 修改商品成功后,重定向到商品编辑页面
// 重定向后浏览器地址栏变更为重定向的地址,
// 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
// 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
return "redirect:/itemEdit.action?itemId=" + item.getId();
// 修改商品成功后,继续执行另一个方法
// 使用转发的方式实现。转发后浏览器地址栏还是原来的请求地址,
// 转发并没有执行新的request和response,所以之前的请求参数都存在
return "forward:/itemEdit.action";
异常处理器
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理
简单的就是说直接把异常都抛到前端控制器
前端控制器拿着异常区找异常处理器
首先写一个自定义异常的类
再写一个自定义异常处理器类
再在springmvc中配置bean 添加异常处理器类
自定义异常类
//自定义异常类
public class MyException extends Exception {
private String message;
public MyException(String message) {
super();
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
自定义异常处理器
public class ItemHandlerException implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mav = new ModelAndView();
if(ex instanceof MyException){
mav.addObject("error", ex.getMessage());
}else{
mav.addObject("error", "未知异常");
}
mav.setViewName("error");
return mav;
}
}
springmvc.xml中加入
<!-- 异常处理器 -->
<bean class="com.wind.exception.ItemHandlerException"></bean>
完成
上传图片
先加入两个包 io fileupload包
然后在springmvc.xml中加入
文件上传解析器
<!-- 文件上传,id必须设置为multipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置文件上传大小 -->
<property name="maxUploadSize" value="5000000" />
</bean>
设置表单可以进行文件上传
<form id="itemForm" action="" method="post" enctype="multipart/form-data">
<input type="file" name="pictureFile"/>
在controller中加入形参
@RequestMapping(value="/updateItemsByid.action")
public String updateItem(Items item,MultipartFile pictureFile) throws IllegalStateException, IOException{
String name = UUID.randomUUID().toString().replaceAll("-", "");
//获得后缀
String ext = FilenameUtils.getExtension(pictureFile.getOriginalFilename());
//保存文件到本地
pictureFile.transferTo(new File("D:\\MyEclipse workspace 2014\\ziang\\src\\main\\webapp\\uploadedImages\\"+name+"."+ext));
item.setPic(name + "." + ext);
service.updateItemsByid(item);
return "redirect:/itemEdit.action?id="+item.getId();
}
在页面上
<img src="${pageContext.request.contextPath }/uploadedImages/${item.pic}" width=100 height=100/>
json数据交互
jsp中
<script type="text/javascript">
$(document)
.ready(
function() {
var params = '{"id": 1,"name": "测试商品","price": 99.9,"detail": "测试商品描述","pic": "123456.jpg"}';
$
.ajax({
url : "${pageContext.request.contextPath }/json.action",
data : params,
contentType : "application/json;charset=UTF-8",
type : "post",
dataType : "json",
success : function(data) {
alert(data.name)
}
})
})
</script>
其中controller方法中
//json数据交互
@RequestMapping(value="/json.action")
public @ResponseBody Items json(@RequestBody Items items){
System.out.println(items);
return items;
}
@RequestBody 把json字符串转换成java对象
@ResponseBody 把Java对象转换成json字符串
RESTful
!!!!!!! 一定要在web.xml中前端控制器 的
<url-pattern>/</url-pattern>
不然用不了
配置成这个后静态资源也会拦截所以要在
springmvc.xml中加入
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />
mapping:映射
location:本地资源路径,注意必须是webapp根目录下的路径。
两个*,它表示映射resources/下所有的URL,包括子路径(即接多个/)
拦截器
先定义拦截器类 实现HandlerInterceptor接口
public class HandlerInterceptor1 implements HandlerInterceptor {
@Override
//方法执行前
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("方法执行前");
return false;
}
@Override
//方法执行后
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("方法执行后");
}
@Override
//视图返回后调用
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("视图返回后");
}
}
在springmvc.xml中配置拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置第一个拦截器 -->
<mvc:interceptor>
<!-- 拦截所有请求 -->
<mvc:mapping path="/**" />
<!-- 拦截器类 -->
<bean class="com.wind.interceptor.HandlerInterceptor1"></bean>
</mvc:interceptor>
<!-- 配置第二个拦截器 -->
<mvc:interceptor>
<!-- 拦截所有请求 -->
<mvc:mapping path="/**" />
<!-- 拦截器类 -->
<bean class="com.wind.interceptor.HandlerInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
一个登录拦截的demo
controller中应该有这样的方法
//跳转到登录界面
@RequestMapping(value="/login.action",method=RequestMethod.GET)
public String login(){
return "login";
}
//登录
@RequestMapping(value="/login.action",method=RequestMethod.POST)
public String login(String name,HttpServletRequest request){
request.getSession().setAttribute("USER_NAME", name);
return "redirect:/getItemList.action";
}
拦截器中
@Override
//方法执行前
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("方法执行前");
String requestURI = request.getRequestURI();
if(requestURI.contains("/login")){
return true;
}else{
String attribute = (String) request.getSession().getAttribute("USER_NAME");
if(null==attribute){
response.sendRedirect(request.getContextPath()+"/login.action");
/*request.getRequestDispatcher("").forward(request, response);*/
return false;
}else{
return true;
}
}
}