SpringMVC入门
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 配置前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定DispatcherServlet的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 拦截配置方式有两种正确和一种错误的 --> <!-- 第一种:*.do 拦截以.do结尾的--> <!-- 第二种:/,会拦截所有请求(不包括jsp请求),会包括静态资源(CSS、js、图片、html页面,只需要设置静态资源拦截规则就可以访问),还可以满足restful请求的url --> <!-- 第三种:/*,这种配置是错误的,会拦截所有请求(包括jsp请求)--> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> |
config/springmvc.xml <?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:p="http://www.springframework.org/schema/p" 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-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 使用注解扫描器,配置处理器,扫描包内 --> <context:component-scan base-package="com.itjava.springmvc.first" /> </beans> |
package com.itjava.springmvc.first; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.itjava.springmvc.po.Items; @Controller public class ItemsController { @RequestMapping("/queryItems") public ModelAndView queryItems() { // 调用service方法,返回商品列表(使用静态数据模拟) List<Items> itemList = new ArrayList<>(); // 商品列表 Items items_1 = new Items(); items_1.setName("联想笔记本_3"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); itemList.add(items_1); itemList.add(items_2); ModelAndView mv = new ModelAndView(); // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中 mv.addObject("itemsList", itemList); // 指定视图名称 mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp"); return mv; } } |
访问路径:端口号/项目名/queryItems.do |
如何开发处理器(Controller类) 1. 类上加Controller注解 2. 方法上加RequestMapping注解 3. 还有其他开发方式(实现HttpRequestHandler接口、实现Controller接口,此两种仅作了解) |
实现HttpRequestHandler接口 package com.itjava.springmvc.first; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.HttpRequestHandler; import com.itjava.springmvc.po.Items; public class ItemsController2 implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 调用service方法,返回商品列表(使用静态数据模拟) List<Items> itemList = new ArrayList<>(); // 商品列表 Items items_1 = new Items(); items_1.setName("联想笔记本_3"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); itemList.add(items_1); itemList.add(items_2); // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中 request.setAttribute("itemsList", itemList); // 指定视图名称,不会经过视图解析器 request.getRequestDispatcher("/WEB-INF/jsp/item/itemsList.jsp").forward(request, response); } } 访问路径:端口号/项目名/queryItems2.do |
实现Controller接口 package com.itjava.springmvc.first; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.itjava.springmvc.po.Items; public class ItemsController3 implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { // 调用service方法,返回商品列表(使用静态数据模拟) List<Items> itemList = new ArrayList<>(); // 商品列表 Items items_1 = new Items(); items_1.setName("联想笔记本_3"); items_1.setPrice(6000f); items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); Items items_2 = new Items(); items_2.setName("苹果手机"); items_2.setPrice(5000f); items_2.setDetail("iphone6苹果手机!"); itemList.add(items_1); itemList.add(items_2); ModelAndView mv = new ModelAndView(); // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中 mv.addObject("itemsList", itemList); // 指定视图名称 mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp"); return mv; } } 访问路径:端口号/项目名/queryItems3.do |
config/springmvc.xml <?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:p="http://www.springframework.org/schema/p" 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-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 使用注解扫描器,配置处理器,按包匹配扫描,多个包中间使用半角逗号分隔--> <context:component-scan base-package="com.itjava.springmvc.first" /> <!-- 配置实现HttpRequestHandler接口的处理器,下面两种不需要注解扫描器--> <bean name="/queryItems2.do" class="com.itjava.springmvc.first.ItemsController2"></bean> <bean name="/queryItems3.do" class="com.itjava.springmvc.first.ItemsController3"></bean> </beans> |
springmvc架构(重点)
架构流程
1. 用户发送请求至前端控制器DispatcherServlet 2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器 5. HandlerAdapter执行处理器(handler,也叫后端控制器)。 6. Controller执行完成返回ModelAndView 7. HandlerAdapter将handler执行结果ModelAndView返回给DispatcherServlet 8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器 9. ViewReslover解析后返回具体View对象 10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。 11. DispatcherServlet响应用户 在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。 需要用户开发的组件有:处理器、视图 |
在config/springmvc..xml配置文件中
<!-- 配置注解映射器和适配器,配置这两行代码后,非注解的访问会报错 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean> <!-- 使用mvc标签配置注解和非注解映射器和适配器,配置下面的代码可注释上面的两行代码 --> <!-- 该配置就默认配置注解方式的映射器和适配器,还配置了参数绑定组件,比如json参数绑定组件 --> <mvc:annotation-driven /> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 视图解析器配置前缀,返回视图会自动添加此前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 视图解析器配置后缀,返回视图会自动添加此后缀--> <property name="suffix" value=".jsp" /> <!-- mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp");可改为mv.setViewName("item/itemsList");//此称之为逻辑视图--> </bean> |
整合ssm
自定义转换器,转换日期格式
package com.itjava.ssm.controller.converter; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; public class DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { try { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return format.parse(source); } catch (Exception e) { e.printStackTrace(); } return null; } |
config/mybatis/SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration> |
config/spring/applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 读取java配置文件 --> <context:property-placeholder location="classpath:db.properties" />
<!-- 配置数据源,使用dbcp连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="10" /> <property name="maxIdle" value="5" /> </bean>
<!-- 配置SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定mybatis的全局配置文件路径 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> <!-- 指定数据源 --> <property name="dataSource" ref="dataSource"></property> <!-- 指定类型别名 --> <property name="typeAliasesPackage" value="com.itjava.ssm.po"></property> </bean>
<!-- 批量代理mapper对象 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 注入批量代理的mapper对象所在的包名 --> <property name="basePackage" value="com.itjava.ssm.mapper"></property> </bean> </beans> |
config/spring/applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 通过组件扫描器,加载service的bean --> <context:component-scan base-package="com.itjava.ssm.service"></context:component-scan>
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
<!-- 配置通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 配置事务传播特性,name指的就是业务方法的名称,可以使用通配符 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="modify*" propagation="REQUIRED" /> <tx:method name="find*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="select*" read-only="true" /> <tx:method name="get*" read-only="true" /> </tx:attributes> </tx:advice>
<!-- 配置AOP --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itjava.ssm.service.impl.*.*(..))" /> </aop:config>
</beans> |
config/spring/springmvc.xml
<?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:p="http://www.springframework.org/schema/p" 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-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 使用注解扫描器,配置处理器 --> <context:component-scan base-package="com.itjava.ssm.controller" /> <!-- 使用mvc标签配置注解映射器和适配器 --> <!-- 该配置就默认配置注解方式的映射器和适配器,还配置了参数绑定组件,比如json参数绑定组件 --> <!-- 如果不配置自定义转换器,则删除conversion-service="conversionService" --> <mvc:annotation-driven conversion-service="conversionService" />
<!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 配置自定义转换器 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.itjava.ssm.controller.converter.DateConverter"></bean> </set> </property> </bean> </beans> |
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 配置前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定DispatcherServlet的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<!-- 解决POST乱码 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> |
对象传递
service层 @Service public class ItemsServiceImpl implements ItemsService { @Autowired private ItemsMapper mapper; // 代码... } |
controller层 @RequestMapping("/items") @Controller public class ItemsController { @Autowired private ItemsService service; // 代码... } |
什么是参数绑定?
客户端通过http请求的参数,默认是key/value格式(http://XXXXX?id=1&type=301)的字符串,springmvc通过参数绑定组件将请求参数串的value进行类型转换,将转换后的值赋值给controller方法的形参,这就是参数绑定的过程
springmvc使用controller方法形参接收请求的参数 |
struts2通过成员变量接收请求的参数 |
参数绑定之简单类型
直接绑定
@Controller public class ItemsController { @Autowired private ItemsService service; @RequestMapping("/itemsEdit") public ModelAndView itemsEdit(Integer id) { Items items = service.queryItemsById(id); ModelAndView mv = new ModelAndView(); // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中 mv.addObject("items", items); // 指定视图名称 mv.setViewName("item/editItems"); return mv; } } |
参数绑定之pojo类型
访问路径端口号/项目名/itemsEdit.do?id=1&name=张三&age=20 访问方式为POST |
@Controller public class ItemsController { @Autowired private ItemsService service; @RequestMapping("/itemsEdit") // id会分配给id与user中的id public ModelAndView itemsEdit(Integer id ,User user) { ModelAndView mv = new ModelAndView(); // 代码... return mv; } } |
已在web.xml配置 |
绑定包装pojo类
key值为items.name,接收参数为QueryVO,QueryVO中有属性items,items中有name属性,即可接收到 |
自定义参数绑定
由于日期数据有很多种格式,所以springmvc没办法把字符串转换成统一的日期类型。所以需要自定义参数绑定。
前端控制器接收到请求后,找到处理器适配器,适配器在执行处理器时,对方法中的形参进行参数绑定。所以如果自定义参数绑定组件的话,需要将该参数组件绑定到处理器适配器上。如果使用<mvc:annotation-driven/>可以在此标签上进行扩展
已在前面的代码及配置文件配置
springmvc与struts2不同
1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。 2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。 |
绑定数组
如果页面传递的请求参数中,是一个集合参数,并且是简单类型的,这个时候只能使用数组来接收,不能使用List 对于这种批量操作简单类型数据的情况,Controller方法中可以用String[]接收,或者pojo的String[]属性接收,但是不能使用集合接收。两种方式任选其一即可,比如根据id批量删除商品信息 |
将表单的数据绑定到List
如果页面传递的请求参数中,是一个集合参数,并且是POJO类型的,这个时候可以使用数组也可以使用List来接收,但是不能将数组或者List直接声明在Controller的方法中,只能通过一个POJO来包装它们然后接收
Item中有userList(user的List集合或数组集合) 方法的参数名为(Item item) 传递的参数name="userList[0].username"即可 |
URL路径映射:在方法上
@RequestMapping(value="/items")或@RequestMapping("/items") value的值是数组,可以将多个url映射到同一个方法 @RequestMapping(value={"/items","/queryItems"}) |
窄化请求映射
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。 如下: @RequestMapping放在类名上边,设置请求前缀 @Controller @RequestMapping("/items") 方法名上边设置请求映射url: @RequestMapping放在方法名上边,如下: @RequestMapping("/queryitems") 访问地址为:/items/queryItems.do |
请求方法限定:在类上
限定GET方法 @RequestMapping(method = RequestMethod.GET) 如果通过Post访问则报错: HTTP Status 405 - Request method 'POST' not supported 例如: @RequestMapping(value="/edititems",method=RequestMethod.GET) |
限定POST方法 @RequestMapping(method = RequestMethod.POST) 如果通过Post访问则报错: HTTP Status 405 - Request method 'GET' not supported |
GET和POST都可以 @RequestMapping(method={RequestMethod.GET,RequestMethod.POST}) |
controller方法返回值
返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。 | ||||
返回void 在controller方法形参上可以定义request和response,使用request或response指定响应结果: 1、使用request转发页面,如下: request.getRequestDispatcher("页面路径").forward(request, response); 2、也可以通过response页面重定向: response.sendRedirect("url") 3、也可以通过response指定响应结果,例如响应json数据如下: response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串"); | ||||
返回字符串(推荐)
|
异常处理器
package com.itjava.ssm.exception; public class BusinessException extends Exception { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public BusinessException(String message) { super(); this.message = message; } } |
import com.itjava.ssm.exception.BusinessException; public String itemsEdit(Integer id, Model model) throws Exception { Items items = service.queryItemsById(id); if (items == null) throw new BusinessException("根据该商品ID无法查找商品数据!"); // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中 model.addAttribute("items", items); return "item/editItems"; } |
package com.itjava.ssm.exception.resolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import com.i tjava.ssm.exception.BusinessException; public class BusinessExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { //获取异常错误信息 String msg = "未知错误"; if (ex instanceof BusinessException) { BusinessException bx = (BusinessException) ex; msg = bx.getMessage(); } ModelAndView mv = new ModelAndView(); //将异常信息封装到request域中 mv.addObject("msg", msg); //在错误页面显示 mv.setViewName("error"); return mv; } } |
springmvc.xml中 <!-- 配置异常处理器 --> <bean class="com.itjava.ssm.exception.resolver.BusinessExceptionResolver"></bean> |
上传图片
springmvc.xml中 <!-- 多部件解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置上传文件的最大尺寸 5M ,,单位是byte --> <property name="maxUploadSize" value="5242880" /> </bean> |
@RequestMapping("/updateItems") public String updateItems(Integer id, Items items, MultipartFile pictureFile) throws Exception{ if (pictureFile != null) { // 目的是为了获取上传文件的扩展名 String originalFilename = pictureFile.getOriginalFilename(); // 判断文件名称不为空 if (originalFilename != null && !"".equals(originalFilename)) { // 获取扩展名 String extName = originalFilename.substring(originalFilename.lastIndexOf(".")); // 创建新的文件名称 String newFileName = UUID.randomUUID().toString() + extName; // 指定文件生成之后的目录 String dir = "E:\\03-teach\\07-upload\\temp\\"; // 判断如果目录不存在,则创建 File dirFile = new File(dir); if (!dirFile.exists()) { dirFile.mkdirs(); } //上传文件到指定目录 pictureFile.transferTo(new File(dir+newFileName)); //保存上传文件名称 items.setPic(newFileName); } } // 调用service的方法进行修改 service.updateItems(items); // 重定向 // return "redirect:queryItems.do"; // 请求转发 return "forward:queryItems.do"; } |
配置图片文件的虚拟目录
1. 通过eclipse配置tomcat的虚拟目录 |
2. 直接修改tomcat的配置文件 在tomcat安装目录中的conf/server.xml文件中,添加虚拟目录: <Context docBase="E:\03-teach\07-upload\temp" path="/pic" reloadable="false"/> |
json数据交互
用户发出请求 | ||
请求参数是json串(必须外面单引里面双引) data : '{"name":"zhangsan","price":999}' 需要指定 contentType=application/json;charset=utf-8 |
| 请求参数是key/value data : "name=zhangsan&price=999" 不需要指定contentType 默认contentType=application/x-www-form-urlencoded |
使用@RequestBody将json串转成java对象 | 不用@RequestBody | |
使用@ResponseBody将返回值的java对象转成json串输出 @RequestMapping("/requestJSON") @ResponseBody public Items requestJSON(@RequestBody Items items){ return items; } | 使用@ResponseBody将返回值的java对象转成json串输出 @RequestMapping("/requestKV") @ResponseBody public Items requestKV(Items items){ return items; } | |
最终都是输出了json串到页面,方便客户端解析 |
RESTful支持
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
普通URL:
http://localhost:8080/ssm/queryItemsById.do?id=1
restful风格URL
http://localhost:8080/ssm/items/1
uri:统一资源定位符ssm/queryItemsById
httpMethod有7种:其中获取资源使用get方式、添加资源使用post方式、删除资源使用delete方式、修改资源使用put方式。
Restful风格要求三个规范:
1、 要求URL要规范
2、 要求httpmethod方法要被利用(不用在意)
3、 要求返回格式是由调用人员指定
注意:restful风格的请求URL只会在GET方式的请求过程中和普通请求方式有所区别
在web.xml将拦截规则改为
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定DispatcherServlet的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
根据需求,设计的restful风格的请求url如下:
http://localhost:8280/ssm2/queryItemsById/1
// 参数名不相同的格式 @RequestMapping("/queryItemsById/{itemsId}") @ResponseBody public Items queryItemsById4Rest(@PathVariable("itemsId") Integer id){ return service.queryItemsById(id); } |
// 参数名相同的格式 @RequestMapping("/queryItemsById/{id}") @ResponseBody public Items queryItemsById4Rest(@PathVariable Integer id){ return service.queryItemsById(id); } |
由于更改了在web.xml中的配置导致访问静态资源也会被拦截,所以需要在springmvc.xml中如下配置
<!-- 配置静态资源处理器配置 --> <mvc:resources location="/js/" mapping="/js/**" /> <mvc:resources location="/css/" mapping="/css/**" /> |
拦截器
Springmvc的拦截器主要是拦截处理器的
针对单个HandlerMapping配置(一般不使用)
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="handlerInterceptor1" /> </list> </property> </bean> <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1" /> |
自定义拦截器
package com.itjava.ssm.controller.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class Interceptor1 implements HandlerInterceptor { // 使用时机:处理器执行之前 // 使用场景:登录认证、权限验证 // 返回值:true 放行 false 不放行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor1...preHandle"); return false; } // 使用时机:处理器执行时未返回之前 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub System.out.println("Interceptor1...postHandle"); } // 使用时机:处理器执行之后 // 使用场景:日志记录 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub System.out.println("Interceptor1...afterCompletion"); } } |
springmvc.xml <!-- 全局拦截器配置/**全部拦截 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.itjava.ssm.controller.interceptor.Interceptor1"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.itjava.ssm.controller.interceptor.Interceptor2"></bean> </mvc:interceptor> </mvc:interceptors> |
<mvc:interceptor> <mvc:mapping path="/manage/**"/> <mvc:exclude-mapping path="/manage/goLogin.*"/> <mvc:exclude-mapping path="/manage/login.*"/> <mvc:exclude-mapping path="/manage/logout.*"/> <bean class="com.xx.ManageInterceptor"/> </mvc:interceptor> |
拦截器测试:1在前先执行,2在后后执行
1放行,2放行 HandlerIntercepter1...preHandle HandlerIntercepter2...preHandle
HandlerIntercepter2...postHandle HandlerIntercepter1...postHandle
HandlerIntercepter2...afterCompletion HandlerIntercepter1...afterCompletion |
1放行,2不放行 HandlerIntercepter1...preHandle HandlerIntercepter2...preHandle
HandlerIntercepter1...afterCompletion |
1不放行,2不放行 HandlerIntercepter1...preHandle |