1. Controller中向页面传值的几种办法2. Controller中利用Servlet API3. RESTful风格编码4. SpringMVC中处理静态资源5. SpringMVC中的核心组件6. SpringMVC中处理JSON7. SpringMVC中非常处理8. SpringMVC中拦截器9. SpringMVC中的文件上传下载一. Controller向页面通报数据实现的3种方案:

1、ModelAndView

2、Map

3、Model

mvnjsp导入包SpringMVC进修笔记02 Ruby

第一种:

java代码:

@RequestMapping("/edit")public ModelAndView edit(){User user = new User();user.setUsername("用户名!");user.setAge(11);user.setPassword("123");Address address = new Address();address.setProvince("辽宁");address.setCity("葫芦岛");user.setAddress(address);ModelAndView modelAndView = new ModelAndView();//viewname 指定要查找的页面modelAndView.setViewName("user/form");//添加modelAndView添加携带的user数据modelAndView.addObject("user", user);return modelAndView;}

页面显示代码:

/WEB-INF/user/form.jsp

直策应用el表达式!

<form action="/spring-mvc-22/user/add" method="post"&gt; <label for="username">用户名:<input type="text" value="${user.username }" id="username" name="username" /></label><br/> <label for="password">密码:<input type="password" id="password" name="password" /></label><br/> <label for="age">年事:<input type="text" value="${user.age }" name="age" /></label><br/> <label for="address.province">省份:<input type="text" value="${user.address.province }" name="address.province" /></label><br/> <label for="address.city">城市:<input type="text" value="${user.address.city }" name="address.city" /></label><br/> <label for="address.sp.pname">特产名称:<input type="text" name="address.sp.pname" /></label><br/> <label for="address.sp.price">特产价格:<input type="text" name="address.sp.price" /></label><br/> <input type="submit" value="提交" /></form>

第二种

Java代码:

@RequestMapping("/map") public String retMap(Map<String,Object> map){ map.put("name","map return"); return "show"; }

方法中添加 map参数, 往map中放置数据,就可以发送到jsp页面!

显示代码如上!

第三种

将map更换成model即可!

java代码:

@RequestMapping("/model") public String retModel(Model model){ model.addAttribute("name","model return!"); return "show"; }

总结: 利用以上三种情形可以将数据返回给页面,页面利用EL表达式即可获取!但是要把稳!数据放入的是requestScope域!其他域获取不到!

验证代码:

${name}${requestScope.name}${sessionScope.name}结果显示值!前两个显示!sessionScope不显示!model return! model return!

如果须要将在sessionScope赋值一份!可以利用@SessionAttributes属性!

@SessionAttributes(names = "name") //names可以选择多个值,但是必须是已有的命名!@Controller@RequestMapping("/user")public class UserController {二. 掌握器方法中利用原生API

如果我们须要利用Servlet内部常用类:

HttpServletRequestHttpServletResponseHttpSession 等

直接在Controller层的方法中传入对应参数即可!不分顺序!

把稳:如果利用maven项目 须要导入 jsp jstl servlet api

<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency><dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope></dependency><dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.2.1</version> <scope>provided</scope></dependency>

Java代码示例:

@RequestMapping("/slt") public String getSlt(HttpServletRequest request){ //TODO 如果须要引入原生api类!直接在参数引入即可! return "show"; }三. RESTful风格编码1. RESTful先容

REST:即Representational State Transfer , (资源)表现层状态转化,是目前最盛行的一种互联网软件架构。
它构造清晰、符合标注、易于理解、方便扩展,以是越来越多的网站采取!

详细说,便是HTTP协议里面,四个表示操作办法的动词:

GET POST PUT DELETE

它们分别代表着四种基本操作:

GET用来获取资源POST用来创建新资源PUT用来更新资源DELETE用来删除资源

示例:

/order/1 HTTP GET :得到id = 1 的 order/order/1 HTTP DELETE: 删除 id=1 的order/order/1 HTTP PUT : 更新id = 1的 order/order HTTP POST : 新增 order2. Spring中实现RESTful风格

HiddenHttpMethodFilter:浏览器form表单只支持GET和POST,不支持DELETE和PUT要求,Spring添加了一个过滤器,可以将这些要求转换为标准的http方法,支持GET,POST,DELETE,PUT要求!

3.详细实现3.1 web.xml添加HiddenHttpMethodFilter配置

<filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping>3.2 实现查,改,删 框架!

@Controller@RequestMapping("/order")public class OrderController{ @RequestMapping(value = "/list",method = RequestMethod.GET) public String list(){ //获取用户列表 return "order/list"; } @RequestMapping(value = "/{id}",method = RequestMethod.DELETE) public String delete(@PathVariable("id") Integer id){ //实行删除操作 System.out.println("id = " + id); return "redirect:/order/list"; } @RequestMapping(value = "/{id}",method = RequestMethod.PUT) public String update(@PathVariable("id") Integer id){ //实行更新操作 System.out.println("id = " + id); return "redirect:/order/list"; }}

Jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h1>获取用户列表</h1> <a href="javascript:void(0)" onclick="deleteById()">删除</a> <form action="/order/1" method="post" id="deleteForm"> <input type="hidden" name="_method" value="DELETE" /> </form> <a href="javascript:void(0)" onclick="updateById()">修正</a> <form action="/order/1" method="post" id="updateForm"> <input type="hidden" name="_method" value="PUT" /> </form> <script> function updateById() { var form = document.getElementById("updateForm"); form.submit(); } function deleteById() { //TODO 删除 var form = document.getElementById("deleteForm"); form.submit(); } </script></body></html>

须要把稳: 由于doFilterInternal方法只对method为post的表单进行过滤,以是在页面中必须如下设置:

<form action="..." method="post"> <input type="hidden" name="_method" value="put" /> </form>

代表post要求,但是HiddenHttpMethodFilter将把本次要求转化成标准的put要求办法! name="_method"固定写法!

测试: 查看方法可以调通即可!

3.3 利用RESTful风格 CRUD操作!添加Order Pojo类!

public class Order { private Integer id; private String code; private Double money; public Order() { } public Order(Integer id, String code, Double money) { this.id = id; this.code = code; this.money = money; }//setter getter toString }添加OrderDao

@Repositorypublic class OrderDao { private static Map<Integer,Order> orders = null;//虚拟数据 static { orders = new HashMap<Integer, Order>(); orders.put(1,new Order(1,"订单1",20.5)); orders.put(2,new Order(2,"订单2",22.5)); orders.put(3,new Order(3,"订单3",24.5)); orders.put(4,new Order(4,"订单4",25.5)); orders.put(5,new Order(5,"订单5",26.5)); } public static Integer initId = 6; //记录id / 保存/更新 order @param order / public void save(Order order){ if (order.getId() == null) { order.setId(initId++); } orders.put(order.getId(),order); } / 返回所有数据 @return / public Collection<Order> getAll(){ return orders.values(); } / 获取数据 @param id @return / public Order get(Integer id){ return orders.get(id); } / 删除 @param id / public void delete(Integer id) { orders.remove(id); }}修正list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><html><head> <title>Title</title></head><body> <h1>获取用户列表</h1> <form action="/order/1" method="post" id="deleteForm"> <input type="hidden" name="_method" value="DELETE" /> </form> <form action="/order/1" method="post" id="updateForm"> <input type="hidden" name="_method" value="PUT" /> </form> <table align="center" width="60%" border="1px" bordercolor="#FB5832" CELLSPACING="0"> <tr> <td>id</td> <td>订单</td> <td>金额</td> <td>操作</td> </tr> <c:forEach items="${orderList }" var="order"> <tr> <td>${order.id}</td> <td>${order.code}</td> <td>${order.money}</td> <td> <a href="javascript:void(0)" onclick="deleteById(${order.id})">删除</a> <a href="javascript:void(0)" onclick="updateById(${order.id})">修正</a> </td> </tr> </c:forEach> </table> <center> <h3>添加订单</h3> <form action="/order/save" method="post"> <label for="code">订单<input id="code" type="text" name="code" /></label> <label for="money">总金额<input id="money" type="text" name="money" /></label> <button>添加订单</button> </form> </center> <script> function updateById(id) { //更新订单 //把稳 要动态修正form的action var form = document.getElementById("updateForm"); form.action = "/order/"+id; form.submit(); } function deleteById(id) { //TODO 删除 var form = document.getElementById("deleteForm"); form.action = "/order/"+id; form.submit(); } </script></body></html>完善Controller由于练习省略了业务层!直接在Controller层进行调用

@Controller@RequestMapping("/order")public class OrderController{ @Autowired private OrderDao orderDao; @RequestMapping(value = "/list",method = RequestMethod.GET) public String list(Model model){ //获取用户列表 Collection<Order> all = orderDao.getAll(); model.addAttribute("orderList",all); return "order/list"; } @RequestMapping(value = "/{id}",method = RequestMethod.DELETE) public String delete(@PathVariable("id") Integer id){ //实行删除操作 System.out.println("id = " + id); orderDao.delete(id); return "redirect:/order/list"; } @RequestMapping(value = "/{id}",method = RequestMethod.PUT) public String update(@PathVariable("id") Integer id){ //实行更新操作 System.out.println("id = " + id); orderDao.get(id).setCode("修正过后的订单"); return "redirect:/order/list"; } @RequestMapping(value = "/save",method = RequestMethod.POST) public String save(Order order){ //实行更新操作 orderDao.save(order); return "redirect:/order/list"; }}四. 处理静态资源

须要把稳一种,DispatcherServlet拦截资源设置成了 / 避免了去世循环,但是 / 不拦截jsp资源,但是它会拦截其他静态资源,例如 html , js , 图片等等, 那么我们在利用jsp内部添加 静态资源就无法成功,以是,我们须要单独处理下静态资源!

处理方案: 在springmvc的配置文件中添加mvc命名空间下的标签!

1. 修正Spring MVC对应配置文件,添加mvc命名空间和约束

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">2. 添加处理标签

<mvc:annotation-driven /> <!--表明驱动--> <mvc:resources mapping="/static/" location="/static/" ></mvc:resources>

配置阐明: 将静态资源(图片,css,js,html)放入了webApp/static文件夹下! 直接访问DispatcherServlet会拦截涌现404问题!

location元素表示webapp目录下的static包下的所有文件;

mapping元素表示将 location对应文件加下的资源对应到 /static路径下!

该配置的浸染是:DispatcherServlet不会拦截以/static开头的所有要求路径,并当作静态资源

交由Servlet处理

五. Spring MVC的组件1. SpringMVC事情事理2. 组件回顾DispatcherServlet:作为前端掌握器,全体流程掌握的中央,掌握其它组件实行,统一调度,降落组件之间的耦合性,提高每个组件的扩展性。
HandlerMapping:通过扩展处理器映射器实现不同的映射办法,例如:配置文件办法,实现接口办法,表明办法等。
HandlAdapter:通过扩展处理器适配器,支持更多类型的处理器,调用处理器通报参数等事情!ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。

把稳:但是我们之前编写代码只添加了DispatcherServlet和ViewResolver,但是没有涉及到HandlerMapping和HandlerAdapter!由于DispatcherServlet默认已经配置了HandlerMapping和HandlerAdapter!以是,我们没有自己定义HandlerMapping和HandlerAdapter!当然我们也可以进行自定义,本章节紧张讲解自定义ViewResolver,HandlerMapping和HandlerAdapter。

查看DispatcherServlet的默认配置

文件位置: org/springframework/web/servlet/DispatcherServlet.properties

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver//默认的HandlerMappingorg.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,/org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping//默认HandlerAdapterorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,/org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,/org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterorg.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,/org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,/org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator//默认视图解析器org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=org.springframework.we3. 配置HandlerAdapter 和 HandlerMapping

配置 RequestMappingHandlerAdapter 和 RequestMappingHandlerMpping

文件上传,返回JSON须要依赖以上适配器和映射器!

配置

<!-- 处理器映射器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /><!-- 处理器适配器--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" /><mvc:annotation-driven /> <!--可以更换以上两种! -->

阐明: <mvc:annotaion-driveb /> 默认对应的处理类是 org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser ;

@Overridepublic BeanDefinition parse(Element element, ParserContext parserContext) {....//加载: RequestMappingHandlerMapping RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);//加载:RequestMappingHandlerAdapterRootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);handlerAdapterDef.setSource(source);handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);...六.返回JSON数据

访问掌握器返回Json类型数据!

1. 导入对应的JSON包!

支持:

jackson : jackson-databind/jackson-annotations/jack-core

gson: gson

把稳: jackson须要三个jar包!如果利用maven引入jackson-databind会连带引入 core和annotations。

如果非maven项目,必须加入三个jar包!

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.9</version></dependency>

或者:

<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.4</version></dependency>2. 实当代码

紧张利用@ResponseBody

@ResponseBody@RequestMapping("/json")public List<User> getJson(){ //TODO 返回JSON数据,返回List或者工具都可以! //ResponseBody都可以转成JSON类型 User user = new User(); user.setName("测试1"); user.setAge("12"); user.setBirthday(new Date()); List<User> list = new ArrayList<User>(); list.add(user); list.add(user); return list;}3. 回顾Spring MVC返回值类型String情形1: 查找到指定的视图return "user/show";情形2: 转发或者重定向return "redirect: path";return "forword:path";ModelAndView​ 返回数据视图模型工具!​ ModelAndView mv = new ModelAndView();​ mv.setViewName("查找视图路径");​ mv.addObject("key","object type data");​Object​ 合营@ResponseBody返回Json数据类型!void​ 可以返回其他mimetype类型的数据!常日将方法定义成void!合营方法传参得到Response工具,通过Response.getWriter().writer("数据");七.Spring MVC非常处理1. Spring MVC非常处理先容

Spring MVC通过HandlerExceptionResolver处理程序的非常,包括处理映射,数据绑定及处理器实行时发生非常。
HandlerExceptionResolver仅有一个接口方法:

ModelAndView resolveException(HttpServletRequest reqeust,HttpServletResponse response,Object handler,Exception ex);

当发生非常时,Spring MVC将调用 resolveException()方法,并转到ModelAndView对应视图中,作为一个非常报告页面,反馈给用户!

HandlerExceptionResolver拥有4个实现类:

DefaultHandlerExceptionResolverSimpleMappingExceptionResolverAnnotationMethodHandlerExceptionResolverResponseStatusExceptionResolver2. 非常处理方案2.1 DefaultHandlerExceptionResolver

​ Spring MVC默认装置了DefaultHandlerExceptionResolver,它会将Spring MVC框架的非常转换为相应的相应状态码!

非常和相应状态码对应表

非常类型相应状态码ConversionNotSupportedException500(Web做事器内部缺点)HttpMediaTypeNotAcceptableException406(无和要求accept匹配的MIME类型)HttpMediaTypeNotSupportedException415(不支持MIME类型)HttpMessageNotReadableException400HttpMessageNotWritableException500HttpRequestMethodNotSupportedException405MissingServletRequestParameterException400

在web.xml相应状态码配置一个对应页面

<error-page> <error>404</error> <location>/404.html</location></error-page>

把稳: 静态资源把稳会被DispatcherServlet拦截!

2.2 AnnotationMethodHandlerExceptionResolver

Spring MVC 默认注册了 AnnotationMethodHandlerExceptionResolver,它许可通过@ExceptionHandler表明指定处理特定非常的方法!

@ExceptionHandler public String handleException(RuntimeException re, HttpServletRequest request) { return "forward:/user/error"; }

通过@ExceptionHandler指定了当前类的一个缺点处理方法!如果当前类中涌现非常,会触发缺点处理方法!

但是@ExceptionHandler的非常处理方法只能对同一处理类中的其他处理方法进行非常相应处理!!

2.3 全局非常处理

@ControllerAdvicepublic class MyExecptionHandler { @ExceptionHandler(Exception.class) public ModelAndView handleException(Exception ex) { System.out.println("全局非常:ex = " + ex); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("exception",ex); return modelAndView; }}

此处可以捕捉全局非常,但是不要忘了在spring配置的时候扫描该类!

八. Spring MVC拦截器实现

Spring MVC 的拦截器类似于Servlet中的拦截器!须要先定义一个类实现HandlerInterceptor接口!

添加未实现的方法,在springmvc配置中配置!详细实现步骤如下:

1. 创建拦截器类

public class MyInterceptors implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("调用之前触发此方法!"+handler); / return false 代表拦截,不调用controller方法直接返回 true 不拦截 / return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { / 调用之后调用此方法 / System.out.println("handler已经被调用完毕!"+handler); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { / 相应已经被渲染后,实行该方法. / System.out.println("相应已经进行了渲染"); }}boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):在要求到达Handler之前,先实行这个前置处理方法.当该方法返回false时,要求直接返回,不会通报到链中的下一个拦截器,更不会通报到链尾的Handler,只有返回true时,要求才会向链中的下一个处理节点通报!void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView); 在相应已经被渲染后,实行该方法.void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); 在相应已经被渲染后,实行该方法!2. SpringMVC 配置文件中配置拦截器

<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/user/"/> <bean class="com.itqf.spring.interceptors.MyInterceptors" /> </mvc:interceptor> </mvc:interceptors>九. Spring MVC处理文件上传

Spring MVC为文件上传供应了直接支持,这种支持是通过即插即用的MultipartResolver实现. Spring利用Jakarta Commons FileUpload技能实现了一个MultipartResolver实现类:CommonsMultipartResolver。

在SpringMVC高下文中默认没有装置MultipartResolver,因此默认情形下不能处理文件上传事情。
如果想利用Spring的文件上传功能,则须要先在高下文中配置MultipartResolver。

1. 引入jar包!

commons-fileupload.jar

commons-io.jar

maven项目pom.xml

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --><dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version></dependency><!-- https://mvnrepository.com/artifact/commons-io/commons-io --><dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version></dependency>2. 配置MultipartResolver

配置

<!--multipartResolver配置--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="UTF-8" p:maxUploadSize="5242880" p:uploadTempDir="file:/d:/temp" />3. 编写掌握器和文件上传表单编写文件上传表单 upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <center> <form method="post" enctype="multipart/form-data" action="/user/upload"> <label for="name">文件名称<input type="text" id="name" name="name" /></label> <input type="file" name="file" /> <button>提交</button> </form> </center></body></html>编写掌握器代码

@RequestMapping("/toUpload") public String toUpload(){ //跳转到上传页面 return "user/upload"; } @RequestMapping("/upload") public String saveFile(@RequestParam("name") String name , @RequestParam("file")MultipartFile file) throws IOException { //吸收表单提交的数据,包含文件 System.out.println("name = " + name); if (!file.isEmpty()) { file.transferTo(new File("G:/temp/"+file.getOriginalFilename())); } return "success"; }

​ SpringMVC会将上传文件绑定到MultipartFile工具上. MultipartFile供应了获取长传文件内容,文件名等方法,通过transferTo()方法还可将文件存储到磁盘中,详细方法如下:

方法名称方法阐明byte [] getBytes()获取文件数据String getContentType()获取文件MIMETYPE类型,如image/jpeg,text/plain等InputStream getInputStream()获取文件输入流String getName()获取表单中文件组件的名称 name值!String getOriginalFilename()获取文件上传的原名long getSize()获取文件的字节大小,单位为byteboolean isEmpty()是否有长传的文件void transferTo(File dest)可以将上传的文件保存到指定的文件中