完整的项目案例: springmvc.zip
目录
实例
除了依赖spring-webmvc还需要依赖jackson-databind(用于转换json数据格式)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
项目结构:
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 请求总控器 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
配置dispatcher-servlet.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="edu.nf.ch09"/> <mvc:annotation-driven/> <mvc:default-servlet-handler/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
Controller (UserController)
package edu.nf.ch09.controller; import edu.nf.ch09.controller.vo.ResponseVO; import edu.nf.ch09.entity.Users; import edu.nf.ch09.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpSession; /** * @author wangl * @date 2018/11/5 */ @Controller public class UserController { @Autowired private UserService userService; /** * 局部异常处理方法 * * @ExceptionHandler标注的方法用于专门处理请求方法抛出的异常 * value属性指定异常的Class对象(是一个数组,可以指定多个class), * 表示捕获什么样的异常对象,最后在标注的方法中传入一个异常参数,就可以得到相应的异常对象 * 注意:@ExceptionHandler标注的方法只在当前的Controller类中有效, * 在其他类中必须重新编写相关的Handler异常处理方法, * 如果希望让所有的Controller都共享一个Handler异常处理,那么可以配置为全局异常处理 * * @return */ /*@ExceptionHandler(UserException.class) public ResponseVO handlerException(RuntimeException e){ ResponseVO vo = new ResponseVO(); vo.setCode(401); vo.setMessage(e.getMessage()); return vo; }*/ /** * 用户登陆 * @param user * @param session * @return */ @PostMapping("/userLogin") @ResponseBody public ResponseVO login(Users user, HttpSession session){ ResponseVO vo = new ResponseVO(); //如果login方法引发了异常,则会执行上面的handlerLoginException异常处理方法 user = userService.login(user); session.setAttribute("user", user); vo.setValue("index.html"); return vo; } @PostMapping("/addUser") @ResponseBody public ResponseVO addUser(Users user){ userService.addUser(user); return new ResponseVO(); } }
ExceptionAdvice(全局的异常处理类)
package edu.nf.ch09.controller.advice; import edu.nf.ch09.controller.vo.ResponseVO; import edu.nf.ch09.service.exception.DataAccessException; import edu.nf.ch09.service.exception.UserException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * @author wangl * @date 2018/11/5 * 定义一个全局的异常处理类(类似一个切面) * 这个类中定义的所有方法都是异常处理方法, * 也可以理解为是全局的异常通知 * value属性指定对哪些控制器进行切入拦截 */ @ControllerAdvice("edu.nf.ch09.controller") public class ExceptionAdvice { /** * 全局异常处理方法 * 用于处理用户登陆异常 * @param e * @return */ @ExceptionHandler(UserException.class) @ResponseBody public ResponseVO handlerLoginException(RuntimeException e){ ResponseVO vo = new ResponseVO(); vo.setCode(401); vo.setMessage(e.getMessage()); return vo; } /** * 全局异常处理方法 * 用于处理crud操作 * @param e * @return */ @ExceptionHandler(DataAccessException.class) @ResponseBody public ResponseVO handlerDataAccessException(RuntimeException e){ ResponseVO vo = new ResponseVO(); vo.setCode(500); vo.setMessage(e.getMessage()); return vo; } }
持久层引发的异常
package edu.nf.ch09.dao.impl; import edu.nf.ch09.dao.UserDao; import edu.nf.ch09.entity.Users; import edu.nf.ch09.service.exception.DataAccessException; import org.springframework.stereotype.Repository; /** * @author wangl * @date 2018/11/5 */ @Repository public class UserDaoImpl implements UserDao { @Override public Users getUserByName(String userName) { Users user = null; if("user1".equals(userName)){ user = new Users(); user.setUserName("user1"); user.setPassword("123456"); } return user; } @Override public void saveUser(Users user) { System.out.println("insert into user_info values ..."); throw new DataAccessException("添加失败"); } }
业务逻辑层引发的异常
package edu.nf.ch09.service.impl; import edu.nf.ch09.dao.UserDao; import edu.nf.ch09.entity.Users; import edu.nf.ch09.service.UserService; import edu.nf.ch09.service.exception.UserException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author wangl * @date 2018/11/5 */ @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public Users login(Users user) { Users newUser = userDao.getUserByName(user.getUserName()); if(newUser == null){ throw new UserException("用户不存在"); } if(!user.getPassword().equals(newUser.getPassword())){ throw new UserException("密码错误"); } return newUser; } @Override public void addUser(Users user) { userDao.saveUser(user); } }
页面收到异常消息