Java Exception 捕获和展示

       在进行Java B/S架构开发时,经常有这样的场景:后端处理业务逻辑,前端负责展示,当后端处理出现异常时,如何把错误信息展示给前台呢?错误信息栈通常很多,对开发人员查找问题比较方便,但对于客户来说,打一堆的错误信息,无疑是对他们感官的一种摧残,如何捕捉最重要的信息显示到客户端呢?该信息要求简明扼要,指向出错点,且应指明异常的类型。

        在很多情况下Exception的 getMessage()方法返回空的值,如果使用该方式则会在前端显示空值。我们要显示的重要信息有两个:

  •          异常类型
  •          出错点和出错信息

        

1、异常类型如何获得呢?

可以通过Exception 的getClass().getName()方法来实现。


2、出错点如何获得呢?

出错点信息一般在“Cause by:”标识开始的行。如果能抓取到该行,则可取出异常信息,一个异常栈例子如下:

Caused by: org.apache.activemq.selector.ParseException: Parse error at line 0, column 0.  Encountered: <EOF>
	at org.apache.activemq.selector.SelectorParser.generateParseException(SelectorParser.java:1231)
	at org.apache.activemq.selector.SelectorParser.jj_consume_token(SelectorParser.java:1179)
	at org.apache.activemq.selector.SelectorParser.unaryExpr(SelectorParser.java:468)
	at org.apache.activemq.selector.SelectorParser.multExpr(SelectorParser.java:390)
	at org.apache.activemq.selector.SelectorParser.addExpression(SelectorParser.java:359)
	at org.apache.activemq.selector.SelectorParser.comparisonExpression(SelectorParser.java:211)
	at org.apache.activemq.selector.SelectorParser.equalityExpression(SelectorParser.java:156)
	at org.apache.activemq.selector.SelectorParser.andExpression(SelectorParser.java:135)
	at org.apache.activemq.selector.SelectorParser.orExpression(SelectorParser.java:114)
	at org.apache.activemq.selector.SelectorParser.JmsSelector(SelectorParser.java:106)
	at org.apache.activemq.selector.SelectorParser.parse(SelectorParser.java:84)
	... 63 more

        由于一些原因,往往它并不出现在第一行,所以,通过取第一行的方式不能获取出错点和出错提示信息。

        如果自己解析该输出,一行一行地读入,然后通过判断首字符是否是“Caused by:” 也能抓取到出错点和出错信息。

        最简单的方式,还是使用正则表达式,可以比较简单地实现抓取出错点和出错信息。例如:

代码1:使用正则表达式获取出错点和出错信息

		    String regEx = "Caused by:(.*)";  
		    Pattern pat = Pattern.compile(regEx);  
		    Matcher mat = pat.matcher(content);  
		    boolean rs = mat.find();  
		    System.out.println("found?" + rs);
		    System.out.println(mat.group(1));

代码1的结果输出:

org.apache.activemq.selector.ParseException: Parse error at line 0, column 0.  Encountered: <EOF>

3、异常信息的获取

         虽然知道了如何找出错点,但异常信息如何获得呢?Exception.printStrackTrace()中虽然有出错点信息,但都打到控制台上去了,Exception.getStackTrace(),并不能获得出错点的提示信息。

        一个应对办法就是捕获e.printStrackTrace()输出, 使用e.printStackTrace(PrintStream)方法,将异常栈信息先输出到ByteOutputStream ,然后再将ByteOutputStream 转换为字符串,就获得了异常的完整输出。代码为:

代码2:获取完整异常信息

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			e.printStackTrace(new PrintStream(baos));
			String exception = baos.toString();
			System.out.println("baos:" + exception);



