@RequestMapping
通过@RequestMapping注解可以定义不同的处理器映射规则。
@RequestMapping(value="item")或@RequestMapping("/item") 只有一个参数时,value可以省略不写,多个参数时,必须写value。value的值是一个数组可以指定多个url,@RequestMapping(value = { "itemList", "itemListAll" })。
如果添加在类上面就是加一个前缀 /product/item
第二个参数是请求方法限定,@RequestMapping(value = "itemList",method = RequestMethod.POST) 只可以post提交,是一个数组 可以写多个来同时支持get和post请求@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST}),如果不写就是所有请求都可以。
Controller方法返回值
1.ModelAndView:可以添加model数据和view页面路径。 不建议使用
2.String:返回页面路径 需要使用model形参携带数据 解耦
@RequestMapping(value={"/haha","/hehe"}) public String hehe(Model model){ model.addAttribute("hehe","hehe"); return "list"; }
3.void:需要使用request转发或response重定向 多用于异步请求
@RequestMapping(value={"/haha","/hehe"}) public void hehe(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("list").forward(request,response); }
4.redirect:重定向一个路径
@RequestMapping(value={"/haha","/hehe"}) public String hehe(){ return "redirect:/product/list"; }
5.forward:转发 处理一个Controller之后继续下一个Controller处理
@RequestMapping(value={"/haha","/hehe"}) public String hehe(){ return "forward:/product/edit"; }
异常处理
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过补货异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
自定义异常类
为了区别不同的异常,通常根据异常类型进行区分,自定义一个系统异常。
package com.david.utils; public class MyException extends Exception { private String message; public MyException() { } public MyException(String message) { this.message = message; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
自定义异常处理器
package com.david.utils; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; public class CustomHandleException implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { String msg; if(e instanceof MyException){ // 如果是自定义异常 msg = e.getMessage(); }else{ //运行时异常 Writer out = new StringWriter(); PrintWriter s = new PrintWriter(out); e.printStackTrace(s); msg = out.toString(); } //记录日志 发送邮件 ModelAndView mav = new ModelAndView(); mav.addObject("msg",msg); mav.setViewName("error"); return mav; } }
配置异常处理器 springmvc.xml
<!-- 配置全局异常处理器 -->
<bean id="customHandleException" class="com.david.utils.CustomHandleException"/>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>500</title> </head> <body> 服务器发生异常 500 ${msg} </body> </html>
测试异常
throw new MyException("自定义异常");
上传图片
1.导入commons-fileupload.jar commons-io.jar两个包
2.配置springmvc.xml
<!-- 文件上传,id必须设置为multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置文件上传大小 --> <property name="maxUploadSize" value="5000000" /> </bean>
3.jsp页面
<form action="/product/upload" method="post" enctype="multipart/form-data"> <input type="file" name="imgFile"> <button type="submit">提交</button> </form>
4.controller
@RequestMapping("/upload") public String upload(MultipartFile imgFile,HttpServletRequest request) throws IOException { // 获取文件名 String fileName = imgFile.getOriginalFilename(); // 获取图片后缀 String extName = fileName.substring(fileName.lastIndexOf(".")); if(extName.equals(".jpg")){ // 项目在容器中实际发布运行的根路径 String realPath=request.getSession().getServletContext().getRealPath("/"); // 自定义的文件名称 String trueFileName=String.valueOf(System.currentTimeMillis())+fileName; // 设置存放图片文件的路径 String path=realPath+"/upload/" +trueFileName; // 开始上传 imgFile.transferTo(new File(path)); } return "list"; }
json数据交互
@RequestBody注解用于获取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为java对象并绑定到Controller方法的参数上。
@ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为制定格式的数据如:xml,json等,通过response响应给客户端。
加入jar包:jackson-annotation.jar jackson-core.jar jackson-databind.jar
@RequestMapping("/add") @ResponseBody public Product add(@RequestBody Product product){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); ProductMapper mapper = ac.getBean(ProductMapper.class); mapper.addProduct(product); return product; }
json请求-contentType要application/json dataType要json
<script src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script> <script> $(function(){ var data = { name:'水果梨', price:'18.4', categoryId:3 }; $.ajax({ url:'/product/add', data:JSON.stringify(data), contentType:'application/json;charset=UTF-8', type:"post", dataType:"json", success:function(data){ console.log(data) } }) }) </script>
springmvc.xml要开启注解
<mvc:annotation-driven />
restful支持
restful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
资源操作:使用post、delete、put、get 分别对应添加,删除,修改,查询不同方法对资源进行操作。
使用restful
查询 www.david.com/item/1 get请求
新增 www.david.com/item post请求
修改 www.david.com/item put请求
删除 www.david.com/item/1 delete请求
1.这种url我们可以使用@RequstMapping("item/{id}") 来声明请求的url {id}是占位符,请求的url可以是item/1 或item/23
2.使用(@PathVariable() Integer id)获取url上的数据
@RequestMapping("item/{id}") public String getItemById(@PathVariable() Integer id){ System.out.print(id); return "list"; }
测试地址:http://localhost:9999/product/item/13
拦截器
springmvc中的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
定义拦截器,实现org.springframework.web.servlet.HandlerInterceptor接口
package com.david.utils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class myInterceptor implements HandlerInterceptor { /** * controller执行前调用此方法 * 返回true表示继续执行,返回false终止执行 这里可以加入登陆校验、权限拦截等 */ @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandler"); return false; } /** * controller执行后但未返回视图前调用此方法 * 这里可在返回用户前对模型数据进行加工处理 比如可以加入共用信息以便页面显示 */ @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.print("postHandle"); } /** * controller执行后且试图返回后调用此方法 * 这里可得到执行controller时的异常信息 也可以记录日志 */ @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.print("afterCompletion"); } }
配置拦截器 springmvc.xml-定义拦截规则即可
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/product/*"/> <bean class="com.david.utils.myInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>