本帖最后由 cyahua 于 2018-8-17 11:58 编辑
Spring MVC 笔记 Spring MVC处理流程- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
- 执行处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户
组件说明DispatcherServlet:前端控制器 用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。 HandlerMapping:处理器映射器 HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。 Handler:处理器 Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。 由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。 HandlAdapter:处理器适配器 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行 View Resolver:视图解析器 springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
问题:Spring MVC三大组件有哪些?
在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。 需要用户开发的组件有handler 和view
Spring MVC基础配置[XML] 纯文本查看 复制代码 <!-- 扫描controller注解,多个包中间使用半角逗号分隔 -->
<context:component-scan base-package="cn.itcast.springmvc.controller"/>
注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method。 从spring3.1版本开始,废除了DefaultAnnotationHandlerMapping的使用,推荐使用RequestMappingHandlerMapping完成注解式处理器映射。 [XML] 纯文本查看 复制代码 <!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
注解式处理器适配器,对标记@ResquestMapping的方法进行适配 从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。 [XML] 纯文本查看 复制代码 <!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<mvc:annotation-driven>
springmvc使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter,可用在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。
配置前缀和后缀 [XML] 纯文本查看 复制代码 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
InternalResourceViewResolver:支持JSP视图解析 viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,所以classpath中必须包含jstl的相关jar 包。此属性可以不设置,默认为JstlView。 prefix 和suffix:查找视图页面的前缀和后缀,最终视图的址为: 前缀+逻辑视图名+后缀,逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为hello,则最终返回的jsp视图地址 “WEB-INF/jsp/hello.jsp”
SSM整合整合思路Dao层
Service层
表现层
Springmvc.xml
包扫描器,扫描@Controller注解的类。 配置注解驱动。 视图解析器
Web.xml
配置前端控制器。 spring容器加载 CharacterEncodingFilter
配置文件[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>
[XML] 纯文本查看 复制代码 </configuration><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans [url=http://www.springframework.org/schema/beans/spring-beans-4.0.xsd]http://www.springframework.org/schema/beans/spring-beans-4.0.xsd[/url]
[url=http://www.springframework.org/schema/context]http://www.springframework.org/schema/context[/url] [url=http://www.springframework.org/s]http://www.springframework.org/s[/url] ... ing-context-4.0.xsd">
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--数据库连接池-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:SqlMapConfig.xml"/>
</bean>
<!--扫描Mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.springmvc.mapper"/>
</bean>
</beans>
[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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans [url=http://www.springframework.org/schema/beans/spring-beans.xsd]http://www.springframework.org/schema/beans/spring-beans.xsd[/url] [url=http://www.springframework.org/schema/context]http://www.springframework.org/schema/context[/url] [url=http://www.springframework.org/schema/context/spring-context.xsd]http://www.springframework.org/schema/context/spring-context.xsd[/url] [url=http://www.springframework.org/schema/tx]http://www.springframework.org/schema/tx[/url] [url=http://www.springframework.org/schema/tx/spring-tx.xsd]http://www.springframework.org/schema/tx/spring-tx.xsd[/url] [url=http://www.springframework.org/schema/aop]http://www.springframework.org/schema/aop[/url] [url=http://www.springframework.org/schema/aop/spring-aop.xsd]http://www.springframework.org/schema/aop/spring-aop.xsd[/url]">
<!--包扫描-->
<context:component-scan base-package="com.itheima.springmvc.service"/>
<!-- 事务管理器 -->
<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="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.itheima.springmvc.service.*.*(..))" />
</aop:config>
</beans>
[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" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans [url=http://www.springframework.org/schema/beans/spring-beans-4.0.xsd]http://www.springframework.org/schema/beans/spring-beans-4.0.xsd[/url]
[url=http://www.springframework.org/schema/context]http://www.springframework.org/schema/context[/url] [url=http://www.springframework.org/s]http://www.springframework.org/s[/url] ... ing-context-4.0.xsd
[url=http://www.springframework.org/schema/aop]http://www.springframework.org/schema/aop[/url] [url=http://www.springframework.org/schema/aop/spring-aop-4.0.xsd]http://www.springframework.org/schema/aop/spring-aop-4.0.xsd[/url] [url=http://www.springframework.org/schema/tx]http://www.springframework.org/schema/tx[/url] [url=http://www.springframework.org/schema/tx/spring-tx-4.0.xsd]http://www.springframework.org/schema/tx/spring-tx-4.0.xsd[/url]
[url=http://www.springframework.org/schema/util]http://www.springframework.org/schema/util[/url] [url=http://www.springframework.org/schema/util/spring-util-4.0.xsd]http://www.springframework.org/schema/util/spring-util-4.0.xsd[/url] [url=http://www.springframework.org/schema/mvc]http://www.springframework.org/schema/mvc[/url] [url=http://www.springframework.org/schema/mvc/spring-mvc.xsd]http://www.springframework.org/schema/mvc/spring-mvc.xsd[/url]">
<!-- 扫描带Controller注解的类 -->
<context:component-scan base-package="com.itheima.springmvc.controller"/>
<!-- 加载注解驱动 -->
<!--<mvc:annotation-driven conversion-service="conversionService"/>-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<!-- jsp前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- jsp后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
<!--日期转换器-->
<!--如果在类中加上@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss"),就不用再配置-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.springmvc.converter.DateConverter"/>
</set>
</property>
</bean>
<!--异常处理器-->
<bean class="com.itheima.springmvc.exceptionresolver.CustomerExceptionResolver"/>
<!--多媒体解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--最大上传问价1M-->
<property name="maxUploadSize" value="1048576"/>
</bean>
<!--资源映射-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
</beans>
参数绑定支持的数据类型 解决乱码post乱码 web.xml中配置filter [XML] 纯文本查看 复制代码 <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> get乱码 方法1 修改tomcat配置文件添加编码与工程编码一致,如下: [XML] 纯文本查看 复制代码 <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> 方法2 [Java] 纯文本查看 复制代码 String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8"); 自定义Converter继承Converter接口 [Java] 纯文本查看 复制代码 public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
配置converter [XML] 纯文本查看 复制代码 <!-- 转换器配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.springmvc.convert.DateConverter"/>
</set>
</property>
</bean>
springmvc与struts2区别springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。 springmvc是基于方法开发(一个ur对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。Jsp视图解析器默认使用jstl。
相关注解@RequestMapping value:请求路径 method:接受指定请求方式的参数
@RequestParam当前台参数与接收名称不一致时使用 value:前台参数名称 required:是否必须,当为true时,前台必须传递此参数,否则报400错误 defaultValue:当前台没有传递该参数时的默认值
@RequestBody @ResponseBody @PathVariable jsp中<c:forEach>标签的varStatus属性varStatus属性常用参数总结下: ${status.index} 输出行号,从0开始。 ${status.count} 输出行号,从1开始。 ${status.current} 当前这次迭代的(集合中的)项 ${status.first} 判断当前项是否为集合中的第一项,返回值为true或false ${status.last} 判断当前项是否为集合中的最后一项,返回值为true或false begin、end、step分别表示:起始序号,结束序号,跳跃步伐。 Controller中方法的返回值ModelAndView String
直接返回视图名 "redirect:重定向地址"
如果方法参数中有Model,重定向时会自动在地址后拼接model中的参数 使用RedirectAttributes,有一个方法叫做addFlashAttribute
"forward:转发地址"
void
Object
重定向和转发区别全局异常处理器自定义异常类 [Java] 纯文本查看 复制代码 public class CustomException extends Exception {
/** serialVersionUID*/
private static final long serialVersionUID = -5212079010855161498L;
public CustomException(String message){
super(message);
this.message = message;
}
//异常信息
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
自定义全局异常处理器 [Java] 纯文本查看 复制代码 public class CustomerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handle, Exception e) {
String message = null;
ModelAndView modelAndView = new ModelAndView();
if (e instanceof CustomerException) {
CustomerException customerException = (CustomerException) e;
message = customerException.getMessage();
} else {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
message = stringWriter.toString();
}
modelAndView.addObject("message", message);
modelAndView.setViewName("error");
return modelAndView;
}
}
编写错误页面 [HTML] 纯文本查看 复制代码 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!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>错误页面</title>
</head>
<body>
您的操作出现错误如下:<br/>
${message }
</body>
</html>
配置异常处理器 [XML] 纯文本查看 复制代码 <!-- 异常处理器 -->
<bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/> 上传图片配置解析器 [XML] 纯文本查看 复制代码 <!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
Controller [Java] 纯文本查看 复制代码 @RequestMapping("/updateitem.action")
public String itemUpdate(Items items, MultipartFile pictureFile,Model model) throws IOException {
if (pictureFile != null) {
String originalFilename = pictureFile.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID().toString()+suffix;
File file = new File("D:/tmp/pic");
if(!file.exists()){
file.mkdirs();
}
pictureFile.transferTo(new File(file,fileName));
model.addAttribute("id", items.getId());
items.setPic(fileName);
}
itermsService.updateItems(items);
return "redirect:itemEdit.action";
}
前台页面 [HTML] 纯文本查看 复制代码 <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" enctype="multipart/form-data" method="post">
<tr>
<td>商品图片</td>
<td>
<c:if test="${item.pic !=null}">
<img src="/pic/${item.pic}" width=100 height=100/>
<br/>
</c:if>
<input type="file" name="pictureFile"/>
</td>
</tr>
</form> Json交互406错误:没有导入json的jar包 @RestController相当于在类上添加@Controller和@ResponseBody @RequestBody @ResponseBody 配置json转换器 [XML] 纯文本查看 复制代码 <!--注解适配器 -->
<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>
注意:如果使用<mvc:annotation-driven /> 则不用配置上边的内容 REstfull支持Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。 资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数 资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。Put和Delete几乎不使用。 配置DispatcherServlet拦截路径 [XML] 纯文本查看 复制代码 <servlet>
<servlet-name>springmvc-servlet-rest</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-servlet-rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springMVC的url-pattern中的路径写法含义: / 表示拦截除.jsp和.jspx外的所有请求, /* 表示拦截所有请求 / 不拦截.jsp和.jspx的原因: %tomcat%\conf\web.xml中有如下配置: [XML] 纯文本查看 复制代码 <servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
Controller中注解的写法 [Java] 纯文本查看 复制代码 @RequestMapping("/viewItems/{id}")
public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
//方法中使用@PathVariable获取useried的值,使用model传回页面
//调用 service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(id);
return itemsCustom;
}
如何传递多个参数? 路径的写法:"/viewItems/{id}/name/{name}" 配置资源映射 由于Restfull风格的url-pattern拦截了所有的路径,所以要配置资源映射 [XML] 纯文本查看 复制代码 <!--在srping-mvc.xml中配置-->
<!-- /** 表示包含子目录 -->
<mvc:resources location="/js/" mapping="/js/**"/>
拦截器Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。 intercepter执行顺序 按照配置文件中的配置顺序执行 preHandle方法按照配置文件中的顺序执行 postHandle和afterCompletion按照倒序执行 postHandler在拦截器链内所有拦截器返成功调用 afterCompletion只有preHandle返回true才调用 如果转发到的是系统内部的方法,拦截器会拦截,如果到的是视图,不会拦截 编写自定义Interceptor,实现HandlerInterceptor接口 [Java] 纯文本查看 复制代码 public class UserLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("拦截执行");
String url = httpServletRequest.getRequestURL().toString();
if(url.contains("login")){
return true;
}
Object user = httpServletRequest.getSession().getAttribute("user");
if(user !=null){
return true;
}
httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(httpServletRequest,httpServletResponse);
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
} mvc配置文件 [XML] 纯文本查看 复制代码 <!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.itheima.springmvc.interceptor.UserLoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
|