完整的测试代码--异常Caused by捕获(注:该测试代码中并没有出现Caused by字样,实际应用代码比较多,没有放进测试用例中):

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexpTest {
	/**
	 * 读取文件中的内容
	 * @return
	 */
	public String readFile(){
		try {
			String fileName = "D:\\test2\\exception.log";
			File f = new File(fileName);
			FileInputStream fis = new FileInputStream(f);
			int filesize = fis.available();
			byte[] buffer = new byte[filesize];
			fis.read(buffer);
			return new String(buffer);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}		
	}
	
	/**
	 * 正则表达式测试
	 */
	public void test(){
		try {
			String content = readFile();
			System.out.println(content);
			
		    String regEx = "Caused by:(.*)";  
		    Pattern pat = Pattern.compile(regEx);  
		    Matcher mat = pat.matcher(content);  
		    boolean rs = mat.find();  
		    System.out.println("found?" + rs);
		    System.out.println(mat.group(1));
//		    for(int i=1;i<=mat.groupCount();i++){  
//		    	System.out.println("found:" + mat.group(i));  
//		    }   
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void test2(){
		try {
			FileInputStream fis = new FileInputStream("d:\\test.txt");
			fis.read();
		} catch (Exception e) {
			e.printStackTrace();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			e.printStackTrace(new PrintStream(baos));
			String exception = baos.toString();
			System.out.println("exception:" + exception);
		}
	}
	
	public static void main(String[] args) {
		RegexpTest rt = new RegexpTest();
		//rt.test();
		rt.test2();
	}

4、获取异常类型和出错点还有一种简单的方法

获取出错点类型:

 e.getCause().getClass()

获取出错点信息(出错原因):

e.getCause().getMessage()

代码示例(注:实际代码截取,不可直接运行):

	@SuppressWarnings("unchecked")
	@RequestMapping(value="/createSubscriber", method = RequestMethod.POST)
	public @ResponseBody
	WrappedResult createSubscriber(@ItemsRequestBody List<Map> list) {
		LocalBrokerFacade facade = new LocalBrokerFacade(BrokerRegistry.getInstance().findFirst());
		WrappedResult result = new WrappedResult();
		try {
			Map params = list.get(0);
			String clientId = (String)params.get("clientId");
			String subscriberName = (String)params.get("subscriberName");
			String topicName = (String)params.get("topicName");
			String selector = (String)params.get("selector");
			
//			if("".equals(selector)){
//				selector = null;
//			}
			
			facade.getBrokerAdmin().createDurableSubscriber(clientId,
					subscriberName,topicName,selector);
			result.setSuccessful(true);
		} catch (Exception e) {
			System.out.println("Exception:" + e.getCause().getClass() + "," + e.getCause().getMessage());
			//log.error("createSubscriber failed.", e);
		}



输出:Exception:class org.apache.activemq.selector.ParseException,Parse error at line 0, column 0.  Encountered: <EOF>


<think>好的,我现在要处理用户关于Java捕获Exception异常的示例的问题。首先,我需要回顾Java中异常处理的基本概念。Java使用try-catch块来捕获处理异常,用户可能想知道如何具体实现这一点,特别是针对Exception这个通用异常类的捕获。 接下来,我应该考虑用户的需求。他们可能需要一个简单的示例,展示如何捕获Exception异常。因此,我需要编写一个包含try块的代码,其中可能抛出异常,然后在catch块中捕获Exception类型。需要注意,捕获Exception捕获所有继承自它的异常,包括RuntimeException,所以通常建议捕获更具体的异常类型。不过用户明确要求捕获Exception,所以示例需要符合这一点。 然后,我需要参考提供的引用资料。引用[1]提到了System.out.println处理异常的方式,引用[2]展示了重新抛出异常的代码,引用[3]讨论onErrorResume操作符捕获特定异常类型,引用[4]指出异常信息的位置。这些引用中,引用[1][2]更相关,因为它们涉及Java的异常处理机制。 接下来,构造一个示例。例如,在try块中执行可能引发异常的操作,比如除以零,然后在catch块中捕获Exception,并打印堆栈跟踪。同时,可以展示多catch块的情况,说明捕获不同异常的顺序,因为Exception是所有异常的父类,如果先捕获Exception,后面的catch块将不可到达,这点需要注意。 此外,用户可能对最佳实践感兴趣,比如避免捕获过于宽泛的异常,或者如何在捕获后重新抛出异常。根据引用[2],可以展示如何包装异常并重新抛出,以保持异常链的信息。 最后,生成相关问题,帮助用户深入理解异常处理的其他方面,比如自定义异常、try-with-resources、异常处理机制等。</think>在Java中,捕获$Exception$异常需要结合$try-catch$语句块实现,以下是具体示例注意事项: ### 一、基础捕获示例 ```java try { // 可能抛出异常的代码 int result = 10 / 0; // 这里会抛出ArithmeticException } catch (Exception e) { System.out.println("捕获到异常:" + e.getMessage()); e.printStackTrace(); // 打印完整堆栈信息[^4] } ``` ### 二、多异常处理示例 ```java try { FileInputStream file = new FileInputStream("test.txt"); file.read(); } catch (FileNotFoundException e) { System.out.println("文件未找到:" + e.getMessage()); // 具体异常优先处理 } catch (Exception e) { System.out.println("通用异常捕获:" + e.getClass().getName()); // 兜底处理[^3] } ``` ### 三、异常包装与重新抛出 ```java try { // 数据库操作可能抛出SQLException } catch (SQLException e) { throw new SystemException("数据库操作失败") .set("errorCode", e.getErrorCode()) // 包装原始异常[^2] .addSuppressed(e); } ``` ### 四、注意事项 1. **捕获顺序**:子类异常应放在父类异常之前,否则子类捕获块无法到达 2. **资源管理**:使用$try-with-resources$自动关闭资源 ```java try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { // 自动关闭资源 } catch (IOException e) { // 异常处理 } ``` 3. **日志记录**:推荐使用$logger.log(Level.SEVERE, "异常信息", e)$替代$e.printStackTrace()$
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值