I. BACKGROUND
Write this article from a friend asked the Java checked exception and unchecked exception what difference, at that time I replied to it is: I only use runtimeexception programming. In fact, I say a word I have a prerequisite, exactly should say so: in the mature development framework to write business code, I only use or focus on runtimeexception. Because frameworks tend to encapsulate exception handling in such a way that programmers can better focus on business code, while some of the business's errors usually occur during system runs, the business exception is usually designed as a runtimeexception subclass.
My answer is clearly not satisfactory to my friends! Because, regardless of any beginner Java knows, when we learn the IO class and JDBC programming, we use a lot of try...catch ..., this repeated try...catch will let us to the exception of Java memory profound! Beginners often don't know why Java exceptions are designed to look like this, they usually simply deal with exceptions-simply print the exception in the catch block, with the most use of this statement:
We are also associated with some memory, such as the array of bounds such as the exception:
Java.lang.arrayindexoutofboundsexception:6
This also makes us remember, because when we debug the program, it often appears! We will find that this kind of exception does not need to use Try...catch in the code ... To catch it.
The above two examples, in fact, is a friend asked checked exception and unchecked exception, need Try...catch ... The anomaly is checked exception, and unchecked exception is not required. If you want to say their difference, I say they want to try...catch ..., one does not need, such an answer is OK? I think the answer is pale. Some students will further say that Try...catch is obviously forced to throw an exception to the method caller explicitly handle the exception, that E.printstacktrace () is not counted to deal with the exception, I think that is a simple lazy way of handling it! What kind of approach is brilliant, the Java language designer is actually expecting an exception, the caller can return the exception in the catch, so that the program can continue to carry out. However, "Smart programmers are lazy" Oh, most of the cases we choose to log the exception and the UI user prompts, I will combine the jersey framework, said that the unified exception handling. Read here, some people will say, that checked exception and unchecked exception unusual difference is that one needs to deal with, one does not need to deal with. Is that the right answer? I think it's wrong! My point is: whether it is checked exception or unchecked exception, we have to deal with!
In the last paragraph, it seems that we still haven't solved the difference between checked exception and unchecked exception, and I think how to give the answer is not important, it's how we handle these anomalies, and how we use exceptions at development time.
My point is (web system development):
1, at the framework level package checked exception, convert it into unchecked exception, avoid the development process of writing cumbersome Try...catch code.
2, the development of the business level, according to the program code responsibility to define different runtimeexception (it is unchecked exception, generally defined as RuntimeException subclass)
3, through the first two views, the system of the custom exception will only exist unchecked exception, the system is only the upper layer of the client Exchange data, set up a unified exception handling mechanism, and some exceptions to the user can understand the message conveyed to the user.
4, other such as business layer, data persistence layer, and so on the bottom is only responsible for the exception can be thrown, but be careful not to lose the exception stack (this is a beginner easy to make a mistake).
The background is long enough! Let's get to the point and see how the unified exception handler for the Jersey framework is used!
Unified exception handling mechanism of Jersey framework
There are the following conventions:
1, the example adopts jersey1.x version
2, spring version is 2.5
3. For the sake of simplicity, the example project does not use the MAVEN mechanism
Example Business Scenario Description:
1, we read a properties configuration file, the contents of the configuration file is:
Key1=hello
key2=iteye.com
2. Initiate a http://localhost:8888/a/resources/test?n=11 GET request, requiring N to be a number and must be less than 10, if n error, will produce a unchecked exception error.
3. The data access layer in this example reads a file, and reading a file error will result in a checked exception error.
Sample Project Structure Design
Code Fragment Description
1. Data storage file: Test.properties
This is the file we want to read, and for simplicity it is a properties file.
2. Data Access class: Testdao.java
Package Com.iteye.redhacker.jersey.dao;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.net.URL;
Import java.util.Properties;
Import org.springframework.stereotype.Component;
Import com.iteye.redhacker.jersey.exception.DaoException;
Import Com.iteye.redhacker.jersey.exception.ExceptionCode;
@Component public class Testdao {public String SayHello () {ClassLoader ClassLoader = TestDao.class.getClassLoader ();
String iniFile = "Com/iteye/redhacker/jersey/dao/test.properties";
URL url = classloader.getresource (iniFile);
InputStream is;
try {is = Url.openstream ();
catch (IOException e) {throw new Daoexception (E, exceptioncode.read_file_failed);
Properties proper = null;
try {if (proper = = null) {proper = new Properties ();
} proper.load (Url.openstream ());
catch (IOException e) {throw new Daoexception (E, exceptioncode.read_config_failed);
Finally {if (is!= null) {try {is.close (); is = null;
catch (IOException e) {throw new Daoexception (E, exceptioncode.colse_file_failed);
}} return Proper.getproperty ("Key1") + "," + Proper.getproperty ("Key2"); }
}
In this class, all checked exception are converted to unchecked exception (our custom exception), SayHello is no longer required when invoking the Try...catch () method ...
3, Business implementation Category: Testservice.java
Package com.iteye.redhacker.jersey.service;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.stereotype.Component;
Import Com.iteye.redhacker.jersey.dao.TestDao;
Import Com.iteye.redhacker.jersey.exception.ExceptionCode;
Import com.iteye.redhacker.jersey.exception.ServiceException;
@Component public
class Testservice {
@Autowired
private Testdao Testdao;
The public String sayhello (int n) {
/////Business specified n cannot be greater than ten
if (n >) {
throw new Serviceexception (Exceptioncode. MUST_BE_LESS_THAN_10);
}
return Testdao.sayhello ();
}
/**
* @param testdao the Testdao to set
*
/public void Settestdao (Testdao testdao) {
This.testdao = Te Stdao
}
}
In this class, we throw out a business exception of our own, it is a unchecked exception.
Note: We injected the Testdao class with @autowired, @Autowired is an annotation provided by spring; We must provide a set method to annotate the attribute, otherwise the annotation will fail.
4, Request Access class: Testresources.java
Package com.iteye.redhacker.jersey.delegate;
Import Javax.ws.rs.GET;
Import Javax.ws.rs.Path;
Import javax.ws.rs.Produces;
Import Javax.ws.rs.QueryParam;
Import Javax.ws.rs.core.MediaType;
Import Com.iteye.redhacker.jersey.service.TestService;
Import Com.sun.jersey.api.spring.Autowire;
@Path ("/test")
@Autowire public
class Testresources {
private testservice testservice;
@GET
@Produces (mediatype.text_plain) public
String SayHello (@QueryParam ("n") int n) {
return Testservice.sayhello (n);
}
/**
* @param testservice the Testservice to set
*
/public void Settestservice (Testservice testservice) { C21/>this.testservice = Testservice;
}
Here is a resource defined by jersey that we can access this resource by initiating a GET request, accessing the URI as/resources/test, and passing a query parameter n, for example:/resources/test?n=1
Note: We use the @autowire is not a note of spring, it is an annotation of the jersey-srping integration package; We must provide a set method for the annotation attribute, otherwise the annotation will fail.
5, unified Exception processor class: Exceptionmappersupport.java
Package com.iteye.redhacker.jersey.jaxrs;
Import Javax.servlet.ServletContext;
Import Javax.servlet.http.HttpServletRequest;
Import Javax.ws.rs.core.Context;
Import Javax.ws.rs.core.MediaType;
Import Javax.ws.rs.core.Response;
Import Javax.ws.rs.core.Response.Status;
Import Javax.ws.rs.ext.ExceptionMapper;
Import Javax.ws.rs.ext.Provider;
Import Org.apache.log4j.Logger;
Import Org.springframework.web.context.WebApplicationContext;
Import com.iteye.redhacker.jersey.exception.BaseException;
Import Com.iteye.redhacker.jersey.exception.ExceptionCode;
Import com.sun.jersey.api.NotFoundException; /** * Unified Exception Handler * * @Provider public class Exceptionmappersupport implements exceptionmapper<exception> {private St
atic final Logger Logger = Logger. GetLogger (Exceptionmappersupport.class);
private static final String Context_attribute = Webapplicationcontext.root_web_application_context_attribute;
@Context private HttpServletRequest request; @Context Private ServletContext SErvletcontext; /** * Exception Handling * * @param exception * @return Exception Handling Response Object * * Public Response Toresponse (Exception exception)
{String message = Exceptioncode.internal_server_error;
Status StatusCode = Status.internal_server_error;
Webapplicationcontext context = (Webapplicationcontext) servletcontext. getattribute (Context_attribute); Processing unchecked exception if (Exception instanceof baseexception) {baseexception baseexception = (baseexception) exce
ption;
String code = Baseexception.getcode ();
object[] args = Baseexception.getvalues ();
message = Context.getmessage (code, args, Exception.getmessage (), Request.getlocale ());
else if (Exception instanceof notfoundexception) {message = Exceptioncode.request_not_found;
StatusCode = Status.not_found;
}//checked exception and unchecked exception are recorded in the log logger.error (message, exception);
return Response.ok (Message, mediatype.text_plain). Status (StatusCode)-build ();
}
}
In this class we deal with the unchecked exception exception that we have defined, and also deal with the unknown exception of the system (including the unknown unchecked exception and checked exception). The way we handle this is: A, record the abnormal log; b, throw a standard HTTP standard error status code and error message to the client, which is handled by the client on its own, it is worth noting that this kind of processing is advocated by rest, it uses the HTTP standard status code properly;
In this class we also use the International configuration component of spring, which is used to internationalize the error key thrown by the system, which facilitates the internationalization of our project.
6. Custom exception base class: Baseexception.java
package com.iteye.redhacker.jersey.exception;
/** * Exception base class, each module's Run-time exception is inherited with this class/public class Baseexception extends RuntimeException {/** * the Serialversionuid
* Private static final long serialversionuid = 1381325479896057076L;
/** * Message key */private String code;
/** * Message Params * * Private object[] values;
/** * @return The code */public String GetCode () {return code;
}/** * @param the code the code to set */public void Setcode (String code) {this.code = code;
}/** * @return The values */public object[] GetValues () {return values;
}/** * @param values the values to set */public void setvalues (object[] values) {this.values = values;
Public baseexception (String message, Throwable cause, String code, object[] values) {Super (message, cause);
This.code = code;
This.values = values; }
}
This class defines the basic template for the project exception class, and other exceptions inherit from it. Notably, it takes advantage of some of the features of an internationalized configuration, and can even throw an error message that is defined below to reuse the error message by passing parameters:
{0} {1} parameter Error
7, other anomalies are basically similar, but the type is different, let's take a look at Daoexception.java
package com.iteye.redhacker.jersey.exception; public class Daoexception extends Baseexception {/** * constructors * * @param code * ERROR codes/public D
Aoexception (String code) {Super (code, NULL, code, NULL); /** * Constructors * * * @param cause * Exception interface * @param code * ERROR code */Public Daoexception (Throw
Able cause, String code) {Super (code, cause, code, NULL); /** * Constructors * * @param code * ERROR Codes * @param values * A set of exception information undetermined parameters/public Daoexceptio
N (String code, object[] values) {Super (code, NULL, code, values); /** * Constructors * * @param cause * Exception interface * @param code * ERROR code * @param values * A set of exceptions
Information pending parameters/public daoexception (throwable cause, String code, object[] values) {Super (code, NULL, code, values);
Private static final long serialversionuid = -3711290613973933714l; }
It inherits the Baseexception, and when we throw this exception, we're going to start by directly judging from the name of the exception that the error comes from the DAO layer.
8, Errmsg.properties used to define the exception information, to see:
read.file.failed= Read file failed
read.config.failed= Read configuration entry failed
must.be.less.than.10= parameter must be less than ten
colse.file.failed = Shutdown file failed
request.not.found= did not find the appropriate service
internal.server.error= server Internal Error
III. Deployment and Testing
You can download the source code in the appendix of this article. After you import eclipse, view the source.
Deployment is simple, just add your tomcat/config/server.xml:
<Host> ...
<context path= "/A" reloadable= "true" docbase= "D:/workspace/test/jerseyexceptionmappertest/web"/> </
Host>
Start Tomcat on the go!
Do two Tests:
1,
2,
For the 1th test, you can also see the following exception error in log:
[2013-08-15 00:25:55] [ERROR] parameter must be less than ten com.iteye.redhacker.jersey.exception.serviceexception:must.be.less.than.10 at Com.iteye.redhacker.jersey.service.TestService.sayHello (TESTSERVICE.JAVA:20) at Com.iteye.redhacker.jersey.delegate.TestResources.sayHello (testresources.java:21) at Sun.reflect.NativeMethodAccessorImpl.invoke0 (Native method) at Sun.reflect.NativeMethodAccessorImpl.invoke ( nativemethodaccessorimpl.java:39) at Sun.reflect.DelegatingMethodAccessorImpl.invoke ( DELEGATINGMETHODACCESSORIMPL.JAVA:25) at Java.lang.reflect.Method.invoke (method.java:597) at Com.sun.jersey.spi.container.javamethodinvokerfactory$1.invoke (javamethodinvokerfactory.java:60) at Com.sun.jersey.server.impl.model.method.dispatch.abstractresourcemethoddispatchprovider$typeoutinvoker._ Dispatch (abstractresourcemethoddispatchprovider.java:185) at Com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch ( resourcejavamethoddispatcher.java:75) at com.sun.jersey.server.impl.uRi.rules.HttpMethodRule.accept (httpmethodrule.java:288) at Com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept (resourceclassrule.java:108) at Com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept (righthandpathrule.java:147) at Com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept (rootresourceclassesrule.java:84) at Com.sun.jersey.server.impl.application.webapplicationimpl._handlerequest (webapplicationimpl.java:1483) at Com.sun.jersey.server.impl.application.webapplicationimpl._handlerequest (webapplicationimpl.java:1414) at Com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest (webapplicationimpl.java:1363) at
Com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest (webapplicationimpl.java:1353)
On some other tests, you can go to try, such as deliberately delete test.properties, when not find the file to read, checked exception is how to convert to our own definition of unchecked exception, and recorded the log , the HTTP Error status code and error message are returned to the client standard.
Iv. Summary
1, through the jersey framework we can see, in terms of Web project development, for the checked exception and unchecked exception processing we as far as possible at the framework level of the unified processing, so that we pay more attention to the implementation of the business.
2, if it is not a Web project, I think, the program architects should try to deal with the exception as much as possible, if not unified processing, when encountered checked exception, we should be appropriate to deal with the exception, rather than simply do a e.printstacktrace () If we cannot recover the exception, we should at least complete the error information of the exception to the log file, so that the subsequent program fails to troubleshoot.
Full text (end)