1. 배경
내가 여기에 쓴 기사는 친구가 Java에서 확인 된 예외와 선택되지 않은 예외의 차이점을 물었 기 때문입니다. 그것에 대한 나의 대답은 : 나는 프로그래밍 할 때만 runtimeexception 만 사용했다. 사실, 나는 무언가를 말할 때 전제가 있습니다. 나는 그것을 정확하게 말해야한다 : 나는 성숙한 개발 프레임 워크 아래에서 비즈니스 코드를 작성할 때만 런 티미 셀로 인식에만주의를 기울이거나주의를 기울여야한다. 프레임 워크는 종종 예외 처리를 균일하게 캡슐화하기 때문에 프로그래머는 비즈니스 코드에 더 나은주의를 기울일 수 있고 일부 비즈니스 오류는 일반적으로 시스템 실행 중에 발생하기 때문에 일반적으로 비즈니스 예외는 일반적으로 runtimeexception의 서브 클래스로 설계됩니다.
내 대답은 분명히 내 친구들을 만족시킬 수 없습니다! Java의 초보자가 누구인지에 관계없이 우리는 많은 시도를 사용합니다 ... 캐치 ... 우리가 IO 수업과 JDBC 프로그래밍을 배울 때, 이런 종류의 반복 시도 ... Catch는 우리가 Java의 예외를 기억하게 만들 것입니다! 초보자는 종종 Java 예외가 왜 이와 같이 설계되었는지 모릅니다. 일반적으로 예외 만 처리합니다. 단순히 캐치 블록에 예외를 인쇄하면 가장 일반적으로 사용되는 문장은 다음과 같습니다.
e.printstacktrace ().
또한 배열 교차점 경계와 같은 메모리와 같은 예외도 있습니다.
java.lang.arrayindexoutofboundsexception : 6
이것은 또한 우리가 프로그램을 디버깅 할 때 종종 나타나기 때문에 우리를 신선하게 기억하게 만들 것입니다! 우리는이 유형의 예외가 시도를 사용할 필요가 없다는 것을 알게 될 것입니다 ... Catch ... 코드에서 잡을 수 있습니다.
위의 두 예제는 실제로 확인 된 예외이며 친구가 요청한 예외를 확인하지 않았습니다. 시도가 필요한 예외는 ... 캐치 ... 점검 된 예외이며, 확인되지 않은 예외는 확인되지 않은 예외입니다. 그들의 차이에 대해 이야기하고 싶다면, 그들 중 하나는 시도하고 싶어한다고 말합니다 ... 캐치 ... 그리고 다른 하나는 그것을 필요로하지 않습니다. 이 대답은 괜찮습니까? 이 대답이 창백하다고 생각합니다. 일부 학생들은 시도해 볼 것입니다 ... Catch는 분명히 예외를 명시 적으로 처리하도록 강요하는 방법 발신자입니다. e.printstacktrace ()가 처리 예외로 간주됩니까? 나는 그것이 그것을 다루는 단순하고 게으른 방법이라고 생각합니다! 그렇다면 어떤 종류의 취급 방법이 영리한 것으로 간주됩니까? Java Language Designer는 실제로 예외가 발생한 후 발신자가 프로그램의 예외를 복원하여 프로그램이 계속 실행될 수 있다고 기대합니다. 그러나 "스마트 프로그래머는 게으르다." 헤헤. 대부분의 경우 예외가 나타난 후 로그 및 UI 사용자 프롬프트를 기록하도록 선택합니다. 나중에 저지 프레임 워크를 결합하여 통합 예외 처리에 대해 이야기하겠습니다. 이 글을 읽은 후, 어떤 사람들은 확인 된 예외와 확인되지 않은 예외의 차이점이 처리되어야하고 다른 사람들은 처리 할 필요가 없다고 말할 것입니다. 이 답변이 맞습니까? 틀린 것 같아요! 내 요점은 : 우리는 그것이 점검 된 예외이든 선택되지 않은 예외인지를 다루어야한다는 것입니다!
이전 단락에서는 여전히 확인 된 예외와 선택되지 않은 예외의 차이를 해결하지 못하는 것 같습니다. 나는 답을주는 것이 중요하다고 생각하지 않습니다. 중요한 것은 이러한 예외를 처리하는 방법과 개발 중 예외를 사용하는 방법입니다.
내 요점은 (웹 시스템 개발) :
1. 프레임 워크 레벨에서 확인 된 예외를 캡슐화하고 지루한 시도를하지 않도록 검사되지 않은 예외로 변환하십시오. 개발 중 코드를 잡으십시오.
2. 비즈니스 수준 개발, 프로그램 코드 책임에 따라 다른 runtimeexceptions를 정의합니다 (일반적으로 runtimeexception의 서브 클래스로 정의되는 점검되지 않은 예외입니다).
3. 처음 두 뷰를 통해 시스템의 사용자 정의 예외는 검사되지 않은 예외 만 나타나며 시스템은 클라이언트 교환 데이터의 상단 계층에만 통합 된 예외 처리 메커니즘을 설정하며 사용자가 사용자에게 이해하고 전달할 수있는 정보로 일부 예외를 변환합니다.
4. 비즈니스 계층, 데이터 지속성 계층 등과 같은 다른 사람들은 예외를 던지는 일만 책임을지만 예외 스택을 잃지 않도록주의하십시오 (이것은 초보자가 제작하기 쉬운 실수입니다).
배경은 충분히 길다! 요점에 가서 저지 프레임 워크의 통합 예외 처리기가 어떻게 사용되는지 살펴 보겠습니다!
2. 저지 프레임 워크의 통합 예외 처리 메커니즘
다음 계약이 있습니다.
1. 예제는 Jersey1.x 버전을 사용합니다
2. 스프링 버전은 2.5입니다
3. 단순화를 위해 샘플 프로젝트는 Maven 메커니즘을 사용하지 않습니다.
예제 비즈니스 시나리오 설명 :
1. 속성 구성 파일을 읽고 구성 파일의 내용은 다음과 같습니다.
key1 = hello key2 = iteye.com
2. GET 요청 http : // localhost : 8888/a/resource/test? n = 11, n은 숫자가되어야하고 10보다 작아야합니다. n이 잘못되면 확인되지 않은 예외 오류가 생성됩니다.
3.이 예에서는 데이터 액세스 계층이 파일을 읽고 파일을 읽으면 확인 된 예외 오류가 발생합니다.
샘플 프로젝트 구조 설계
코드 스 니펫 설명
1. 데이터 저장 파일 : test.properties
key1 = hello key2 = iteye.com
이것은 우리가 읽고 싶은 파일이며 단순화하기 위해 속성 파일입니다.
2. 데이터 액세스 클래스 : 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.stereotyp.component; import com.iteye.redhacker.jersey.daoxcement com.iteye.redhacker.jersey.exception.exceptioncode; @componentpublic class testdao {public string sayhello () {classloader classloader = testdao.class.getclassloader (); String Inifile = "com/iteye/redhacker/jersey/dao/test.properties"; classLoade.getResource (inifile); inputStream은; try {is = url.openstream ();} catch (ioexception e) {wrach new daoexception (e, exception.read_file_filed);} properties apply = null; try (proper = null) {null = new properties ();} apply.load (url.openstream ());} catch (ioexception e) {e, exceptioncode.read_config_failed);} 마지막으로 {if (is! = null) {try {is.close (); is = null e) {wash new daoexceme (e) ExceptionCode.colse_file_failed);}}} return reture.getProperty ( "key1") + "," + 적절한.getProperty ( "key2");}}이 클래스에서 확인 된 모든 예외는 확인되지 않은 예외 (우리의 사용자 정의 예외)로 변환됩니다. SayHello () 메소드를 호출 할 때 시도해보십시오 ... 잡기 ...
3. 비즈니스 구현 클래스 : TestService.java
package com.iteye.redhacker.jersey.service; import org.springframework.bean.beans.beans.annotation.autowired; import org.spramframework.stereotyp.component; import com.itey.redhacker.jersey.dao.testdao; import com.iteye.redhacker.jersey.exmencecode; com.iteye.redhacker.jersey.exception.serviceException; @componentPublic 클래스 testservice {@autowiredprivate testdao testdao; public string sayshello (int n) {// business sistipulates (n> 10) {rask new serviceEction.must__ve_10). testdao.sayhello ();}/** * @param testdao testdao set */public void settestdao (testdao testdao) {this.testdao = testdao;}}이 수업에서 우리는 선택되지 않은 예외입니다.
참고 : @autowired를 사용하여 TestDao 클래스를 주입했습니다. @autowired는 Spring에서 제공하는 주석입니다. 속성에 주석을 달 수있는 정해진 방법을 제공해야합니다. 그렇지 않으면 주석이 실패합니다.
4. 액세스 클래스 요청 : 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.rs.core.mediatype; import com.iteye.redhacker.jersey.service.tervice com.sun.jersey.spri.spring.autowire; @path ( "/test")@autowirepublic class testresources {private testservice testservice;@get@kectes (mediaType.text_plain) public string sayshello (@QueryParam ( "n") int n) {return redervice.sayhello (n); testservice testservice를 설정하여 */public void settestservice (testservice testservice) {this.testservice = testservice;}}다음은 저지가 정의한 리소스입니다. 이러한 방식 으로이 리소스에 액세스 할 수 있습니다. GET 요청을 시작하고 URI IS /RESSOR /TEST에 액세스하고 쿼리 매개 변수 N을 전달합니다.
참고 : 우리는 @autowire를 사용했는데 봄에는 주석이 아니며 Jersey-Srping Integration 패키지에 대한 주석입니다. 속성에 주석을 달 수있는 정해진 방법을 제공해야합니다. 그렇지 않으면 주석이 실패합니다.
5. Unified Exception Handler 클래스 : ExceptionMappersUpport.java
package com.iteye.redhacker.jersey.jaxrs; import javax.servlet.servletcontext; import javax.servlet.http.httpservletrequest; import javax.ws.rs.core.context; import javav.ws.rs.core.mediatepe; import javax.ws.rs.core.core javax.ws.rs.rs.core.response.status; import javax.ws.rs.ext.exceptmapper; import javax.ws.rs.rs.ext.ext.provider; import org.apache.log4j.logger; import org.spramframework.web.context.webapplicationContext; com.iteye.redhacker.jersey.exception.baseexception; import com.iteye.redhacker.jersey.exception.exceptioncode; import com.sun.jersey.api.notfoundexception;/*** Unified Exception*/@ProviderPublic Class ExceptionMappser <Exception appport appport empless emport emplate em unified exception*/@providerpublic class expressmappers emport emplation < logger.getLogger (ExceptionMappersUpport.class); 개인 정적 최종 문자열 context_attribute = webApplicationContext.root_web_Application_context_attribute; @contextPrivate httpservletRequest 요청; @ContextPrivate ServletContext ServletContext * @ContextPrivate servletontext;/** ** 예외 처리 처리*/공개 응답 toresponse (예외 예외) {string message = exceptioncode.internal_server_error; status statescode = status.internal_server_error; webApplicationContext context = (webApplicationContext) servletcontext (context_attribute); geteexection (baseexection) {exception of incisteocectement (context_attribute); (Bainexception) 예외; String Code = BaveException.getCode (); object [] args = baveseception.getValues (); message = context.getMessage (code, args, exception.getmessage (), request.getLocale ());} else (explorindof notFoundException) {exceptCode.Request_NOT_OOD =; status.not_found;} // 점검 된 예외 및 확인되지 않은 예외는 logger.error (메시지, 예외)에 기록됩니다. return response.ok (메시지, mediaType.text_plain) .status (statusCode) .build ();}}이 클래스에서는 우리가 정의한 선택되지 않은 예외를 처리하고 시스템의 알려지지 않은 예외 (확인되지 않은 예외 및 점검 된 예외 포함)를 처리합니다. 우리의 처리 방법은 다음과 같습니다. 예외 로그를 기록하십시오. 비. 표준 HTTP 표준 오류 상태 코드 및 오류 메시지를 클라이언트에게 보내면 클라이언트가 오류 정보를 자체적으로 처리합니다. 이 처리 방법은 휴식에 의해 옹호되며 HTTP 표준 상태 코드를 적절하게 사용한다는 점은 주목할 가치가 있습니다.
이 클래스에서는 Spring의 국제 구성 구성 요소를 사용하여 시스템이 던진 오류 키를 국제화하는데, 이는 프로젝트의 국제화 업그레이드에 도움이됩니다.
6. 사용자 정의 예외 기반 클래스 : Bainexception.java
package com.iteye.redhacker.jersey.xception;/*** 예외 기반 클래스, 각 모듈의 런타임 예외는이 클래스에서 상속됩니다*/public class baseexception은 runtimeexception을 확장합니다. {/*** serialversionuid*/private static final long serialversionuid = 138132547980576L; / ** * 메시지 키 */ 개인 문자열 코드; / ** * 메시지 매개 변수 */ 개인 객체 [] 값; / ** * @return 코드 */ public string getCode () {return code; } / ** * @param 코드 설정 * / public void setCode (문자열 코드) {this.code = code; } / *** @value* / public object [] getValues () {return 값; } / ** * @param 값 값을 설정하도록 값 * / public void setValues (Object [] value) {this.values = values; } public bainxception (문자열 메시지, 던지기 가능한 원인, 문자열 코드, 개체 [] 값) {super (메시지, 원인); this.code = 코드; this.values = 값; }}이 클래스는 프로젝트 예외 클래스의 기본 템플릿을 정의하고 기타 예외는 상속됩니다. 국제 구성의 일부 기능을 영리하게 활용하고 아래에 정의 된 오류 메시지를 던지고 매개 변수를 전달하여 오류 메시지를 재사용 할 수 있다는 점은 주목할 가치가 있습니다.
{0} {1} 매개 변수 오류
7. 다른 예외는 기본적으로 동일하지만 유형은 다릅니다. daoexception.java를 살펴 보겠습니다
package com.iteye.redhacker.jersey.xception; public class daoexception은 baseexception을 확장합니다 {/** * 생성자 * * @param code * error code */public daoexception (string code) {super (code, null, code, null);}/** * @param code */public code */public code */public code */public code (public code) {super (코드, 원인, 코드, null);}/** * 생성자 * * @param code * 오류 코드 * @param 값 * 예외 정보 세트 보류 매개 변수 */public daoexception (string code, object [] value) {super, code, code, code, code * @param value * @param value * a @param value * 매개 변수 */public daoexception (Throwable 원인, 문자열 코드, 개체 [] 값) {super (코드, 널, 코드, 값);} 개인 정적 최종 최종 SerialVersionUid = -37112906139733714L;}그것은 Bainexception을 물려받습니다. 이 예외가 발생하면 예외 이름에서 예비 판단을 직접 판단하고 오류는 DAO 레이어에서 나옵니다.
8. errmsg.properties는 예외 정보를 정의하는 데 사용됩니다. 살펴 보겠습니다.
read.file.failed = 읽기 실패 read.config.failed = 구성 항목이 실패했다.
III. 배포 및 테스트
이 기사의 첨부에서 소스 코드를 다운로드 할 수 있습니다. Eclipse를 가져 오면 소스 코드를 확인하십시오.
배포는 매우 간단합니다. tomcat/config/server.xml을 추가하십시오.
<host> ... <context path = "/a"Reloadable = "true"docbase = "d :/workspace/test/jerseyExceptionMapperTest/Web"/> </host>
Tomcat을 시작하십시오!
두 가지 테스트를 수행하십시오.
1.
2.
첫 번째 테스트의 경우 로그에서 다음 예외 오류를 볼 수 있습니다.
[2013-08-15 00:25:55] [오류] 매개 변수는 10com.iteye.redhacker.jersey.exception.serviceexception : must.be.less.10at com.iteye.redhacker.jersey.service.testservice.sayhello (recedservice.java:20) at com.iteye.redhacker.jersey.delegate.testresources.testresources.sayhello (testresources.java:21) sun.reflect.nativemethodaccessorimpl.invoke0 (Native Method)에서 sun.reflect.nativemedaccessorimpl.invoke sun.reflect.delegatingMethodaccessorimpl.invoke (java.lang.reflect.method.invoke (method.java:597)의 Voke (위임 methodaccessorimpl.java:25) at com.sun.jersey.spi.container.javamethodinvokerfactory $ 1. invoke (javamethodinvokerfactory.java:60) at com.sun.jersey.spi.container.javamethodinvoker factory $ 1.invoke (javamethodinvokerfactory.java:60) at com.sun.jersey.server.impl.model.method.dispatch.abstresourcemethoddispatchprovider $ 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.accrect (httpmethodrule.java:288) at com.sun.jersey.server.impl.uri.rules.resourceclassruce (resourceclassrucececcept) at com.sun.jersey.server.impl.uri.rules.righthandpathrule.accrect (righthandpathrule.java:147)의 com.sun.jersey.server.impl.uri.rules.rootresourceclassesrule.accrect (rootresourclassesruceccept (rootresourceclassesrule) 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).
다른 테스트의 경우 의도적으로 Test.properties와 같은 시도해 볼 수 있습니다. 읽을 파일을 찾을 수없는 경우 확인 된 예외가 자체 정의되지 않은 예외로 변환되는 방법을 기록하고 로그인하여 표준 HTTP 오류 상태 코드 및 오류 정보를 클라이언트에 반환합니다.
4. 요약
1. 저지 프레임 워크를 통해 웹 프로젝트 개발에서 우리는 비즈니스 구현에 더 많은주의를 기울일 수 있도록 체크 프로젝트 개발에서 가능한 한 균일하게 확인되지 않은 예외와 검사되지 않은 예외를 처리했습니다.
2. WEB가 아닌 프로젝트 인 경우 프로그램 아키텍처 설계자도 예외를 균일하게 처리해야한다고 생각합니다. 균일하게 처리되지 않으면 확인 된 예외가 발생하면 E.printstacktrace ()를 단순히 수행하는 대신 적절하게 처리해야합니다. 예외를 복구 할 수없는 경우 로그 파일에 예외의 오류 정보를 최소한 기록하여 후속 프로그램이 실패 할 때 오류가 확인되도록해야합니다.
전체 텍스트 (끝)