1. Antecedentes
El artículo que escribí aquí es porque un amigo preguntó qué diferencia entre la excepción verificada y la excepción sin control en Java. Mi respuesta fue: solo uso RuntimeException al programar. En realidad, tengo una premisa cuando digo algo. Debo decirlo exactamente: solo uso o presto atención a RuntimeException al escribir el código de negocio bajo un marco de desarrollo maduro. Porque, porque los marcos a menudo encapsulan el manejo de excepción de manera uniforme, para que los programadores puedan prestar mejor atención al código comercial, y algunos errores comerciales generalmente ocurren durante la ejecución del sistema, las excepciones comerciales generalmente se diseñan como subclases de RuntimeException.
¡Mi respuesta obviamente no puede satisfacer a mis amigos! Porque, no importa quién sea un principiante en Java, usamos mucho intento ... Catch ... cuando aprendamos las clases de IO y la programación de JDBC, este tipo de intento repetido ... ¡la captura nos hará recordar las excepciones de Java! Los principiantes a menudo no saben por qué las excepciones de Java están diseñadas así. Por lo general, solo procesan excepciones simplemente, simplemente imprima excepciones en el bloque de captura, y la declaración más utilizada es:
E.PrintStackTrace ().
También tenemos excepciones como memoria como límites de cruce de matriz:
java.lang.arrayindoxoUtofboundsexception: 6
Esto también nos hará recordarlo fresco, ¡porque a menudo aparece cuando depuramos del programa! Encontraremos que este tipo de excepción no necesita usar la prueba ... Catch ... para atraparlo en el código.
Los dos ejemplos anteriores son en realidad la excepción marcada y la excepción sin control solicitada por un amigo. La excepción que requiere intentar ... atrapar ... es la excepción verificada, y la excepción sin control es la excepción sin control. Si quiero hablar sobre sus diferencias, digo que uno de ellos quiere intentar ... atrapar ... y el otro no lo necesita. ¿Esta respuesta está bien? Creo que esta respuesta es pálida. Algunos estudiantes dirán además que intento ... Catch es obviamente una persona que llama de método que obliga a la excepción a ser manejada explícitamente. ¿E.PrintStackTrace () se considera excepciones de procesamiento? ¡Creo que es una forma simple y lento de lidiar con eso! Entonces, ¿qué tipo de método de manejo se considera inteligente? El diseñador de idiomas Java en realidad espera que después de que ocurra una excepción, la persona que llama puede restaurar la excepción en la captura para que el programa pueda continuar ejecutándose. Sin embargo, "los programadores inteligentes son flojos". Jeje. En la mayoría de los casos, elegimos registrar registros y indicaciones del usuario de la interfaz de usuario después de que aparezca la excepción. Más tarde, combinaré el marco de Jersey para hablar sobre el manejo de excepciones unificadas. Después de leer esto, algunas personas dirán que la diferencia entre la excepción verificada y la excepción sin control es que uno necesita ser procesado y el otro no necesita ser procesado. ¿Es esta respuesta correcta? ¡Creo que está mal! Mi punto es: ¡tenemos que lidiar con eso, ya sea una excepción verificada o una excepción sin control!
En el párrafo anterior, todavía no parecía resolver la diferencia entre la excepción verificada y la excepción sin control. No creo que sea importante dar la respuesta. Lo importante es cómo manejamos estas excepciones y cómo usamos excepciones durante el desarrollo.
Mi punto es (desarrollo del sistema web):
1. Encapsula la excepción verificada en el nivel de marco y conviértala en una excepción sin control para evitar escribir el tedioso intento ... Code de captura durante el desarrollo.
2. Desarrollo de nivel empresarial, defina diferentes Creciones RuntimeEx de acuerdo con las responsabilidades del código del programa (es una excepción sin control, generalmente definida como una subclase de RuntimeException)
3. A través de las dos primeras vistas, las excepciones personalizadas en el sistema solo tendrán excepciones sin control, y el sistema solo estará en la capa superior del cliente intercambiando datos, configurar un mecanismo de manejo de excepciones unificadas y convertir algunas excepciones en información que los usuarios pueden entender y transmitir a los usuarios.
4. Otros, como la capa comercial, la capa de persistencia de datos, etc., solo son responsables de lanzar excepciones, pero ten cuidado de no perder la pila de excepciones (este es un error que los principiantes son propensos a hacer).
¡El fondo es lo suficientemente largo! ¡Vamos al punto y veamos cómo se usa el controlador de excepciones unificados del marco de Jersey!
2. Mecanismo de manejo de excepciones unificadas del marco de Jersey
Hay los siguientes acuerdos:
1. El ejemplo usa la versión Jersey1.x
2. La versión de primavera es 2.5
3. Por simplicidad, el proyecto de muestra no utiliza el mecanismo Maven
Ejemplo de escenario comercial Descripción:
1. Leemos un archivo de configuración de propiedades, y el contenido del archivo de configuración es:
Key1 = Hello Key2 = Iteye.com
2. Comience una solicitud GET http: // localhost: 8888/a/recursos/test? N = 11, lo que requiere que N sea un número y debe ser inferior a 10. Si n está equivocado, se generará un error de excepción sin control.
3. En este ejemplo, la capa de acceso a datos leerá un archivo, y se producirá un error de excepción verificado si se lee el archivo.
Diseño de estructura de proyecto de muestra
Descripción del fragmento de código
1. Archivo de almacenamiento de datos: Test.Properties
Key1 = Hello Key2 = Iteye.com
Este es el archivo que queremos leer, y por simplicidad es un archivo de propiedades.
2. Clase de acceso a datos: testdao.java
paquete 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.conent; import com.iteye.redhacker.jersey.exception.DaoException; importar; com.iteye.redhacker.jersey.exception.exceptionCode; @ComponentPublic Class testDao {public String Sayshello () {classLoader classLoader = testDao.class.getClassLoader (); String Inifile = "Com/Iteye/Redhacker/Jersey/Dao/test.Properties"; ClassLoader.getResource (INiFile); InputStream is; try {is = url.OpenStream ();} Catch (ioException e) {throw New DaoException (E, ExceptionCode.Read_File_Failed);} Propiedades correctas = NULL; Try {if (apropiado == null) {apropiado = nuevo Properties ();} aproped.load (url.OpenStream ());} catch (ioException e) {throw new DaoException (e, excepcionCode.read_config_failed);} finalmente {if (is! = Null) {try {is.close (); is = null;} Catch (ioException e) {showe neoxception (e, e, e, E, Excepcioncode.colse_file_failed);}}} return adecuado.getProperty ("key1") + "," + aproped.getProperty ("key2");}}En esta clase, todas las excepciones verificadas se convierten en excepciones sin control (nuestra excepción personalizada). Al llamar al método sayhello (), intente ... atrapar ...
3. Clase de implementación comercial: TestService.Java
paquete com.iteye.redhacker.jersey.service; import org.springframework.beans.factory.annotation.autewired; import org.springframework.stereotype.component; import com.iteye.redhacker.jersey.dao.testdao; import com.iteye.rede.rede.jersey.exception.exception.exception; com.iteye.redhacker.jersey.exception.serviceException; @ComponentPublic Class testService {@autewiredPrivate testDao testDao; public String Sayshello (int n) {// Business estipula que n no puede ser mayor que 10 si (n> 10) {droga nuevo servicio (excepcionCode.must_Be_Lipula_10); testDao.sayhello ();}/** * @param testDao the testDao para establecer */public void settestDao (testDao testDao) {this.testdao = testDao;}}En esta clase, organizamos una excepción comercial propia, que es una excepción sin control.
Nota: inyectamos la clase TestDao usando @aUtowired, que es una anotación proporcionada por Spring; Debemos proporcionar un método establecido para anotar los atributos, de lo contrario, la anotación fallará.
4. Solicitar clase de acceso: testResources.java
paquete com.iteye.redhacker.jersey.delegate; import javax.ws.rs.get; import javax.ws.rs.path; import javax.ws.rs.produce; import javax.ws.rs.Queryparam; import javax.ws.core.mediatype; import.itye.redhacker.jersey.service.service.service.service; com.sun.jersey.api.spring.autowire; @path ("/test")@autowirepublic class testResources {private testService testService;@get@produces (mediatype.text_lain) public sayshello (@QueryParam ("n") int n) TestService el TestService para establecer */public void settestService (testService testService) {this.testService = testService;}}Aquí hay un recurso definido por Jersey. Podemos acceder a este recurso de esta manera: iniciar una solicitud GET, acceder al URI es /recursos /prueba y pasar un parámetro de consulta n, por ejemplo: /recursos /test? N = 1
Nota: Usamos @Autowire no es una anotación para la primavera, es una anotación para el paquete de integración de jersey-srping; Debemos proporcionar un método establecido para anotar los atributos, de lo contrario, la anotación fallará.
5. Clase de controlador de excepciones unificadas: excepcionMapperSupport.java
paquete 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.core.Respelse; importación; 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.edhacker.jersey.exception.exceptioncode; import com.sun.jersey.api.notfoundException;/*** manejador de excepción unificado*/@providerpublicpublice excepción de excepción mappersupport implementos excepcionmapper <cexception> {private static static static manejador de excepción*/@Provider Class Exceptionspappersupport Implements Implements Exceptionmappers <CECTECTE> {Private Static Static Static Logger = Logger.getLogger (excepcionMapperSupport.class); static final static final static context_attribute = webApplicationContext.root_web_application_context_attribute; @ContextPrivate httpservletRequest request; @ContextPrivate ServletContext ServletContex Handling*/Public Respuesta Toresponse (excepción de excepción) {String Message = ExceptionCode.Internal_Server_error; Status StatusCode = Status.Internal_Server_error; WebApplicationContext context = (webApplicationContext) ServletContext.getAttribute (context_Attribute); // manejar innumerable excepcion (excepcion instancefexception) {clásico {basesexception {sceException (BaseException) Exception; String Code = BaseException.getCode (); Object [] args = BaseException.getValues (); mensaje = context.getMessage (code, args, excepción.getMessage (), request.getLocale ());} else if (excepción de la instancia nocada no Status.not_found;} // Excepción verificada y las excepciones sin control se registran en log logger.error (mensaje, excepción); return response.ok (mensaje, mediatype.text_lain) .status (statuscode) .Build ();}}En esta clase, manejamos la excepción sin control que definimos, y también manejamos excepciones desconocidas del sistema (incluidas las excepciones desconocidas y las excepciones verificadas). Nuestro método de procesamiento es: a. Registrar el registro de excepciones; b. Envíe un código de estado de error estándar HTTP estándar y un mensaje de error al cliente, y el cliente maneja la información de error por sí solo. Vale la pena señalar que este método de procesamiento es recomendado por REST, y utiliza adecuadamente el código de estado estándar HTTP;
En esta clase, también utilizamos el componente de configuración internacional de Spring para internacionalizar la clave de error lanzada por el sistema, que conduce a la actualización de internacionalización de nuestro proyecto.
6. Clase base de excepción personalizada: BaseException.java
paquete com.iteye.redhacker.jersey.exception;/*** clase base de excepción, las excepciones de tiempo de ejecución de cada módulo se heredan de esta clase*/public class BaseException extiende RuntimeException {/*** The SerialVersionUid*/private estático final SerialVersionUid = 13813254798960570766l; / ** * clave de mensaje */ código de cadena privada; / ** * parámetros de mensaje */ objeto privado [] valores; / ** * @return El código */ public String getCode () {devuelve código; } / ** * @param código El código para establecer * / public void setCode (código de cadena) {this.code = code; } / *** @return los valores* / public objeto [] getValues () {valores de retorno; } / ** * @param valora los valores para establecer * / public void setValues (objeto [] valores) {this.values = valores; } public BaseException (mensaje de cadena, causa de lanzamiento, código de cadena, objeto [] valores) {super (mensaje, causa); this.code = código; this.values = valores; }}Esta clase define la plantilla básica de la clase de excepción del proyecto, y otras excepciones heredan de ella. Vale la pena señalar que utiliza hábilmente algunas características de la configuración internacional e incluso puede lanzar un mensaje de error definido a continuación, y reutilizar el mensaje de error pasando los parámetros:
{0} {1} Error de parámetro
7. Otras excepciones son básicamente las mismas, pero los tipos son diferentes. Echemos un vistazo a daoexception.java
El paquete com.iteye.redhacker.jersey.exception; public class daoException extiende BaseException {/** * constructores * * @param código * código de error */public daoException (código de cadena) {super (código, null, código, null);}/** * constructores * * @param causa * excepcionando * @param code * código público */public daoexception (TooLException (citando). {super (código, causa, código, nulo);}/** * constructores * * @param código * código de error * @param valores * Un conjunto de información de excepción parámetros pendientes */public daoException (código de cadena, objeto [] valores) {super (código, null, código, valores);}/** * constructores * * * @param causa * excepción interfacio de excepción * @param * código de error * código de error * valores * valores * de compensación * Ajuste * Ajuste * Aftuario * Ajusta * APAR * APETA * APETA * APOTO * APAR * A SET DEL AUTO * APAR * A SET DEL AUTO * APAR * A SEP Parámetros */public daoException (Causa de lanzamiento, código de cadena, objeto [] valores) {super (código, nulo, código, valores);} private estático final en serie LongUidSionUid = -3711290613973933714l;}Hereda a BaseException. Cuando se lanza esta excepción, realizamos directamente juicios preliminares desde el nombre de la excepción, y el error proviene de la capa DAO.
8. Errmsg.Properties se utiliza para definir información de excepción. Echemos un vistazo:
read.file.failed = read archivo fallido lea
Iii. Implementación y prueba
Puede descargar el código fuente en el archivo adjunto de este artículo. Después de importar Eclipse, verifique el código fuente.
La implementación es muy simple, simplemente agregue su tomcat/config/server.xml:
<Host> ... <context)
¡Comienza Tomcat!
Hacer dos pruebas:
1.
2.
Para la primera prueba, también puede ver el siguiente error de excepción en el registro:
[2013-08-15 00:25:55] [Error] El parámetro debe ser inferior a 10com.iteye.redhacker.jersey.exception.serviceException: must.be.less.than.10at com.iteye.redhacker.jersey.service.testservice.sayhello (testService.java:20) com.iteye.redhacker.jersey.delegate.testresources.sayhello (testResources.java:21) en sun.reflect.nativemethodaccessorImpl.invoke0 (método nativo) en Sun.reflect.nativemethodaccessimpl.invoke (nativemethodacCessorMepl.JaLJa:39) Sun.Reflect.DelegatingMethodacCessorImpl.invoke (delegandomethodaccessorImpl.java:25) en java.lang.reflect.method.invoke (método.java:597) en com.sun.jersey.spi.container.javamethodinvokerfactory $ 1.invoke (javamethodinvokerfactory.java:60) en com.sun.jersey.spi.container.javamethodinvokerory $ 1.invoke (javamethodinvokerfactory.java:60) AT com.sun.jersey.server.impl.model.method.dispatch.abstractresourcemethoddispatchprovider com.sun.jersey.server.impl.model.method.dispatch.resourcejavamethoddispatcher.dispatch (resourcejavamethoddispatcher.java:75) en com.sun.jersey.server.impl.uri.rules.htttpmethodrule.accept (httpmethodrule.java:288) en com.sun.jersey.server.impl.uri.rules.ResourceclassRule.accept (recursos de recursos com.sun.jersey.server.impl.uri.rules.righthandpathrule.accept (rightthandPathrule.java:147) en com.sun.jersey.server.impl.application.webapplicationImpl._handlerequest (webapplicationImpl.java:1483) en com.sun.jersey.server.imp.application.webapplationImpl._handlerequest (webapplicationiMpl.java:1414) com.sun.jersey.server.impl.application.webapplicationImpl.handlerequest (webapplationImpl.java:1363) en com.sun.jersey.server.impl.application.webapplicationImpl.HandleRequest (webapplicationImpl.Java:1353)
Para otras pruebas, puede probarlo, como eliminar deliberadamente test.properties. Cuando no se puede encontrar el archivo a leer, cómo la excepción verificada se convierte en una excepción sin control autodefinida, y lo inicia, devolviendo el código de estado de error HTTP estándar y la información de error al cliente.
4. Resumen
1. No es difícil ver a través del marco de Jersey que en el desarrollo de proyectos web, hemos manejado la excepción verificada y la excepción sin control lo de la manera más uniforme posible a nivel de marco para que podamos prestar más atención a la implementación del negocio.
2. Si se trata de un proyecto no WEB, creo que el diseñador de arquitectura del programa también debe intentar manejar las excepciones de manera uniforme; Si no se maneja de manera uniforme, cuando se encuentra una excepción verificada, debemos manejarlo adecuadamente, en lugar de simplemente hacer un E.PrintStackTrace (); Si no podemos recuperar la excepción, al menos debemos registrar la información de error de la excepción completamente en el archivo de registro para que los errores se verifiquen cuando los programas posteriores fallan.
Texto completo (final)