一、拦截器
1. 基本概念
SpringMVC 中的 Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆等操作。
2. 定义拦截器
对于 springmvc 拦截器的定义方式有两种方式:
-
实现接口:org.springframework.web.servlet.HandlerInterceptor
-
继承适配器:org.springframework.web.servlet.handler.HandlerInterceptorAdapter
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyInterceptor implements HandlerInterceptor{ /** * preHandle 在请求方法拦截前执行 * 返回 true 代表对当前请求进行放行处理 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Action 之前执行!!!"); return true; // 继续执行 action } /** * 请求执行后,生成视图前执行 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("Action 执行之后,生成视图之前执行!!"); } /** * 在请求方法执行后进行拦截 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("方法执行后进行拦截。。释放资源。。。"); } }
- 继承 HandlerInterceptorAdapter 方式定义拦截器只需重写perHandle方法即可(实际上最终还是 HandlerInterceptor接口实现)
3. 配置拦截器
-
配置方式一
<mvc:interceptors> <!-- 使用 bean 定义一个 Interceptor 直接定义在 mvc:interceptors 根下面的 Interceptor 将拦截所有的请求 --> <bean class="com.xyz.interceptors.MyInterceptor" /> </mvc:interceptors>
-
配置方式二
<mvc:interceptors> <!-- 定义在 mvc:interceptor 下面 拦截所有 test 地址开头的请求--> <mvc:interceptor> <mvc:mapping path="/test/**" /> <bean class="com.xyz.interceptors.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors>
-
配置放行的资源(包含静态资源 js/css/images)(可以配置多个)
<mvc:interceptors> <!-- 使用mvc:interceptor子标签配置拦截器 子标签可以配置多个 --> <mvc:interceptor> <!-- mvc:mapping:配置拦截的方法(Handler) 拦截所有资源(包含静态资源 js/css/images) --> <mvc:mapping path="/**"/> <!-- mvc:exclude-mapping:配置放行的资源(包含静态资源 js/css/images) 可以配置多个 --> <mvc:exclude-mapping path="/js/**"/> <mvc:exclude-mapping path="/user/login"/> <mvc:exclude-mapping path="/user/register"/> <bean class="com.xyz.interceptors.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> <!-- 默认对静态资源放行 不做任何处理 框架提供的default-servlet-handler 默认对静态资源处理 响应给浏览器 --> <mvc:default-servlet-handler/>
-
多个拦截器配置
<mvc:interceptors> <mvc:interceptor> <!-- 拦截所有请求 --> <mvc:mapping path="/**" /> <bean class="com.xyz.interceptors.MyInterceptor" /> </mvc:interceptor> <mvc:interceptor> <!-- 拦截所有请求 --> <mvc:mapping path="/**" /> <bean class="com.xyz.interceptors.MyInterceptor2" /> </mvc:interceptor> </mvc:interceptors>
-
执行顺序:
- 如果存在多个拦截器配置,先配置的首先执行(先执行preHandler 方法 按照配置顺序执行),对于postHandle 、afterCompletion 方法,先配置的后执行
二、SpringMVC 文件上传
1. 配置 pom.xml 文件
<!-- 添加 commons-fileupload 依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
2. 配置 servlet-context.xml 文件
<!--
文件上传解析器配置
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
3. 编写控制层代码
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@Controller
public class FileController {
@RequestMapping("uploadFile")
public String uploadFile(HttpServletRequest request) {
try {
MultipartHttpServletRequest mhsr = (MultipartHttpServletRequest) request;
MultipartFile mf = mhsr.getFile("file");
mf.getInputStream();
if( mf != null && !(mf.isEmpty())) {
// 获取项目WEB-INF所在的服务器绝对路径
String basePath = request.getSession().getServletContext().getRealPath("/WEB-INF");
File file = new File(basePath+"/upload");
if(!(file.exists())) {
// 目录不存在 创建upload 目录
file.mkdir();
}
// 获取文件原始文件名
String fileName = mf.getOriginalFilename();
// 设置文件名唯一:
// 方法一:系统当前时间毫秒数
// 方法二:用户id hash值
// 方法三:uuid(时空唯一)
fileName = System.currentTimeMillis() + "" + fileName.substring(fileName.lastIndexOf("."));
mf.transferTo(new File(file, fileName));
request.setAttribute("result", "文件上传成功!");
}else{
request.setAttribute("result", "文件不存在,上传失败!");
}
} catch (IOException e) {
e.printStackTrace();
request.setAttribute("result", "文件上传失败!");
}
return "result";
}
}
三、SSM 框架集成
1. 创建 maven web 工程
2. 添加坐标
- 包括以下几大类:Spring | Mybatis | Mybatis 整合Spring | SpringMvc
<!-- junit 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring 核心jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 测试jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- aspectj切面编程的jar -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- c3p0 连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 添加mybatis与Spring整合的核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- 日志打印相关的jar -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- web servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- 添加json 依赖jar包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 添加文件上传 依赖jar包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
3. 添加resources plugin
<build>
<finalName>ssm</finalName>
<!--
Maven 项目
如果源代码(src/main/java)存在xml、properties、tld等文件,maven 默认不会自动编译该文件到输出目录
如果要编译源代码中xml、properties、tld 等文件,需要显式配置resources 标签
-->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<contextPath>/ssm</contextPath>
</configuration>
</plugin>
</plugins>
</build>
4. 修改web.xml
- 包括:Spring.xml | 监听器 | 编码过滤器 | 请求转发DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 编码过滤 utf-8 -->
<filter>
<description>char encoding filter</description>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- servlet请求分发器 -->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<!-- 表示启动容器时初始化该Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<!-- 这是拦截请求, /代表拦截所有请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
5. 添加servlet-context.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描com.xyz.controller 下包 -->
<context:component-scan base-package="com.xyz.controller" />
<!-- mvc 请求映射 处理器与适配器配置-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!--配置视图解析器 默认的视图解析器- -->
<bean id="defaultViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType" value="text/html" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!--
默认对静态资源放行 不做任何处理
框架提供的default-servlet-handler 默认对静态资源处理 响应给浏览器
-->
<mvc:default-servlet-handler/>
<!--
文件上传解析器配置
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>
</beans>
6. 添加资源文件
1. spring.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--
配置扫描器
-->
<context:component-scan base-package="com.xyz">
<!--
排除@Controller 注解标注的Java 类
-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--
配置 加载jdbc.properties
-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
数据源c3p0 配置
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--
事务控制
-->
<aop:aspectj-autoproxy/>
<!--
事务管理器
-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
声明事务通知
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="cut" expression="execution(* com.xyz.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="cut"></aop:advisor>
</aop:config>
<!--
mybatis 整合spring
-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis.xml"></property>
<property name="mapperLocations" value="classpath:com/xyz/mappers/*.xml"></property>
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描com.xyz.dao这个包以及它的子包下的所有映射接口类 -->
<property name="basePackage" value="com.xyz.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
</bean>
</beans>
2. mybatis.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>
<typeAliases>
<package name="com.xyz.vo"/>
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
</configuration>
3. jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
4. log4j.properties
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
5. generatorConfig.xml
代码生成器配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--数据库驱动-->
<classPathEntry location="C:/java/m2/repository/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis" userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类存放位置-->
<javaModelGenerator targetPackage="com.xyz.vo" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="com.xyz.mappers" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xyz.dao" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="t_user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>
7. 源代码添加
添加Base(BaseMapper、BaseService、BaseQuery)
BaseMapper.java
import org.springframework.dao.DataAccessException;
import java.util.List;
import java.util.Map;
public interface BaseMapper<T,ID> {
/**
* 添加记录返回影响行数
*/
public int save(T entity) throws DataAccessException;
/**
* 添加记录返回主键
*/
public ID saveHasKey(T entity) throws DataAccessException;
/**
* 批量添加记录
*/
public int saveBatch(List<T> entities) throws DataAccessException;
/**
* 详情查询
* @param id
* @return
*/
public T queryById(ID id) throws DataAccessException;
/**
* 多条件列表查询
* @param baseQuery
* @return
*/
public List<T> queryByParams(BaseQuery baseQuery) throws DataAccessException;
/**
* 更新单条记录
* @param entity
* @return
*/
public int update(T entity) throws DataAccessException;
/**
* 批量更新
* @param map
* @return
*/
public int updateBatch(Map<String, Object> map) throws DataAccessException;
/**
* 删除单条记录
* @param id
* @return
*/
public int delete(ID id) throws DataAccessException;
/**
* 批量删除
* @param ids
* @return
*/
public int deleteBatch(ID[] ids) throws DataAccessException;
}
BaseService.java
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
public abstract class BaseService<T, ID> {
@Autowired
private BaseMapper<T, ID> baseMapper;
public int save(T entity){
return baseMapper.save(entity);
}
public ID saveHasKey(T entity) {
baseMapper.saveHasKey(entity);
try {
Method method= entity.getClass().getDeclaredMethod("getId",null);
return (ID) method.invoke(entity,null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int saveBatch(List<T> entities){
return baseMapper.saveBatch(entities);
}
public T queryById(ID id){
return baseMapper.queryById(id);
}
public List<T> queryByParams(BaseQuery baseQuery){
return baseMapper.queryByParams(baseQuery);
}
public int update(T entity){
return baseMapper.update(entity);
}
public int updateBatch(Map<String,Object> map){
return baseMapper.updateBatch(map);
}
public int delete(ID id){
return baseMapper.delete(id);
}
public int deleteBatch(ID[] ids){
return baseMapper.deleteBatch(ids);
}
/**
* 分页查询
* @param baseQuery
* @return
*/
public PageInfo<T> queryForPage(BaseQuery baseQuery){
PageHelper.startPage(baseQuery.getPageNum(), baseQuery.getPageSize());
return new PageInfo<T>(queryByParams(baseQuery));
}
}
BaseQuery.java
public class BaseQuery {
private Integer pageNum=1;
private Integer pageSize=10;
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}
添加 UserDao、UserMapper.xml、UserService.java、UserController.java
UserDao.java
import com.xyz.vo.User;
public interface UserDao {
public User queryUserByUserId(Integer userId);
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xyz.dao.UserDao">
<select id="queryUserByUserId" parameterType="int" resultType="User">
select id, user_name as userName, user_pwd as userPwd, flag, create_time as createTime from user where id=#{userId}
</select>
</mapper>
UserService.java
import com.xyz.dao.UserDao;
import com.xyz.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User queryUserByUserId(Integer userId){
return userDao.queryUserByUserId(userId);
}
}
UserController.java
import com.xyz.service.UserService;
import com.xyz.vo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
@Controller
@RequestMapping("user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("queryUserByUserId")
@ResponseBody
public User queryUserByUserId(Integer userId){
return userService.queryUserByUserId(userId);
}
@RequestMapping("index")
public String index(Integer userId, Model model){
User user = userService.queryUserByUserId(userId);
model.addAttribute("user",user);
return "user";
}
}
8. 配置启动命令
jetty:run -Djetty.port=8686
四、SpringMVC 全局异常统一处理
1. 全局异常概念
在 JavaEE 项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。
SpringMvc 对于异常处理这块提供了支持,通过 SpringMvc 提供的全局异常处理机制,能够将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。
2. 异常处理方式
- Spring MVC 处理异常有 3 种方式:
-
配置 SimpleMappingExceptionResolver 对象
<!-- 全局异常配置-01 解决视图异常 如果方法本身返回json,但是当方法抛出异常时,方法结果为html --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!-- 异常发生时 默认的错误页面 error:视图名 --> <property name="defaultErrorView" value="error"></property> <!-- 异常发生时 显示在错误页 错误信息 --> <property name="exceptionAttribute" value="ex"></property> <property name="exceptionMappings"> <props> <prop key="com.xyz.exceptions.ParamsException">params-exception</prop> <prop key="com.xyz.exceptions.BusinessException">busi-exception</prop> </props> </property> </bean>
-
实现 HandlerExceptionResolver 接口
import com.xyz.exceptions.BusinessException; import com.xyz.exceptions.ParamsException; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //@Component public class GlobalExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView mv = new ModelAndView("error"); mv.addObject("ex", ex.getMessage()); if (ex instanceof ParamsException) { ParamsException pe = (ParamsException) ex; mv.setViewName("params-exception"); mv.addObject("ex", pe.getMsg()); } if (ex instanceof BusinessException) { BusinessException be = (BusinessException) ex; mv.setViewName("busi-exception"); mv.addObject("ex", be.getMsg()); } return mv; } }
-
页面处理器继承 BaseController
import com.xyz.exceptions.BusinessException; import com.xyz.exceptions.ParamsException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; public class BaseController { @ExceptionHandler public ModelAndView resolveException(Exception ex) { ModelAndView mv = new ModelAndView("error"); mv.addObject("ex", ex.getMessage()); if (ex instanceof ParamsException) { ParamsException pe = (ParamsException) ex; mv.setViewName("params-exception"); mv.addObject("ex", pe.getMsg()); } if (ex instanceof BusinessException) { BusinessException be = (BusinessException) ex; mv.setViewName("busi-exception"); mv.addObject("ex", be.getMsg()); } return mv; } }
将要异常处理的 Controller 类继承于 BaseController 即可
import com.xyz.exceptions.ParamsException; import com.xyz.service.UserService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class TestController extends BaseController { @Resource private UserService userService; @RequestMapping("test01") public String index(Integer userId, Model model) { model.addAttribute("user", userService.queryUserByUserId(userId)); if (1 == 1) { throw new ParamsException("用户id为空!"); } return "user"; } @RequestMapping("test02") public String index02(Integer userId, Model model) { model.addAttribute("user", userService.queryUserByUserId(userId)); return "user"; } }
-
未捕获异常的处理
-
修改 web.xml 文件
<!-- 出错页面定义 --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/500.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page>
-