登录页面:
主页:
错误页面:
步骤流程示意图:
示例代码如下:
在登陆中异常的处理:
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 {
@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"));
return admin;
}
} 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;
}
}
在持久层中,包装后并抛出异常RuntimeException,抛给service层
业务层代码为:
package com.tarena.netctoss.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.tarena.netctoss.dao.AdminDAO;
import com.tarena.netctoss.entity.Admin;
@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;
}
}
业务层异常包装成ApplicationException异常向上抛出给控制器,由控制器来处理
处理器:
package com.tarena.netctoss.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.netctoss.entity.Admin;
import com.tarena.netctoss.service.ApplicationException;
import com.tarena.netctoss.service.LoginService;
@Controller
public class LoginController {
@Resource(name="loginService")
private LoginService service;
@RequestMapping("/toLogin.do")
public String toLogin(){
return "login";
}
@RequestMapping("/login.do")
//登录成功-重定向到首页
public String login(HttpServletRequest request){
//jsp页面采用的是post提交 可以使用以下编码,预防中文乱码
//request.setCharacterEncoding("UTF-8");
String adminCode = request.getParameter("adminCode");//账号
String pwd = request.getParameter("pwd");//账号
System.out.println(adminCode + " " + pwd);
//调用业务层服务--此处要处理异常
try{
Admin admin = service.checkLogin(adminCode, pwd);
}catch(Exception e){
e.printStackTrace();
//此处有两种异常需要处理
if(e instanceof ApplicationException){
//应用异常,提示用户采取正确的操作
request.setAttribute("login_failed", e.getMessage());
return "login";//登录页面
}
//系统异常(例如数据库异常、断网) 提示用户稍后重试
return "error";//错误页面
}
return "redirect:toIndex.do";
}
@RequestMapping("/toIndex.do")
//首页
public String toIndex(){
return "index";
}
}
处理器对可能出现的异常进行分类处理:
由于用户输入造成的为应用异常,转发到相应页面即可
由于系统错误造成的为系统异常(连接数据库失败、断网等)转发到相应页面即可
若没有异常则从定向到指定页面
===========================================================================
以上处理方式是通过try{}catch()进行处理,还可以将异常交给spring容器来处理
springmvc提供的异常处理机制
我们可以将异常抛给spring框架,让spring来帮我们处理异常。
(1)使用简单异常处理器
step1. 配置简单异常处理器。
step2. 添加对应的异常处理页面。
注:该方式只适合处理简单异常的处理,用的比较少,如果要对异常做复杂处理,比如 记录日志等,则不合适了。
例如:在controller中
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String hello(){
System.out.println("hello()");
//此处会抛出异常NumberFormatException,通过spring配置文件来处理
Integer.parseInt("100a");
return "hello";
}
@RequestMapping("/demo/hello.do")
public String hello2(){
System.out.println("hello2()");
String str = "abcd";
str.charAt(10);//取下标为10的字符
return "hello";
}
}
spring配置文件:
<!-- 配置简单异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- key是异常类型 后面的参数是视图解析器解析后的视图名-->
<prop key="java.lang.NumberFormatException">error1</prop>
<prop key="java.lang.StringIndexOutOfBoundsException">error2</prop>
</props>
</property>
</bean>
error1.jsp如下:
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<html>
<head></head>
<body style="font-size: 30px">
请输入正确的数字
</body>
</html>
error21.jsp如下:
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<html>
<head></head>
<body style="font-size: 30px">
下标越界
</body>
</html>
(2)使用@ExceptionHandler注解
step1. 在处理器类当中,添加一个异常处理方法, 该方法要使用@ExceptionHandler注解来标注。
step2.添加对应的异常处理页面
此方法不需要再spring配置文件中配置异常
案例代码如下:
这是定义了一个处理异常的类,让其他controller继承即可
package exception;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
/**
* 处理异常(利用注解)
*/
public class BaseController {
@ExceptionHandler
//这是一个异处理方法 参数ex:其他方法所抛出的异常
public String exHandle(Exception ex, HttpServletRequest request){
//根据异常类型不同,分别进行相应的处理
if(ex instanceof NumberFormatException){
//例如此处可以记录下异常发生的时间等
request.setAttribute("errorMsg", "亲,请输入正确的数字");
return "error";
}else if( ex instanceof StringIndexOutOfBoundsException){
request.setAttribute("errorMsg", "下标越界");
return "error";
}else{
//其他异常(系统异常)
return "system_error";
}
}
}
controller如下:
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import exception.BaseController;
@Controller
public class HelloController extends BaseController{
@RequestMapping("/hello.do")
public String hello(){
System.out.println("hello()");
//此处会抛出异常NumberFormatException
Integer.parseInt("100a");
return "hello";
}
@RequestMapping("/demo/hello.do")
public String hello2(){
System.out.println("hello2()");
String str = "abcd";
str.charAt(10);//取下标为10的字符
return "hello";
}
}
error.jsp如下:
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<html>
<head></head>
<body style="font-size: 30px">
${errorMsg }
</body>
</html>
system_error.jsp如下:
<%@ page pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<html>
<head></head>
<body style="font-size: 30px">
系统异常,请稍后重试!
</body>
</html>