利用spring框架提供的处理方式来处理异常(使用@ExceptionHandler注解)
登录controller处理器:
package com.tarena.netctoss.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.netctoss.entity.Admin;
import com.tarena.netctoss.exception.BaseController;
import com.tarena.netctoss.service.LoginService;
@Controller
public class LoginController extends BaseController{
@Resource(name="loginService")
private LoginService service;
@RequestMapping("/toLogin.do")
public String toLogin(){
return "login";
}
@RequestMapping("/login.do")
//登录成功-重定向到首页
public String login(HttpServletRequest request, HttpSession session){
//jsp页面采用的是post提交 可以使用以下编码,预防中文乱码
//request.setCharacterEncoding("UTF-8");
String adminCode = request.getParameter("adminCode");//账号
String pwd = request.getParameter("pwd");//账号
System.out.println(adminCode + " " + pwd);
//调用业务层服务--此处要处理异常
//采用注解(spring框架)来处理异常
Admin admin = service.checkLogin(adminCode, pwd);
//把admin对象绑定到session,用于session验证(位于拦截器)
session.setAttribute("admin", admin);
return "redirect:toIndex.do";
}
@RequestMapping("/toIndex.do")
//首页
public String toIndex(){
return "index";
}
}
业务层代码:
/**
* 业务层实现
*/
@Service("loginService")
public class LoginServiceImpl implements LoginService{
@Resource(name="adminDAO")
private AdminDAO dao;
public Admin checkLogin(String adminCode, String pwd) {
Admin admin = null;
admin = dao.findByAdminCode(adminCode);
if(admin == null){
//账号不存在
//抛出一个应用异常(用户操作引起的异常)
throw new ApplicationException("账号不存在");
}
if(!admin.getPassword().equals(pwd)){
//密码不正确
throw new ApplicationException("密码错误");
}
//登录成功
return admin;
}
}
持久层代码:
package com.tarena.netctoss.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.stereotype.Repository;
import com.tarena.netctoss.entity.Admin;
/**
* 持久层实现
*/
@Repository("adminDAO")
public class AdminDAOJdbcImpl implements AdminDAO{
//通过依赖注入将连接池注入(DataSource是接口 无论是绝对不是还是c3p0)
@Resource(name="ds")
private DataSource ds;
public Admin findByAdminCode(String adminCode) {
Admin admin = null;
Connection conn = null;
try {
conn = ds.getConnection();
String sql = "select * from admin_info where admin_code=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, adminCode);
ResultSet rs = ps.executeQuery();
if(rs.next()){
admin = new Admin();
admin.setAdminId(rs.getInt("admin_id"));
admin.setAdminCode(rs.getString("admin_code"));
admin.setPassword(rs.getString("password"));
admin.setName(rs.getString("name"));
admin.setTelephone(rs.getString("telephone"));
admin.setEmail(rs.getString("email"));
admin.setEnrolldate(rs.getTimestamp("enrolldate"));
}
} catch (SQLException e) {
//记录日志
e.printStackTrace();//打印到控制台
/*
* 看异常能否恢复,若能恢复,则立即恢复
* 若不能恢复(例:系统异常,数据库发生异常),则提示用户稍后重试
*/
//此处异常抛给业务层
throw new RuntimeException(e);
} finally {
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);//此处异常抛给业务层
}
}
}
return admin;
}
}
最终在controller中要处理业务层和持久层所抛出的异常,案例中有两种,ApplicationException和RuntimeException
处理方式如下:
此时将登录方法中的try...catch去掉,可以和博客之前的代码比较,将异常交给spring处理
写一个处理异常的类,可以让登录controller集成该类:
package com.tarena.netctoss.exception;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.tarena.netctoss.service.ApplicationException;
public class BaseController{
@ExceptionHandler
public String exHandle(Exception ex, HttpServletRequest request){
if(ex instanceof ApplicationException){
//自定义的应用异常(账号或密码错误)
request.setAttribute("login_failed", ex.getMessage());//在登录页面显示错误原因
return "login";
}
//系统异常
return "error";
}
}
此处的ApplicationException,注意导包,是自己定义的异常(密码或账号错误所抛出的异常),其余的是RuntimeException(看做系统异常),在该类中分别处理异常,定位到不同的页面,还可以记录日志等,此种处理异常的方式很灵活,建议使用