苏州建网站收费,济阳网站建设,网络营销推广怎么做,纯图片网站SpringMVC 进阶 
一、拦截器 
SpringMVC 中 Interceptor 拦截器的主要作⽤是拦截⽤⼾的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证#xff0c;或者是来判断⽤⼾是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两种#xff1a; 
实现接⼝#xff1a;org.springfram…SpringMVC 进阶 
一、拦截器 
SpringMVC 中 Interceptor 拦截器的主要作⽤是拦截⽤⼾的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证或者是来判断⽤⼾是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两种 
实现接⼝org.springframework.web.servlet.HandlerInterceptor 
继承适配器org.springframework.web.servlet.handler.HandlerInterceptorAdapter 
1.拦截器实现 
实现 HandlerInterceptor 接⼝ 
/*** 拦截器的实现*  实现 HandlerInterceptor 接口*/
public class MyInterceptor01 implements HandlerInterceptor {/*** 在目标Handler(方法)执行前执行*      返回true执行Handler方法*      返回false阻止目标Handler执行* param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(目标Handler执行前执行MyInterceptor01 -- preHandle方法...);/*** 返回true执行Handler方法* 返回false阻止目标Handler执行*/return true;}/*** 在 目标Handler(方法)执行后视图生成前 执行* param request* param response* param handler* param modelAndView* throws Exception*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(目标Handler执行后视图生成前执行MyInterceptor01 -- postHandle方法...);}/*** 在 目标Handler(方法)执行后视图生成后 执行* param request* param response* param handler* param ex* throws Exception*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(目标Handler执行后视图生成后执行MyInterceptor01 -- afterCompletion方法...);}
} 
拦截器xml配置 
!-- 拦截器配置方式一 --mvc:interceptors!--使用bean标签定义一个Interceptor直接定义在mvc:interceptors标签中表示拦截器会拦截所有的请求--bean classcom.xxxx.springmvc.interceptor.MyInterceptor01//mvc:interceptors!-- 拦截器配置方式二 推荐使用 --mvc:interceptors!--定义在 mvc:interceptor 标签中可以自定义需要被拦截的请求。可以定义多个拦截器。如果有多个拦截器则会根据配置的先后顺序来执行--mvc:interceptor!-- 通过 mvc:mapping 配置需要被拦截的资源。支持通配符。可配置多个。 --!-- /**表示拦截所有的请求 --mvc:mapping path/**/!-- 通过 mvc:exclude-mapping 标签配置不需要拦截的资源。支持通配符。可配置多个。--!--/url/表示url路径下的所有资源 --mvc:exclude-mapping path/url/*/bean classcom.xxxx.springmvc.interceptor.MyInterceptor01//mvc:interceptor/mvc:interceptors 
继承 HandlerInterceptorAdapter 
实际上最终还是 HandlerInterceptor 接⼝实现。 
子类实现类 
/*** 拦截器实现*      继承 HandlerInterceptorAdapter 适配器*/
public class MyInterceptor02 extends HandlerInterceptorAdapter {/*** 在 目标Handler(方法)执行前 执行*      返回true执行Handler方法*      返回false阻止目标Handler执行* param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(目标Handler执行前执行MyInterceptor02 -- preHandle方法...);return true;}/*** 在 目标Handler(方法)执行后视图生成前 执行* param request* param response* param handler* param modelAndView* throws Exception*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(目标Handler执行后视图生成前执行MyInterceptor02 -- postHandle方法...);}/*** 在 目标Handler(方法)执行后视图生成后 执行* param request* param response* param handler* param ex* throws Exception*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(目标Handler执行后视图生成后执行MyInterceptor02 -- afterCompletion方法...);}
} 
拦截器xml配置 
mvc:interceptorsmvc:interceptor!-- 拦截的资源 --mvc:mapping path/**/!-- 放行的资源 --mvc:exclude-mapping path/url/test01/mvc:exclude-mapping path/url/test02/bean classcom.xxxx.springmvc.interceptor.MyInterceptor02//mvc:interceptor
/mvc:interceptors多个拦截器实现 
SpringMVC 框架⽀持多个拦截器配置从⽽构成拦截器链对客⼾端请求进⾏多次拦截操作。 
拦截器代码实现 
这⾥参考MyInterceptor01、MyInterceptor02代码 
拦截器xml配置 
mvc:interceptors!--拦截器链多个拦截器如果有多个拦截满足拦截的要求则会根据配置的先后顺序执行先配置的拦截器的 preHandle方法先执行先配置的拦截器的 postHandle、afterCompletion方法后执行--mvc:interceptormvc:mapping path/**/bean classcom.xxxx.springmvc.interceptor.MyInterceptor02//mvc:interceptormvc:interceptormvc:mapping path/**/bean classcom.xxxx.springmvc.interceptor.MyInterceptor01//mvc:interceptor/mvc:interceptors2.拦截器应用 - 非法请求拦截 
使⽤拦截器完成⽤⼾是否登录请求验证功能 
用户控制器 
UserInfoController 定义 
/*** 用户模块*      用户登录 不需要拦截*      用户添加 需要拦截*      用户更新 需要拦截*      用户删除 需要拦截*/
Controller
RequestMapping(/userInfo)
public class UserInfoController {/*** 用户登录* return*/RequestMapping(/login)public ModelAndView userLogin(HttpSession session){System.out.println(用户登录...);ModelAndView modelAndView  new ModelAndView();// 设置视图modelAndView.setViewName(success);// 如果用户登录则设置用户对象到session作用域中User user  new User();user.setId(1);user.setUserName(admin);user.setUserPwd(123456);session.setAttribute(user, user);return modelAndView;}/*** 用户添加* return*/RequestMapping(/add)public ModelAndView userAdd(){System.out.println(用户添加...);ModelAndView modelAndView  new ModelAndView();// 设置视图modelAndView.setViewName(success);return modelAndView;}/*** 用户更新* return*/RequestMapping(/update)public ModelAndView userupdate(){System.out.println(用户更新...);ModelAndView modelAndView  new ModelAndView();// 设置视图modelAndView.setViewName(success);return modelAndView;}/*** 用户删除* return*/RequestMapping(/delete)public ModelAndView userDelete(){System.out.println(用户删除...);ModelAndView modelAndView  new ModelAndView();// 设置视图modelAndView.setViewName(success);return modelAndView;}
}页面定义 
success.jsp 定义 
% page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitleTitle/title
/head
bodyh3登录页面/h3
/body
/html 
非法请求拦截器定义 
LoginInterceptor 定义 
public class LoginInterceptor extends HandlerInterceptorAdapter {/*** 在 目标方法执行前 执行* param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取session作用域中的user对象User user  (User) request.getSession().getAttribute(user);// 判断session作用域的user对象是否为空if (user  null){ // 如果为空表示用户未登录// 拦截请求并跳转到登录页面response.sendRedirect(request.getContextPath()  /login.jsp);// 不执行目标方法return false;}// 执行目标方法return true;}
}拦截器xml配置 
servlet-context.xml 配置 
!-- 非法访问拦截 拦截器 --
mvc:interceptorsmvc:interceptor!-- 拦截所有请求 --mvc:mapping path/**/mvc:exclude-mapping path/userInfo/login/mvc:exclude-mapping path/uploadFile/mvc:exclude-mapping path/uploadFiles/bean classcom.xxxx.springmvc.interceptor.LoginInterceptor//mvc:interceptor
/mvc:interceptors二、文件上传 
1.环境配置 
pom.xml文件修改 !-- 添加 commons-fileupload 依赖 --dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.2/version/dependencyservlet-context.xml修改 
!-- 文件上传 --bean idmultipartResolverclassorg.springframework.web.multipart.commons.CommonsMultipartResolver!-- 允许文件上传的最大尺寸 --property namemaxUploadSizevalue104857600/value/property!--设置文件放入临时文件夹的最大大小限制。此值是阈值低于此值则保存在内存中如高于此值则生成硬盘上的临时文件。--property namemaxInMemorySizevalue4096/value/property/bean 
2.代码实现 
单文件上传 
页面表单 
input 的type设置为file 
form 表单的method设为post 
form 表单的enctype设置为multipart/form-data以⼆进制的形式传输数据 
form methodpost actionuploadFile enctypemultipart/form-datainput typefile namefile/button上传/button
/form代码实现 
/*** 单文件上传** return*/
Controller
public class FileController {RequestMapping(/uploadFile)public String uploadFile(HttpServletRequest request, RequestParam(file) MultipartFile file) {// 判断文件是否为空如果不为空则进行对应的文件上传操作if (!file.isEmpty()) {try {// 获取项目所在的路径 绝对路径String path  request.getServletContext().getRealPath(/);// 设置上传文件存放的目录File uploadFile  new File(path  /upload);// 判断文件目录是否存在如果不存在则新建对应的目录if (!uploadFile.exists()) {// 新建目录uploadFile.mkdir();}// 获取上传文件的文件名String originalName  file.getOriginalFilename();// 获取上传文件的后缀名String suffix  originalName.substring(originalName.lastIndexOf(.));// 通过系统当前时间的毫秒数生成随机的文件名String fileName  System.currentTimeMillis()  suffix;// 上传文件 转存文件到指定目录file.transferTo(new File(uploadFile, fileName));// 如果上传成功设置作用域request.setAttribute(msg, 文件上传成功);} catch (IOException e) {e.printStackTrace();// 如果上传失败设置作用域request.setAttribute(msg, 文件上传失败);}} else {// 如果上传文件不存在设置作用域request.setAttribute(msg, 文件不存在);}return result;}
}多文件件上传 
页面表单 form methodpost actionuploadFiles enctypemultipart/form-datainput typefile namefiles/input typefile namefiles/button上传/button/form代码实现 RequestMapping(/uploadFiles)public String uploadFiles(HttpServletRequest request, RequestParam(files) ListMultipartFile files){// 判断文件集合是否为空if (files ! null  files.size()  0) {for (MultipartFile file : files ) {// 上传文件saveFile(file, request);}}return result;}/*** 上传文件* param file* param request*/public void saveFile(MultipartFile file, HttpServletRequest request) {// 判断文件是否为空如果不为空则进行对应的文件上传操作if (!file.isEmpty()) {try {// 获取项目所在的路径 绝对路径String path  request.getServletContext().getRealPath(/);// 设置上传文件存放的目录File uploadFile  new File(path  /upload);// 判断文件目录是否存在如果不存在则新建对应的目录if (!uploadFile.exists()) {// 新建目录uploadFile.mkdir();}// 获取上传文件的文件名String originalName  file.getOriginalFilename();// 获取上传文件的后缀名String suffix  originalName.substring(originalName.lastIndexOf(.));// 通过系统当前时间的毫秒数生成随机的文件名String fileName  System.currentTimeMillis()  suffix;// 上传文件 转存文件到指定目录file.transferTo(new File(uploadFile, fileName));// 如果上传成功设置作用域request.setAttribute(msg,文件上传成功);} catch (IOException e) {e.printStackTrace();// 如果上传失败设置作用域request.setAttribute(msg,文件上传失败);}} else {// 如果上传文件不存在设置作用域request.setAttribute(msg,文件不存在);}}三、SSM 框架集成与测试 
1.环境配置 
配置 pom.xml 
修改 JDK 版本 propertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.target/properties添加坐标依赖 
dependencies!-- junit 测试 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency!-- spring 核心jar --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.4.RELEASE/version/dependency!-- spring 测试jar --dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.2.4.RELEASE/version/dependency!-- spring jdbc --dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.2.4.RELEASE/version/dependency!-- spring事物 --dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.2.4.RELEASE/version/dependency!-- aspectj切面编程的jar --dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.5/version/dependency!-- c3p0 连接池 --dependencygroupIdcom.mchange/groupIdartifactIdc3p0/artifactIdversion0.9.5.2/version/dependency!-- mybatis --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.3/version/dependency!-- 添加mybatis与Spring整合的核心包 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.3/version/dependency!-- mysql 驱动包 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.19/version/dependency!-- 日志打印相关的jar --dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactIdversion1.7.2/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion1.7.2/version/dependency!-- 分页插件 --dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.1.10/version/dependency!-- spring web --dependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion5.2.4.RELEASE/version/dependency!-- spring mvc --dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.2.4.RELEASE/version/dependency!-- web servlet --dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.0.1/version/dependency!-- 添加json 依赖jar包注意版本问题 --dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.10.0/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.10.0/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.10.0/version/dependency!-- commons-fileupload --dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.2/version/dependency/dependencies设置资源目录和插件 
buildfinalNamessm/finalName!--Maven 项目:如果源代码(src/main/java)存在xml、properties、tld 等文件Maven 默认不会自动编译该文件到输出目录,如果要编译源代码中xml properties tld 等文件需要显式配置 resources 标签--resourcesresourcedirectorysrc/main/resources/directory/resourceresourcedirectorysrc/main/java/directoryincludesinclude**/*.xml/includeinclude**/*.properties/includeinclude**/*.tld/include/includesfilteringfalse/filtering/resource/resourcesplugins!-- 编译环境插件 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion2.3.2/versionconfigurationsource1.8/sourcetarget1.8/targetencodingUTF-8/encoding/configuration/plugin!-- jetty插件 --plugingroupIdorg.eclipse.jetty/groupIdartifactIdjetty-maven-plugin/artifactIdversion9.4.27.v20200227/versionconfigurationscanIntervalSeconds10/scanIntervalSeconds!-- 设置端口 --httpConnectorport8080/port/httpConnector!-- 设置项目路径 --webAppConfigcontextPath/ssm/contextPath/webAppConfig/configuration/plugin/plugins/build 
配置 web.xml 
?xml version1.0 encodingUTF-8?
web-app idWebApp_ID version3.0xmlnshttp://java.sun.com/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd!-- 启动spring容器--context-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:spring.xml/param-value/context-param!-- 设置监听器 --listenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!-- 编码过滤 utf-8 --filterdescriptionchar encoding filter/descriptionfilter-nameencodingFilter/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueUTF-8/param-value/init-param/filterfilter-mappingfilter-nameencodingFilter/filter-nameurl-pattern/*/url-pattern/filter-mapping!-- servlet请求分发器 --servletservlet-namespringMvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-classinit-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:servlet-context.xml/param-value/init-param!-- 表示启动容器时初始化该Servlet --load-on-startup1/load-on-startup/servletservlet-mappingservlet-namespringMvc/servlet-name!-- 这是拦截请求 /代表拦截所有请求*.do拦截所有.do请求 --url-pattern//url-pattern!--url-pattern*.do/url-pattern--/servlet-mapping/web-app配置 servlet-context.xml 
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:mvchttp://www.springframework.org/schema/mvcxmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!-- 开启扫描器 --context:component-scan base-packagecom.xxxx.ssm.controller /!-- mvc 注解驱动 并添加json 支持 --mvc:annotation-drivenmvc:message-converters!-- 返回信息为字符串时 处理 --bean classorg.springframework.http.converter.StringHttpMessageConverter/!-- 将对象转换为json 对象 --bean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//mvc:message-converters/mvc:annotation-driven!-- 使用默认的 Servlet 来响应静态文件 --mvc:default-servlet-handler/!-- 配置视图解析器 --bean classorg.springframework.web.servlet.view.InternalResourceViewResolveridinternalResourceViewResolver!-- 前缀在WEB-INF目录下的jsp目录下 --property nameprefix value/WEB-INF/jsp//!-- 后缀以.jsp结尾的资源 --property namesuffix value.jsp//bean!-- 文件上传 --bean idmultipartResolverclassorg.springframework.web.multipart.commons.CommonsMultipartResolver!-- 允许文件上传的最大尺寸 --property namemaxUploadSizevalue104857600/value/property!--设置文件放入临时文件夹的最大大小限制。此值是阈值低于此值则保存在内存中如高于此值则生成硬盘上的临时文件。--property namemaxInMemorySizevalue4096/value/property/bean/beans配置 spring.xml 
在项⽬的 src/main/resources 下创建 spring.xml ⽂件 内容如下 
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aop xmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd!-- 扫描基本包 --context:component-scan base-packagecom.xxxx.ssm !--  context:exclude-filter标签排除对某个注解的扫描 过滤controller层 --context:exclude-filter typeannotationexpressionorg.springframework.stereotype.Controller //context:component-scan!-- 加载properties 配置文件 --context:property-placeholder locationclasspath:db.properties /!-- aop --aop:aspectj-autoproxy /!-- 配置c3p0 数据源 --bean iddataSource classcom.mchange.v2.c3p0.ComboPooledDataSourceproperty namedriverClass value${jdbc.driver}/propertyproperty namejdbcUrl value${jdbc.url}/propertyproperty nameuser value${jdbc.username}/propertyproperty namepassword value${jdbc.password}/property/bean!-- 配置事务管理器 --bean idtxManagerclassorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource/property/bean!-- 设置事物增强 --tx:advice idtxAdvice transaction-managertxManagertx:attributestx:method nameadd* propagationREQUIRED /tx:method nameinsert* propagationREQUIRED /tx:method nameupdate* propagationREQUIRED /tx:method namedelete* propagationREQUIRED //tx:attributes/tx:advice!-- aop 切面配置 --aop:configaop:pointcut idservicePointcutexpressionexecution(* com.xxxx.ssm.service..*.*(..)) /aop:advisor advice-reftxAdvice pointcut-refservicePointcut //aop:config!-- 配置 sqlSessionFactory --bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/propertyproperty nameconfigLocation valueclasspath:mybatis.xml /property namemapperLocations valueclasspath:com/xxxx/ssm/mapper/*.xml //bean!-- 配置扫描器 --bean idmapperScanner classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 扫描com.xxxx.ssm.dao这个包以及它的子包下的所有映射接口类 --property namebasePackage valuecom.xxxx.ssm.dao /property namesqlSessionFactoryBeanName valuesqlSessionFactory //bean
/beans配置 mybatis.xml 
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationtypeAliasespackage namecom.xxxx.ssm.po//typeAliasespluginsplugin interceptorcom.github.pagehelper.PageInterceptor/plugin/plugins
/configuration配置 db.properties 
在项⽬的 src/main/resources 下创建 db.properties ⽂件内容如下(mysql 创建数据库ssm) 
jdbc.drivercom.mysql.cj.jdbc.Driver
jdbc.urljdbc:mysql://localhost:3306/ssm?useUnicodetruecharacterEncodingutf8serverTimezoneGMT%2B8useSSLfalse
jdbc.usernameroot
jdbc.passwordroot添加 log4j.properties 
在项⽬的 src/main/resources 下创建 log4j.properties ⽂件内容如下 
log4j.rootLoggerDEBUG, Console
# Console
log4j.appender.Consoleorg.apache.log4j.ConsoleAppender
log4j.appender.Console.layoutorg.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSetINFO
log4j.logger.org.apacheINFO
log4j.logger.java.sql.ConnectionDEBUG
log4j.logger.java.sql.StatementDEBUG
log4j.logger.java.sql.PreparedStatementDEBUG2.添加源代码 
添加包 
在项⽬的 src/main/java 下创建对应的包结构 
com.xxxx.ssm.controller 
com.xxxx.ssm.service 
com.xxxx.ssm.mapper 
com.xxxx.ssm.dao 
com.xxxx.ssm.po 
添加 User.java 
在 com.xxxx.ssm.po 包下创建 JavaBean ⽂件 User.java (数据库字段对应如下) public class User {private Integer userId;private String userName;private String userPwd;private String userEmail;private Date createDate;private Date updateDate;
}添加UserDao.java 接口 
com.xxxx.ssm.dao 包下创建 UserDao.java ⽂件提供对应的⽤⼾详情查询功能 
public interface UserDao {User queryUserByUserId(Integer userId);
} 
添加UserMapper.xml 映射文件 
com.xxxx.ssm.mapper 包下创建 UserMapper.xml ⽂件提供select 查询标签配置 
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.xxxx.ssm.dao.UserDaoselect idqueryUserByUserId parameterTypeint resultTypecom.xxxx.ssm.po.Userselect user_id as userId,user_name as userName,user_pwd as userPwdfrom tb_userwhere user_id  #{userId}/select
/mapper添加 UserService.java 
com.xxxx.ssm.service 包下创建UserService.java ⽂件提供⽤⼾详情查询⽅法 
Service
public class UserService {// 注入userDaoAutowiredprivate UserDao userDao;public User queryUserByUserId(Integer userId){User user  userDao.queryUserByUserId(userId);return user;}}添加 HelloController.java 
在 com.xxxx.ssm.controller 包下创建 HelloController.java ⽂件 
Controller
public class UserController extends BaseController {// 注入userServiceAutowiredprivate UserService userService;RequestMapping(/hello)public String hello (Model model){// 调用UserService层的方法User user  userService.queryUserByUserId(1);// 将数据存到model对象中model.addAttribute(user,user);return hello;}}添加 hello.jsp 视图⽂件 
在src/main/webapp/WEB-INF 创建jsp ⽬录并在该⽬下创建hello.jsp 展⽰查询的⽤⼾信息 
body欢迎你${user.userName}
/body四、RestFul URL 
模型 - 视图 - 控制器MVC是⼀个以设计界⾯应⽤程序为基础的设计思想。 
Restful ⻛格的 API 是⼀种软件架构⻛格设计⻛格⽽不是标准只是提供了⼀组设计原则和约束条件。它主要⽤于客⼾端和服务器交互类的软件。基于这个⻛格设计的软件可以更简洁更有层次更易于实现缓存等机制。 
在Restful ⻛格中⽤⼾请求的 url 使⽤同⼀个 url⽤请求⽅式getpostdeleteput…等⽅式对请求的处理⽅法进⾏区分这样可以在前后台分离式的开发中使得前端开发⼈员不会对请求的资源地址产⽣混淆和⼤量的检查⽅法名的⿇烦形成⼀个统⼀的接⼝。 
GETSELECT从服务器查询可以在服务器通过请求的参数区分查询的⽅式。 
POSTCREATE在服务器端新建⼀个资源调⽤ insert 操作。 
PUTUPDATE在服务器端更新资源调⽤ update 操作。 
PATCHUPDATE在服务器端更新资源客⼾端提供改变的属性。(⽬前 jdk7 未实现tomcat7 不⽀持)。 
DELETEDELETE从服务器端删除资源调⽤ delete 语句。 
1.SpringMVC 支持 RestFul URL 风格设计 
如何使用 Java 构造没有扩展名的RestFul URL 如 /forms/1? 
SpringMVC 是通过 RequestMapping 及 PathVariable 注解提供的。 
通过如RequestMapping(value“/blog /{id}”, method  RequestMethod.DELETE)即可处理 /blog/1 的 delete请求。 
2.RestFul URL 映射地址配置 
准备环境 
添加 Account 
在 src/resources/java 对应的 com.xxxx.ssm.po ⽬录下新建 Account.java 实体类 
public class Account {private Integer id;private String aname;private String type;private Double money;private Integer userId;private Date createTime;private Date updateTime;private String remark;}添加 AccountDao 
在 src/resources/java 对应的 com.xxxx.ssm.dao ⽬录下新建 AccountDao.java 接⼝类 
public interface AccountDao {public Account selectById(Integer id);public int save(Account account);public int update(Account account);public int delete(Integer id);
}添加 AccountMapper 
在 src/resources/java 对应的 com.xxxx.ssm.mapper ⽬录下新建 AccountMapper.xml 映射⽂件 
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd 
mapper namespacecom.xxxx.ssm.dao.AccountDao resultMap idBaseResultMap typecom.xxxx.ssm.po.Account id columnid propertyid jdbcTypeINTEGER /result columnaname propertyaname jdbcTypeVARCHAR /result columntype propertytype jdbcTypeVARCHAR /result columnmoney propertymoney jdbcTypeDOUBLE /result columnuser_id propertyuserId jdbcTypeINTEGER /result columncreate_time propertycreateTime jdbcTypeDATE /result columnupdate_time propertyupdateTime jdbcTypeDATE /result columnremark propertyremark jdbcTypeVARCHAR //resultMapsql idBase_Column_List id, aname, type, money, user_id, create_time, update_time, remark/sql!-- 查询操作 --select idselectById resultMapBaseResultMap parameterTypejava.lang.Integer selectinclude refidBase_Column_List /from tb_accountwhere id  #{id,jdbcTypeINTEGER}/select!-- 删除操作 --delete iddelete parameterTypejava.lang.Integer delete from tb_accountwhere id  #{id,jdbcTypeINTEGER}/delete!-- 添加操作 --insert idsave parameterTypecom.xxxx.ssm.po.Account insert into tb_accounttrim prefix( suffix) suffixOverrides, if testid ! null id,/ifif testaname ! null aname,/ifif testtype ! null type,/ifif testmoney ! null money,/ifif testuserId ! null user_id,/ifif testcreateTime ! null create_time,/ifif testupdateTime ! null update_time,/ifif testremark ! null remark,/if/trimtrim prefixvalues ( suffix) suffixOverrides, if testid ! null #{id,jdbcTypeINTEGER},/ifif testaname ! null #{aname,jdbcTypeVARCHAR},/ifif testtype ! null #{type,jdbcTypeVARCHAR},/ifif testmoney ! null #{money,jdbcTypeDOUBLE},/ifif testuserId ! null #{userId,jdbcTypeINTEGER},/ifif testcreateTime ! null #{createTime,jdbcTypeDATE},/ifif testupdateTime ! null #{updateTime,jdbcTypeDATE},/ifif testremark ! null #{remark,jdbcTypeVARCHAR},/if/trim/insert!-- 更新操作 --update idupdate parameterTypecom.xxxx.ssm.po.Account update tb_accountset if testaname ! null aname  #{aname,jdbcTypeVARCHAR},/ifif testtype ! null type  #{type,jdbcTypeVARCHAR},/ifif testmoney ! null money  #{money,jdbcTypeDOUBLE},/ifif testuserId ! null user_id  #{userId,jdbcTypeINTEGER},/ifif testcreateTime ! null create_time  #{createTime,jdbcTypeDATE},/ifif testupdateTime ! null update_time  #{updateTime,jdbcTypeDATE},/ifif testremark ! null remark  #{remark,jdbcTypeVARCHAR},/if/setwhere id  #{id,jdbcTypeINTEGER}/update
/mapper添加 AccountService 
Service
public class AccountService {Autowiredprivate AccountDao accountDao;public Account selectById(Integer id){return accountDao.selectById(id);}public int saveAccount(Account account){return accountDao.save(account);}public int updateAccount(Account account){return accountDao.update(account);}public int delAccount(Integer id){return accountDao.delete(id);}} 
URL 映射地址配置 
/*** RestFul URL 配置*      1. 设置请求类型*          GET查询     GetMapping*          DELETE删除  DeleteMapping*          POST添加    PostMapping*          PUT更新     PutMapping*      2. URL设置时不体现动作行为 没有动词*          例如/account/1、/account/2、/account*      3. 定义参数格式*          1. 路径参数  PathVariable *          2. json格式  RequestBody *          3. 普通表单参数*      4. 设置响应数据*          json格式  ResponseBody */
Controller
public class AccountController extends BaseController {Autowiredprivate AccountService accountService;/*** 查询操作*      传统的 URL 访问*          http://localhost:8080/ssm/account/queryAccountById?id1*      RestFul URL 访问*          GetMapping(/account/{id})*          http://localhost:8080/ssm/account/1*      PathVariable 将形参设置为参数路径声明在形参前面* param id* return*/// RequestMapping(/account/queryAccountById)GetMapping(/account/{id})ResponseBodypublic Account queryAccountById(PathVariable  Integer id) {// 设置异常return accountService.selectById(id);}/*** 删除操作* param id* return*/DeleteMapping(/account/{id})ResponseBodypublic MapString,String deleteAccountById(PathVariable Integer id) {// 调用service层的删除方法返回受影响的行数int row  accountService.delAccount(id);// 判断受影响的行数是否大于0MapString ,String map  new HashMap();if (row  0) {// 删除成功map.put(code,200);map.put(msg,删除成功!);} else {// 删除失败map.put(code,500);map.put(msg,删除失败!);}return  map;}/*** 添加操作* param account* return*/PostMapping(/account)ResponseBodypublic MapString,String addAccount(RequestBody Account account) {MapString ,String map  new HashMap();// 调用service层的添加方法返回受影响的行数int row  accountService.saveAccount(account);// 判断受影响的行数是否大于0if (row  0) {// 删除成功map.put(code,200);map.put(msg,添加成功!);} else {// 删除失败map.put(code,500);map.put(msg,添加失败!);}return map;}/*** 更新操作* param account* return*/PutMapping(/account)ResponseBodypublic MapString,String updateAccount(RequestBody Account account) {MapString ,String map  new HashMap();// 调用service层的添加方法返回受影响的行数int row  accountService.updateAccount(account);// 判断受影响的行数是否大于0if (row  0) {// 删除成功map.put(code,200);map.put(msg,更新成功!);} else {// 删除失败map.put(code,500);map.put(msg,更新失败!);}return map;}
} 
五、全局异常统⼀处理 
SpringMVC 对于异常处理这块提供了⽀持通过 SpringMVC 提供的全局异常处理机制能够将所有类型的异常处理从各处理过程解耦出来既保证了相关处理过程的功能较单⼀也实现了异常信息的统⼀处理和维护 
全局异常实现⽅式 Spring MVC 处理异常有 3 种⽅式 使⽤ Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver  实现 Spring 的异常处理接⼝ HandlerExceptionResolver ⾃定义⾃⼰的异常处理器  使⽤ ExceptionHandler 注解实现异常处理  
1.异常处理实现 
全局异常处理方式一 
配置简单异常处理器 
配置 SimpleMappingExceptionResolver 对象 
!-- 配置全局异常统⼀处理的 Bean 简单异常处理器 --
bean classorg.springframework.web.servlet.handler.SimpleMappingExceptionResolver
!-- ⻚⾯在转发时出现异常设置默认的错误⻚⾯ error代表的是⼀个视图 --
property namedefaultErrorView valueerror/property
!-- 异常发⽣时设置异常的变量名 --
property nameexceptionAttribute valueex/property
/bean可以在处理异常的⻚⾯获取异常信息 
${ex}使自定定义异常 
参数异常 
package com.xxxx.ssm.exception;/*** 自定义异常参数异常*/
public class ParamsException extends RuntimeException {private Integer code  300;private String msg  参数异常!;public ParamsException() {super(参数异常!);}public ParamsException(String msg) {super(msg);this.msg  msg;}public ParamsException(Integer code) {super(参数异常!);this.code  code;}public ParamsException(Integer code, String msg) {super(msg);this.code  code;this.msg  msg;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code  code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg  msg;}
} 
业务异常 
package com.xxxx.ssm.exception;/*** 自定义异常业务异常*/
public class BusinessException extends RuntimeException {private Integer code400;private String msg业务异常!;public BusinessException() {super(业务异常!);}public BusinessException(String msg) {super(msg);this.msg  msg;}public BusinessException(Integer code) {super(业务异常!);this.code  code;}public BusinessException(Integer code, String msg) {super(msg);this.code  code;this.msg  msg;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code  code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg  msg;}
} 
设置⾃定义异常与⻚⾯的映射 
!-- 设置⾃定义异常与⻚⾯的映射 --
property nameexceptionMappings
props
!-- key⾃定义异常对象的路径 标签中设置具体的处理⻚⾯的视图名--
prop keycom.xxxx.ssm.exception.BusinessExceptionerror/prop
prop keycom.xxxx.ssm.exception.ParamsExceptionerror/prop
/props
/property使⽤ SimpleMappingExceptionResolver 进⾏异常处理具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点但该⽅法仅能获取到异常信息若在出现异常时对需要获取除异常以外的数据的情况不适⽤。 
全局异常处理方式二(推荐) 
实现 HandlerExceptionResolver 接⼝ 
/**
* 全局异常统⼀处理
*/
Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object handler, Exception ex) {
ModelAndView mv  new ModelAndView(error);
mv.addObject(ex,默认错误信息);
return mv;
}
}⾃定义异常处理 
/**
* 全局异常统⼀处理
*/
Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object handler, Exception ex) {
ModelAndView mv  new ModelAndView(error);
mv.addObject(ex,默认错误信息);
// 判断是否是⾃定义异常
if (ex instanceof ParamsException) {
mv.setViewName(params_error);
ParamsException e  (ParamsException) ex;
mv.addObject(ex, e.getMsg());
}
if (ex instanceof BusinessException) {
mv.setViewName(business_error);
BusinessException e  (BusinessException) ex;
mv.addObject(ex, e.getMsg());
}
return mv;
}使⽤实现 HandlerExceptionResolver 接⼝的异常处理器进⾏异常处理具有集成简单、有良好的扩展性、对已有代码没有⼊侵性等优点同时在异常处理时能获取导致出现异常的对象有利于提供更详细的异常处理信息。 
全局异常处理方式三 
⻚⾯处理器继承 BaseController 
public class BaseController {
ExceptionHandler
public String exc(HttpServletRequest request,HttpServletResponse response,Exception ex){
request.setAttribute(ex, ex);
if(ex instanceof ParamsException){
return error_param;
}
if(ex instanceof BusinessException){
return error_business;
}
return error;
}
}使⽤ ExceptionHandler 注解实现异常处理具有集成简单、有扩展性好只需要将要异常处理的 Controller 类继承于 BaseController 即可、不需要附加Spring 配置等优点但该⽅法对已有代码存在⼊侵性(需要修改已有代码使相关类继承于 BaseController)在异常处理时不能获取除异常以外的数据。 
2.未捕获异常的处理 
在 web.xml 中通过(Websphere/Weblogic)或者(Tomcat)节点配置特定异常情况的显⽰⻚⾯。 !-- 出错页面定义 --error-pageexception-typejava.lang.Throwable/exception-typelocation/500.jsp/location/error-pageerror-pageerror-code404/error-codelocation/404.jsp/location/error-pageerror-pageerror-code500/error-codelocation/500.jsp/location/error-page