java自定义异常处理

  1. 1. 实际应用中的经验总结
  2. 2. 情况一:
  3. 3. 情况二:
  4. 4. 代码:

​ 使用 Java 内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。

实际应用中的经验总结

  1. 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
  2. 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
  3. 对于不确定的代码,也可以加上try-catch,处理潜在的异常
  4. 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
  5. 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  6. 尽量添加finally语句块去释放占用的资源。

情况一:

某些时候后台出现了异常,直接给前端抛了一个500错误,这种错误会被用户看到非常不友好,于是就有了以下统一异常处理,就是把所有的异常都经过处理,按照前端可读的json格式返回。

情况二:

如果service业务层方法出现任何业务异常,则返回标记(自定义异常 )到web层(servlet)

service层:

controller层:

测试结果:

整个运行过程中虽然会抛出咱们自定义的异常但不会中断程序,能向客户端发送异常信息。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.entity;

/**
* 结果返回封装工具
*/
public class Consequence {
private Integer code; // 状态码
private String msg; // 响应消息
private Object date; // 数据
private String devMsg; // Java内置的异常信息

get.../set...方法

public void clear(){
this.code=null;
this.date=null;
this.msg=null;
this.devMsg=null;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package com.exception;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.entity.Consequence;

public class Result {

private static volatile Consequence consequence=new Consequence();

/**
* code结果状态码 0:操作成功;
*/
public static int code0=0;
public static int code1=1; //1:未登录;
public static int code2=2; //2:参数错误;
public static int code3=3; //3:系统异常

//时间格式
public static String dateFormat="yyyy-MM-dd HH:mm:ss";

/**
* 成功 —— 返回成功的响应消息跟数据
* @param msg 附带的成功信息
* @param date 你的数据
* @return
*/
public static String succeedResultByMsgAndDate( String msg, Object date){
consequence.clear();
consequence.setCode(code0);
consequence.setMsg(msg);
consequence.setDate(date);
return getResult(consequence);
}

/**
* 成功—— 返回客户端状态码跟响应消息 ,不返回状态马
* @param msg
* @return
*/
public static String succeedResultByMsg( String msg){
consequence.clear();
consequence.setCode(code0);
consequence.setMsg(msg);
consequence.setDate("");
return getResult(consequence);
}

/**
* 成功—— 返回客户端固定的状态码跟响应消息
*/
public static String succeedResult(){
consequence.clear();
consequence.setCode(code0);
consequence.setMsg("操作成功");
consequence.setDate("");
return getResult(consequence);
}


/**
* 默认通过报的异常信息返回数据
* @param msg
* @return
*/
public static String defeatedResultByMsg(String msg){
consequence.clear();
consequence.setCode(code3);
consequence.setDate("");
consequence.setMsg("系统异常,请联系管理员");
consequence.setDevMsg(msg);
return getResult(consequence);
}

/**
* 默认返回客户端异常信息
* @param msg
*/
public static String defeatedResult(){
consequence.clear();
consequence.setCode(code3);
consequence.setDate("");
consequence.setMsg("系统异常,请联系管理员");
return getResult(consequence);
}

/**
* 没有登录异常
* @return
*/
public static String noLoginResult(){
consequence.clear();
consequence.setCode(code1);
consequence.setDate("");
consequence.setMsg("没有登录,请登录");
return getResult(consequence);
}

/**
* 参数错误异常
* @return
*/
public static String errorParameterResult(){
consequence.clear();
consequence.setCode(code2);
consequence.setDate("");
consequence.setMsg("参数错误,或参数不能为空");
return getResult(consequence);
}


/**
* 参数错误异常 —— 通过错误信息
* @return
*/
public static String errorParameterResultByMsg(String msg){
consequence.clear();
consequence.setCode(code2);
consequence.setDate("");
consequence.setMsg(msg);
return getResult(consequence);
}

/**
* 参数错误异常 ——
* @return
*/
public static String defeatedResultByCodeAndMsg(Integer code,String msg){
consequence.clear();
consequence.setCode(code);
consequence.setDate("");
consequence.setMsg(msg);
return getResult(consequence);
}


/**
* 自定义 返回状态码 + 响应消息 + 响应的数据
* @return
*/
public static String setResultByCodeAndMsgAndDate(Integer code,String msg, Object date){
consequence.clear();
consequence.setCode(code);
consequence.setDate(date);
consequence.setMsg(msg);
return getResult(consequence);
}


/**
* 返回json格式数据
* @param consequence —— 封装的json格式的实体类
* @return
*/
public static String getResult(Consequence consequence){
return JSON.toJSONStringWithDateFormat(consequence, dateFormat,
SerializerFeature.DisableCircularReferenceDetect);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.dao;

/**
* 错误码接口
*/
public interface ErrorCode {

/**
* 获取错误码
* @return
*/
Integer getCode();

/**
* 获取错误信息
* @return
*/
String getMsg();

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.dao.impl;


import org.apache.commons.codec.binary.StringUtils;

import com.dao.ErrorCode;

/**
* 枚举类 业务错误码
*/
public enum BizErrorCodeEnum implements ErrorCode {
/**
* 通用异常
*/
NULL_OBJ(1001,"对象为空"),
ERROR_ADD_USER(1002, "添加用户失败"),
REQUEST_ERROR(400, "入参异常,请检查入参后再次调用"),
PAGE_NUM_IS_NULL(4001,"页码不能为空"),
PAGE_SIZE_IS_NULL(4002,"页数不能为空"),
ID_IS_NULL(4003,"ID不能为空"),
SEARCH_IS_NULL(4004,"搜索条件不能为空"),
RES_FAIL(40007,"响应失败"),
TEST(4000, "自定义异常处理测试"),

/**
* 未指明的异常
*/
UNSPECIFIED(500, "网络异常,请稍后再试"),
NO_SERVICE(404, "系统繁忙,请稍后再试....");


/**
* 错误码
*/
private Integer code;

/**
* 描述
*/
private String msg;

/**
* @param code 错误码
* @param msg 描述
*/
private BizErrorCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}

/**
* 根据编码查询枚举。
* @param code 编码。
* @return 枚举。
*/
public static BizErrorCodeEnum getByCode(Integer code) {
for (BizErrorCodeEnum value : BizErrorCodeEnum.values()) {
if (code.equals(value.getCode())) {
return value;
}
}
return UNSPECIFIED; // 状态码500
}

/**
* 枚举是否包含此code
* @param code 枚举code
* @return 结果
*/
public static Boolean contains(Integer code){
for (BizErrorCodeEnum value : BizErrorCodeEnum.values()) {
if (code.equals(value.getCode())) {
return true;
}
}
return false;
}

public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

@Override
public String toString() {
return "[" + this.code + "]" + this.msg;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.exception;

/**
* 自定义异常类 - MyException
* 一般我们的业务异常都是执行时异常。
*/
public class MyException extends RuntimeException{

private static final long serialVersionUID = 1L;

public MyException(Object Obj) {
super(Obj.toString()); // 调用父方法
}

}

测试:

1
2
3
4
5
6
7
8
public static void main(String[] args) throws SQLException, PropertyVetoException {

Object user = null;
if(user == null){
throw new MyException(BizErrorCodeEnum.NO_SERVICE);
}
System.out.println("111");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@WebServlet("/test")
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserService userService = new UserServiceImpl();


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String action = request.getParameter("action");
System.out.println("action=" + action);

if ("tes".equals(action)) {
test(request, response);
} else if ("addUser".equals(action)) {
try {
addUser(request, response);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


private void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
String se = "自定义错误!";
String msg = Result.setResultByCodeAndMsgAndDate(101, se, "这是个错误!");
response.getWriter().println(msg);

}

private void addUser(HttpServletRequest request, HttpServletResponse response) throws SQLException, IOException, ServletException {
String username = "roor";
String password = "111";
String salt = null;

User user = new User(username, password, salt);
try {
int flag = userService.AddUser(username, password, salt); // 更新操作,成功返回1,失败为0
} catch (MyException e) {
String msg = e.getMessage();
response.getWriter().println(msg);
}

response.getWriter().println(111);

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}