文章目录
- 2. Springmvc概述
- 3. springmvc与struts2不同
- 5. springmvc入门
- 6. springmvc 配置
- 7. Handler配置
- 8. 异常处理器
- 9. ssm整合思路
- 10. 上传图片
- 11. RESTful支持
- 12. 拦截器
- 总结
2. Springmvc概述
- Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分
3. springmvc与struts2不同
- springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。
- springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,struts2是基于类开发,传递参数是通过类的属性
- Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,
5. springmvc入门
创建动态web工程(2.5)
导入jar包
commons-logging-1.1.1.jar
jstl-1.2.jar
spring-aop-4.1.3.RELEASE.jar
spring-aspects-4.1.3.RELEASE.jar
spring-beans-4.1.3.RELEASE.jar
spring-context-4.1.3.RELEASE.jar
spring-context-support-4.1.3.RELEASE.jar
spring-core-4.1.3.RELEASE.jar
spring-expression-4.1.3.RELEASE.jar
spring-jdbc-4.1.3.RELEASE.jar
spring-jms-4.1.3.RELEASE.jar
spring-messaging-4.1.3.RELEASE.jar
spring-tx-4.1.3.RELEASE.jar
spring-web-4.1.3.RELEASE.jar
spring-webmvc-4.1.3.RELEASE.jar
在src下创建springmvc.xml
导入所有约束文件aop、beans、context、mvc、tool、tx、util
<?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">
<!--配置扫描注解 配置controller扫描包 -->
<context:component-scan base-package="cn.itcast.springmvc.controller"/>
</beans>
在web.xml中配置SpringMVC的前端控制器DispatcherServlet
<?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">
<display-name>springmvc-first</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 配置SpringMVC前端控制器 -->
<servlet>
<servlet-name>springmvc-first</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 指定SpringMVC配置文件 -->
<!-- SpringMVC的配置文件的默认路径是
/WEB-INF/${servlet-name}-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-first</servlet-name>
<!-- 设置所有以action结尾的请求进入SpringMVC -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
在web.Xml中用dispathcherservlet然后Alt+/提示然后配置一下就行
加入jsp页面
把itemList.jsp放到/WEB-INF/jsp目录
<c:forEach items="${itemList }" var="item">
<tr>
<td>${item.name }</td>
<td>${item.price }</td>
<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td>${item.detail }</td>
<td>
<a href="${pageContext.request.contextPath}/itemEdit.action?id=${item.id}">修改</a>
</td>
</tr>
</c:forEach>
创建pojo
public class Item {
private int id;
private String name;
private double price;
private Date createtime;
private String detail;
创建带参数的构造器
set/get。。。
}
创建ItemController类,不需要实现任何接口。
在类上添加@Controller注解,把Controller交由Spring管理
在方法上面添加@RequestMapping注解,里面指定请求的url。
其中“.action”可以加也可以不加。
@Controller
public class ItemController {
@RequestMapping("/itemList.action")
public ModelAndView queryItemList() {
List<Item> list = new ArrayList<>();
list.add(new Item(1, "1华为 荣耀8", 2399, new Date(), "质量好!1"));
list.add(new Item(2, "2华为 荣耀8", 2399, new Date(), "质量好!2"));
list.add(new Item(3, "3华为 荣耀8", 2399, new Date(), "质量好!3"));
list.add(new Item(4, "4华为 荣耀8", 2399, new Date(), "质量好!4"));
list.add(new Item(5, "5华为 荣耀8", 2399, new Date(), "质量好!5"));
list.add(new Item(6, "6华为 荣耀8", 2399, new Date(), "质量好!6"));
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("list", list);
modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
//或者像下面这么写
// 创建ModelAndView,用来存放数据和视图
//ModelAndView modelAndView = new ModelAndView();
// 设置数据到模型中
//modelAndView.addObject("itemList", list);
// 设置视图jsp,需要设置视图的物理地址
// modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
// 配置好视图解析器前缀和后缀,这里只需要设置逻辑视图就可以了。
// 视图解析器根据前缀+逻辑视图名+后缀拼接出来物理路径
//modelAndView.setViewName("itemList");
//return modelAndView;
return modelAndView;
}
}
启动项目测试
浏览器访问地址http://127.0.0.1:8080/springmvc-first/itemList.action
6. springmvc 配置
组件扫描器(省去在spring容器配置每个Controller类的繁琐)
使用<context:component-scan>自动扫描标记@Controller的控制器类,
在springmvc.xml配置文件中配置如下:
<!-- 配置controller扫描包,多个包之间用,分隔 -->
<context:component-scan base-package="cn.test.springmvc" />
注解驱动(省去直接配置处理器映射器和处理器适配器的麻烦)
SpringMVC使用<mvc:annotation-driven>
自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter
<!-- 注解驱动 -->
<mvc:annotation-driven />
视图解析器
视图解析器使用SpringMVC框架默认的InternalResourceViewResolver()
这个视图解析器支持JSP视图解析
在springmvc.xml配置文件中配置如下:
<!-- Example: prefix="/WEB-INF/jsp/",suffix=".jsp",viewname="test" ->
"/WEB-INF/jsp/test.jsp" -->
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置逻辑视图的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置逻辑视图的后缀 -->
<property name="suffix" value=".jsp" />
</bean>
逻辑视图名需要在controller中返回ModelAndView指定,
比如逻辑视图名为ItemList,则最终返回的jsp视图地址:
“WEB-INF/jsp/itemList.jsp”
最终jsp物理地址:前缀+逻辑视图名+后缀
7. Handler配置
参数绑定(接受请求参数的方法)
处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值。
HttpServletRequest:通过request对象获取请求信息public String editItem(HttpServletRequest request)
HttpServletResponse:通过response处理响应信息public String editItem(HttpServletResponse response)
HttpSession:通过session对象得到session中存放的对象public String editItem(HttpSession session)
简单数据类型(基本数据类型,基本类型包装类)参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
public String editItem(Model model,Integer id,Boolean status) 请求url:http://localhost:8080/xxx.action?id=2&status=false
@RequestParam:常用于处理简单类型的绑定。
value:请求参数名字,required:是否必须,默认是true、defaultValue:默认值,表示如果请求中没有同名参数时的默认值
public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id)
使用pojo对象接收表单数据(提交内容很多的时候)
要求:pojo对象中的属性名和表单中input的name属性一致
前端:name="pojo对象的属性名" value="${pojo.属性名}"
后端:test(pojo){}
pojo定义对应的属性并生成set/get方法
请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。
注意:提交的表单中不要有日期类型的数据,否则会报400错误。
如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。
使用绑定包装pojo(内部类)
前端:name="内部类.内部属性名" value="外部类.内部类.内部属性名"
后端:定义pojo内部类
定义参数接收
@RequestMapping("/queryItem")
public String queryItem(QueryVo queryVo) {
System.out.println(queryVo.getItem().getId());
System.out.println(queryVo.getItem().getName());
return "success";
}
自定义参数绑定(自定义日期格式)
可以在springmvc处理器适配器上自定义转换器Converter进行参数绑定。
一般使用<mvc:annotation-driven/>注解驱动加载处理器适配器,可以在此标签上进行配置。
前端
<input type="text" name="items.createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" />
后端自定义Converter,
//Converter<S, T>
//S:source,需要转换的源的类型
//T:target,需要转换的目标类型
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
// 把字符串转换为日期类型
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
// 如果转换异常则返回空
return null;
}
}
springmvc.xml配置Converter 同时可以配置多个的转换器。
<!-- 配置注解驱动 -->
<!-- 如果配置此标签,可以不用配置... -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 转换器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.springmvc.converter.DateConverter" />
</set>
</property>
</bean>
绑定数组
前端 <c:forEach item="${itemList}" var="item">
<input type="checkbox" name="ids" value="${item.id}"/>
<input type="checkbox" name="ids" value="${item.id}"/>
</c:forEach>
后端:pojo中定义private integer[] ids;生成set/get方法
包装类型 绑定数组类型,可以使用两种方式,pojo的属性接收和直接接收
@RequestMapping("queryItem")
public String queryItem(QueryVo queryVo, Integer[] ids) {
System.out.println(queryVo.getItem().getId());
System.out.println(queryVo.getIds().length);
System.out.println(ids.length);
return "success";
}
绑定List
后端:在pojo中定义private List<Item> itemList;生成set/get方法
前端页面:name属性必须是list属性名+下标+元素属性。
<c:forEach items="${itemList }" var="item" varStatus="s">
<tr>
<td><input type="checkbox" name="ids" value="${item.id}"/></td>
<td>
<input type="hidden" name="itemList[${s.index}].id" value="${item.id }"/>
<input type="text" name="itemList[${s.index}].name" value="${item.name }"/>
</td>
</tr>
</c:forEach>
${current} 当前这次迭代的(集合中的)项
${status.first} 判断当前项是否为集合中的第一项,返回值为true或false
${status.last} 判断当前项是否为集合中的最
varStatus属性常用参数总结下:
${status.index} 输出行号,从0开始。
${status.count} 输出行号,从1开始。
${status.后一项,返回值为true或false
begin、end、step分别表示:起始序号,结束序号,跳跃步伐。
接收List类型的数据必须是pojo的属性,如果方法的形参为ArrayList类型无法正确接收到数据
我们需要从url上获取商品id,步骤如下:
1.@RequestMapping("item/{id}")声明请求的url
{xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”
2.使用(@PathVariable() Integer id)获取url上的数据
* 使用RESTful风格开发接口,实现根据id查询商品
@RequestMapping("item/{id}")
@ResponseBody
public Item queryItemById(@PathVariable() Integer id) {
Item item = this.itemService.queryItemById(id);
return item;
}
如果@RequestMapping中表示为"item/{id}",id和形参名称一致,
@PathVariable不用指定名称。如果不一致,例如"item/{ItemId}"
则需要指定名称@PathVariable("itemId")。
http://127.0.0.1/item/123?id=1
注意两个区别
1.@PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)
2.如果加上@ResponseBody注解,就不会走视图解析器,
不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面
@RequestMapping("/hello")//接收所有hello路径的请求
public String index(参数名与接收的参数名一致) {
return "Hello World";
}
### 指定前端url请求参数名称与方法名一致
### 通过HttpServletRequest来获取前端页面参数
### 创建一个JavaBean对象来封装表单参数或者是请求url路径中的参数
### 通过PathVariable注解来绑定请求路径的参数
### 通过RequestParam注解来获取
## springboot返回参数
### 返回jsp页面(undertow不支持jsp)
值得注意的是,当我们使用Spring Boot 2.0 想要返回页面而不是提供json或者xml数据接口的时候,
切记不能再使用@RestController了,只能使用@Controller.
@RequestMapping:定义不同的处理器映射规则,URL路径映射
添加在方法上面
@RequestMapping("/item")
value的值是数组,可以将多个url映射到同一个方法
@RequestMapping(value = { "/itemList", "/itemListAll" })
public ModelAndView queryItemList() {
List<Item> list = this.itemService.queryItemList();
ModelAndView mv = new ModelAndView("itemList");
mv.addObject("itemList", list);
return mv;
}
添加在类上面 在class上添加@RequestMapping(url)指定通用请求前缀,
限制此类下的所有方法请求url必须以请求前缀开头,可以使用此方法对url进行分类管理
@controller
@RequestMapping("item")
public class ItemController{
@RequestMapping(value = { "itemList", "itemListAll" })
public ModelAndView queryItemList() {
}
}
此时需要进入queryItemList()方法的请求url为:
http://127.0.0.1:8080/springmvc-web2/item/itemList.action
或者
http://127.0.0.1:8080/springmvc-web2/item/itemListAll.action
请求方法限定
限定GET方法
@RequestMapping(method = RequestMethod.GET)如果通过POST访问则报错:
HTTP Status 405 - Request method 'POST' not supported
@RequestMapping(value = "itemList",method = RequestMethod.POST)
限定POST方法
@RequestMapping(method = RequestMethod.POST)
如果通过GET访问则报错:HTTP Status 405 - Request method 'GET' not supported
GET和POST都可以@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})
Controller方法返回值
返回ModelAndView
controller方法中定义ModelAndView对象并返回,可添加model数据、指定view
返回void
request转发
request.getRequestDispatcher("页面路径").forward(request, response);
request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);
response重定向
response.sendRedirect("url")
response.sendRedirect("/springmvc-web2/itemEdit.action");
response指定响应结果,例如响应json数据
response.getWriter().print("{\"abc\":123}");
返回字符串
逻辑视图名
controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
/WEB-INF/jsp/itemList.jsp
return "itemList";
Redirect重定向
Contrller方法返回字符串可以重定向到一个url地址,重定向后浏览器地址栏变更为重定向的地址,
重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
return "redirect:/itemEdit.action?itemId=" + item.getId();
forward转发
Controller方法执行后继续执行另一个Controller方法
修改商品成功后,继续执行另一个方法,使用转发的方式实现。转发后浏览器地址栏还是原来的请求地址,
转发并没有执行新的request和response,所以之前的请求参数都存在
return "forward:/itemEdit.action";
Model/ModelMap(返回处理结果给页面的方法)
Model
除了ModelAndView以外,还可以使用Model来向页面传递数据
Model是一个接口,在参数里直接声明model即可
如果使用Model则可以不使用ModelAndView对象,
Model对象可以向页面传递数据,View对象则可以使用String返回值替代。
不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。
@RequestMapping("/itemEdit")
public String queryItemById(HttpServletRequest request, Model model) {
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.addObject("item", item);
// 设置逻辑视图
// modelAndView.setViewName("itemEdit");
model.addAttribute("item", item);
return "itemEdit";
}
ModelMap
ModelMap是Model接口的实现类,也可以通过ModelMap向页面传递数据
使用Model和ModelMap的效果一样,如果直接使用Model,
springmvc会实例化ModelMap。
@RequestMapping("/itemEdit")
public String queryItemById(HttpServletRequest request, ModelMap model) {
model.addAttribute("item", item);
return "itemEdit";
}
8. 异常处理器
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,
自定义异常类
如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
public class MyException extends Exception {
private String message;
public MyException() {
super();
}
public MyException(String message) {
super();
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
自定义异常处理器
public class CustomHandleException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception exception) {
String msg;
if (exception instanceof MyException) {
// 如果是自定义异常,读取异常信息
msg = exception.getMessage();
} else {
// 如果是运行时异常,则取错误堆栈,从堆栈中获取异常信息
Writer out = new StringWriter();
PrintWriter s = new PrintWriter(out);
exception.printStackTrace(s);
msg = out.toString();
}
// 把错误信息发给相关人员,邮件,短信等方式
// 返回错误页面,给用户友好页面显示错误信息
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", msg);
modelAndView.setViewName("error");
return modelAndView;
}
}
在springmvc.xml中添加:
<!-- 配置全局异常处理器 -->
<bean id="customHandleException" class="cn.itcast.ssm.exception.CustomHandleException"/>
错误页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>异常信息</h1><br />
<h2>${msg }</h2>
</body>
</html>
异常测试
修改ItemController方法“queryItemList”,抛出异常:
@RequestMapping(value = { "itemList", "itemListAll" })
public ModelAndView queryItemList() throws Exception {
// 自定义异常
if (true) {
throw new MyException("自定义异常出现了~");
}
// 运行时异常
int a = 1 / 0;
// 查询商品数据
List<Item> list = this.itemService.queryItemList();
// 创建ModelAndView,设置逻辑视图名
ModelAndView mv = new ModelAndView("itemList");
// 把商品数据放到模型中
mv.addObject("itemList", list);
return mv;
}
9. ssm整合思路
创建数据库和表
导入的jar包
aopalliance-1.0.jar
asm-3.3.1.jar
aspectjweaver-1.6.11.jar
cglib-2.2.2.jar
commons-dbcp-1.2.2.jar
commons-logging-1.1.1.jar
commons-pool-1.3.jar
javassist-3.17.1-GA.jar
jstl-1.2.jar
junit-4.9.jar
log4j-1.2.17.jar
log4j-api-2.0-rc1.jar
log4j-core-2.0-rc1.jar
mybatis-3.2.7.jar
mybatis-spring-1.2.2.jar
mysql-connector-java-5.1.7-bin.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
spring-aop-4.1.3.RELEASE.jar
spring-aspects-4.1.3.RELEASE.jar
spring-beans-4.1.3.RELEASE.jar
spring-context-4.1.3.RELEASE.jar
spring-context-support-4.1.3.RELEASE.jar
spring-core-4.1.3.RELEASE.jar
spring-expression-4.1.3.RELEASE.jar
spring-jdbc-4.1.3.RELEASE.jar
spring-jms-4.1.3.RELEASE.jar
spring-messaging-4.1.3.RELEASE.jar
spring-tx-4.1.3.RELEASE.jar
spring-web-4.1.3.RELEASE.jar
spring-webmvc-4.1.3.RELEASE.jar
创建动态web工程springmvc-web(2.5)
加入sqlMapConfig.xml配置文件
在src下创建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>
加入UserMapper.xml配置文件
applicationContext-dao.xml
配置数据源、配置SqlSessionFactory、mapper扫描器。
<?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">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<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">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
</bean>
<!-- 配置Mapper扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置Mapper的接口所在的扫描包,
同时默认扫描了同包下的同类名的Mapper.xml文件 mapper接口方式开发,
整合后的spring默认加载与接口同包下与接口同名的Mapper文件,
而dao开发就要手动配置mapper的位置,如果没找到就报错,
可以在sqlMapperConfig.xml配置mapper resourc解决-->
<property name="basePackage" value="cn.itcast.ssm.mapper" />
</bean>
</beans>
db.properties
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扫描 -->
<context:component-scan base-package="cn.itcast.ssm.service" />
</beans>
applicationContext-trans.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">
<!-- 事务管理器 -->
<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.ssm.service.*.*(..))" />
</aop:config>
</beans>
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">
<!-- 配置controller扫描包 -->
<context:component-scan base-package="cn.itcast.ssm.controller" />
<!-- 注解驱动 -->
<mvc:annotation-driven />
<!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test"->
"/WEB-INF/jsp/test.jsp" -->
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置逻辑视图的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置逻辑视图的后缀 -->
<property name="suffix" value=".jsp" />
</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">
<display-name>springmvc-web</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<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>
<servlet>
<servlet-name>springmvc-web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-web</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
加入jsp页面
itemList.jsp和itemEdit.jsp到工程中
DAO开发
mapper.xml配置文件
使用逆向工程,生成配置文件,将生成的包复制粘贴到工程下面
ItemService接口
public interface ItemService {
List<Item> queryItemList();
}
ItemServiceImpl实现类
@Service
public class ItemServiceImpl implements ItemService {
@Autowired
private ItemMapper itemMapper;
@Override
public List<Item> queryItemList() {
List<Item> list = this.itemMapper.selectByExample(null);
return list;
}
}
ItemController
@Controller
public class ItemController {
@Autowired
private ItemService itemService;
@RequestMapping("/itemList")
public ModelAndView queryItemList() {
// 获取商品数据
List<Item> list = this.itemService.queryItemList();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemList", list);
modelAndView.setViewName("itemList");
return modelAndView;
}
}
测试访问url:http://127.0.0.1:8080/springmvc-web/itemList.action
10. 上传图片
- 配置虚拟目录
- 在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml中添加:
- 访问http://localhost:8080/pic即可访问D:\develop\upload\temp下的图片。
- 也可以通过eclipse配置,如下图:
- 复制一张图片到存放图片的文件夹,使用浏览器访问
- 测试效果,并复制一张图片到存放图片的文件夹
加入jar包
实现图片上传需要加入的jar包,fileupload和io包、放到工程的lib文件夹中
在springmvc.xml中配置文件上传解析器
<!-- 文件上传,id必须设置为multipartResolver -->
<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
!-- 设置文件上传大小 -->
<property name="maxUploadSize" value="5000000" />
</bean>
jsp页面修改
在商品修改页面,打开图片上传功能
<tr>
<td>商品图片</td>
<td>
<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<form id="itemForm" action="" method="post" enctype="multipart/form-data">
<c:if test="${item.pic !=null}">
<img src="/pic/${item.pic}" width=100 height=100/><br/>
</c:if>
<input type="file" name="pictureFile"/>
</form>
</td>
</tr>
图片上传方法
@RequestMapping("updateItem")
public String updateItemById(Item item, MultipartFile pictureFile) throws Exception {
// 图片上传
// 设置图片名称,不能重复,可以使用uuid
String picName = UUID.randomUUID().toString();
// 获取文件名
String oriName = pictureFile.getOriginalFilename();
// 获取图片后缀
String extName = oriName.substring(oriName.lastIndexOf("."));
// 开始上传
pictureFile.transferTo(new File("C:/upload/image/" + picName + extName));
// 设置图片名到商品中
item.setPic(picName + extName);
// ---------------------------------------------
// 更新商品
this.itemService.updateItemById(item);
return "forward:/itemEdit.action";
}
json数据交互
@RequestBody
用于读取http请求的内容(字符串),通过springmvc的HttpMessageConverter接口
将读到的内容(json数据)转换为java对象并绑定到Controller方法的参数上。
传统的请求参数:itemEdit.action?id=1&name=zhangsan&age=12
现在的请求参数:使用POST请求,在请求体里面加入json数据
{
"id": 1,
"name": "测试商品",
"price": 99.9,
"detail": "测试商品描述",
"pic": "123456.jpg"
}
@ResponseBody
用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口
转换为指定格式的数据如:json,xml等,通过Response响应给客户端
请求json,响应json实现:
加入jar包
jackson-annotations-2.4.0.jar
jackson-core-2.4.2.jar
jackson-databind-2.4.2.jar
ItemController编写
测试json的交互
@RequestMapping("testJson")
public @ResponseBody Item testJson(@RequestBody Item item) {
return item;
}
配置json转换器
如果不使用注解驱动<mvc:annotation-driven />,就需要给处理器适配器配置json转换器,
在springmvc.xml配置文件中,给处理器适配器加入json转换器:
<!--处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.
MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
解决post乱码问题
在web.xml中加入:
<!-- 解决post乱码问题 -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置编码参是UTF8 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
解决get请求乱码
①修改tomcat配置文件添加编码与工程编码一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
②另外一种方法对参数进行重新编码:
String userName =new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
11. RESTful支持
Restful就是一个资源定位及资源操作的风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,
使用不同方法对资源进行操作。分别对应 添加、 删除、修改、查询。
传统方式操作资源
http://127.0.0.1/item/queryItem.action?id=1查询,GET
http://127.0.0.1/item/saveItem.action新增,POST
http://127.0.0.1/item/updateItem.action更新,POST
http://127.0.0.1/item/deleteItem.action?id=1删除,GET或POST
使用RESTful操作资源
http://127.0.0.1/item/1查询,GET
http://127.0.0.1/item新增,POST
http://127.0.0.1/item更新,PUT
http://127.0.0.1/item/1删除,DELETE
需求
RESTful方式实现商品信息查询,返回json数据
从URL上获取参数
使用RESTful风格开发的接口,根据id查询商品,接口地址是:
http://127.0.0.1/item/1
我们需要从url上获取商品id,步骤如下:
1.@RequestMapping("item/{id}")声明请求的url
{xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”
2.使用(@PathVariable() Integer id)获取url上的数据
* 使用RESTful风格开发接口,实现根据id查询商品
@RequestMapping("item/{id}")
@ResponseBody
public Item queryItemById(@PathVariable() Integer id) {
Item item = this.itemService.queryItemById(id);
return item;
}
如果@RequestMapping中表示为"item/{id}",id和形参名称一致,
@PathVariable不用指定名称。如果不一致,例如"item/{ItemId}"
则需要指定名称@PathVariable("itemId")。
http://127.0.0.1/item/123?id=1
注意两个区别
1.@PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)
2.如果加上@ResponseBody注解,就不会走视图解析器,
不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面
12. 拦截器
Spring Web MVC 的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理
拦截器定义
实现HandlerInterceptor接口,如下:
public class HandlerInterceptor1 implements HandlerInterceptor {
// controller执行后且视图返回后调用此方法
// 这里可得到执行controller时的异常信息
// 这里可记录操作日志
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("HandlerInterceptor1....afterCompletion");
}
// controller执行后但未返回视图前调用此方法
// 这里可在返回用户前对模型数据进行加工处理,
比如这里加入公用信息以便页面显示
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("HandlerInterceptor1....postHandle");
}
// Controller执行前调用此方法
// 返回true表示继续执行,返回false中止执行
// 这里可以加入登录校验、权限拦截等
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("HandlerInterceptor1....preHandle");
// 设置为true,测试使用
return true;
}
}
拦截器配置
上面定义的拦截器再复制一份HandlerInterceptor2,注意新的拦截器修改代码:
System.out.println("HandlerInterceptor2....preHandle");
在springmvc.xml中配置拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 所有的请求都进入拦截器 -->
<mvc:mapping path="/**" />
<!-- 配置具体的拦截器 -->
<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
正常流程测试
浏览器访问地址http://127.0.0.1:8080/springmvc-web2/itemList.action
运行流程
HandlerInterceptor1..preHandle..
HandlerInterceptor2..preHandle..
HandlerInterceptor2..postHandle..
HandlerInterceptor1..postHandle..
HandlerInterceptor2..afterCompletion..
HandlerInterceptor1..afterCompletion..
中断流程测试
浏览器访问地址http://127.0.0.1:8080/springmvc-web2/itemList.action
运行流程
HandlerInterceptor1的preHandler方法返回false,
HandlerInterceptor2返回true,运行流程如下:
HandlerInterceptor1..preHandle..
从日志看出第一个拦截器的preHandler方法返回false
后第一个拦截器只执行了preHandler方法,其它两个方法没有执行,
第二个拦截器的所有方法不执行,且Controller也不执行了。
HandlerInterceptor1的preHandler方法返回true,
HandlerInterceptor2返回false,运行流程如下:
HandlerInterceptor1..preHandle..
HandlerInterceptor2..preHandle..
HandlerInterceptor1..afterCompletion..
从日志看出第二个拦截器的preHandler方法返回false
后第一个拦截器的postHandler没有执行,
第二个拦截器的postHandler和afterCompletion没有执行,且controller也不执行了。
总结:
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
postHandler在拦截器链内所有拦截器返成功调用
afterCompletion只有preHandle返回true才调用
总结
本文介绍了的springmvc使用,如有问题欢迎私信和评论