1. 程式人生 > >登陸中的異常處理(對比之前處理方式)

登陸中的異常處理(對比之前處理方式)

利用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(看做系統異常),在該類中分別處理異常,定位到不同的頁面,還可以記錄日誌等,此種處理異常的方式很靈活,建議使用