1. Antecedentes
O artigo que escrevi aqui é porque um amigo perguntou qual a diferença entre a exceção verificada e a exceção desmarcada em Java. Minha resposta foi: eu só uso o RuntimeException ao programar. Na verdade, eu tenho uma premissa quando digo alguma coisa. Devo dizer exatamente: eu só uso ou presto atenção à RunTimeException ao escrever código de negócios sob uma estrutura de desenvolvimento madura. Como, como as estruturas geralmente encapsulam o manuseio de exceção uniformemente, para que os programadores possam prestar melhor atenção ao código dos negócios, e alguns erros de negócios geralmente ocorrem durante a execução do sistema, as exceções comerciais geralmente são projetadas como subclasses da RuntimeException.
Minha resposta obviamente não pode satisfazer meus amigos! Porque, não importa quem seja iniciante em Java, usamos muita tentativa ... Catch ... Quando aprendemos aulas de IO e programação JDBC, esse tipo de tentativa repetida ... Catch nos fará lembrar das exceções de Java! Os iniciantes geralmente não sabem por que as exceções de Java são projetadas assim. Eles geralmente apenas processam exceções simplesmente - basta imprimir exceções no bloco de captura, e a afirmação mais usada é:
E.PrintStackTrace ().
Também temos exceções, como memória, como limites de cruzamento de matrizes:
java.lang.arrayIndexoutOfBoundSexception: 6
Isso também nos fará lembrar fresco, porque geralmente aparece quando depuramos o programa! Descobrimos que esse tipo de exceção não precisa usar tente ... capturar ... para pegá -lo no código.
Os dois exemplos acima são na verdade a exceção verificada e a exceção desmarcada por um amigo. A exceção que requer tentativa ... captura ... é a exceção verificada, e a exceção desmarcada é a exceção desmarcada. Se eu quiser falar sobre suas diferenças, digo que um deles quer tentar ... pegar ... e o outro não precisa. Esta resposta está ok? Eu acho que essa resposta é pálida. Alguns estudantes dirão ainda que tente ... a captura é obviamente um chamador de método que força a exceção a ser tratada explicitamente. E.PrintStackTrace () é considerado exceção de processamento? Eu acho que é apenas uma maneira simples e preguiçosa de lidar com isso! Então, que tipo de método de manuseio é considerado inteligente? O designer de idiomas Java realmente espera que, após uma exceção, o chamador possa restaurar a exceção na captura para que o programa possa continuar a executar. No entanto, "programadores inteligentes são preguiçosos". Hehe. Na maioria dos casos, optamos por registrar os logs e os avisos do usuário da interface do usuário após a exibição da exceção. Mais tarde, combinarei a estrutura de Jersey para falar sobre o manuseio de exceções unificadas. Depois de ler isso, algumas pessoas dirão que a diferença entre a exceção verificada e a exceção desmarcada é que um precisa ser processado e o outro não precisa ser processado. Esta resposta está correta? Eu acho que está errado! O que quero dizer é: temos que lidar com isso, seja uma exceção verificada ou uma exceção desmarcada!
No parágrafo anterior, ainda não parecemos resolver a diferença entre a exceção verificada e a exceção desmarcada. Eu não acho que é importante dar a resposta. O importante é como lidamos com essas exceções e como usamos exceções durante o desenvolvimento.
Meu ponto é (desenvolvimento do sistema da web):
1. Encapsular a exceção verificada no nível da estrutura e convertê -lo em uma exceção desmarcada para evitar escrever um código tedioso ... captura durante o desenvolvimento.
2. Desenvolvimento no nível dos negócios, defina diferentes vezes tempo de execução de acordo com as responsabilidades do código do programa (é uma exceção desmarcada, geralmente definida como uma subclasse da RunTimeException)
3. Através das duas primeiras visualizações, as exceções personalizadas no sistema só terão exceções desmarcadas, e o sistema estará apenas na camada superior dos dados de troca de clientes, configurará um mecanismo de manuseio de exceção unificado e converter algumas exceções em informações que os usuários podem entender e transmitir aos usuários.
4. Outros como a camada de negócios, a camada de persistência de dados etc. são responsáveis apenas por jogar exceções, mas tenha cuidado para não perder a pilha de exceção (este é um erro que os iniciantes são propensos a fazer).
O fundo é longo o suficiente! Vamos direto ao ponto e ver como o manipulador de exceção unificado da estrutura de Jersey é usado!
2. Mecanismo de manuseio de exceção unificado da estrutura de Jersey
Existem os seguintes acordos:
1. O exemplo usa a versão Jersey1.x
2. A versão da primavera é 2.5
3. Por simplicidade, o projeto de amostra não usa o mecanismo Maven
Exemplo de descrição do cenário de negócios:
1. Lemos um arquivo de configuração de propriedades e o conteúdo do arquivo de configuração é:
key1 = hello key2 = iteye.com
2. Inicie uma solicitação de get http: // localhost: 8888/a/Recursos/teste? N = 11, exigindo que N seja um número e deve ser menor que 10. Se n estiver errado, um erro de exceção não verificado será gerado.
3. Neste exemplo, a camada de acesso a dados lerá um arquivo e um erro de exceção verificado ocorrerá se o arquivo for lido.
Design da estrutura do projeto de amostra
Descrição do trecho de código
1. Arquivo de armazenamento de dados: test.properties
key1 = hello key2 = iteye.com
Este é o arquivo que queremos ler e, por simplicidade, é um arquivo de propriedades.
2. Classe de acesso a dados: testdao.java
pacote com.iteye.redhacker.jersey.dao; importar java.io.ioException; importar java.io.inputStream; importar java.net.url; importar java.util.properties; import org.springframework.steotype.component; import.iteyeties; com.iteye.redhacker.jersey.exception.ExceptionCode; @ComponentPublic class TestDao {public String SayHello () {classLoader classLoader = testDao.class.getclassloader (); string inifile = "COME"/redhacker/jesey/test.file; classLoader.getResource (iniFile); inputStream é; try {is = url.openstream ();} catch (ioexception e) {throw DaoException (e, ExceptionCode.read_file_failed);} Propriedades apropriadas = null; tentativa {if (correta == null) {); Propriedades ();} correto.Load (url.openstream ());} catch (ioexception e) {tiro a nova DaoException (e, ExceptionCode.read_config_failed);} finalmente {if (is! ExceptionCode.Colse_File_Failed);}}} Retorne corretamente.getProperty ("Key1") + "," + correta.getProperty ("key2");}}Nesta classe, todas as exceções verificadas são convertidas em exceções não controladas (nossa exceção personalizada). Ao chamar o método Sayhello (), tente ... pegar ...
3. Classe de implementação de negócios: testservice.java
pacote com.iteye.redhacker.jersey.service; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.steroType.Coment; import.iteye.redhacker.jersey.dao.tesdano; importação com.iteye.redhacker.jersey.dao.tehersdao; com.iteye.redhacker.jersey.exception.serviceException; @ComponentPublic Classe testService {@AutowiredPrivate testDao testDao; public string dizhello (int n) {// estipula de negócios que N não pode ser maior que 10 se (n> 10) {tlowExcepture testdao.sayhello ();}/** * @param testDao o testDao para definir */public void SettStdao (testdao testDao) {this.testdao = testdao;}}Nesta classe, jogamos uma exceção comercial própria, que é uma exceção desmarcada.
Nota: Injetamos a classe Testdao usando @Autowired, que é uma anotação fornecida pela primavera; Devemos fornecer um método definido para anotar os atributos, caso contrário, a anotação falhará.
4. Classe de acesso à solicitação: testResources.java
pacote com.iteye.redhacker.jersey.delegate; importar javax.ws.rs.get; importar javax.ws.rs.path; importar javax.ws.rs.produces; import javax.ws.rs.QueryParam; importheth.erk.erSev.SetHerSev.Senst.SetHerStr.SerDeStric.Senstric.SerDherSevice.SenseT.SeSTICE.MERRED.IREDHEME.MERRED.IRETHEME.MERRED.IRETHEME.MERRED.IRETHEMEM.MERRED.IMERD.IMERD.SETHEST.SEst. com.sun.jersey.api.spring.autowire; @path ("/teste")@autowirepublic classe testResources {private testService testService;@get@produz (mediatype.text_plain) public string Sayhello (@QueryParam ("n") int n) {Testert)* TestService O serviço de teste para definir */public void SettStestService (TestService TestService) {this.testService = TestService;}}Aqui está um recurso definido por Jersey. Podemos acessar esse recurso dessa maneira: iniciar uma solicitação GET, acessar o URI IS /Recursos /Teste e passar um parâmetro de consulta n, por exemplo: /Recursos /Teste? N = 1
NOTA: Usamos @Autowire não é uma anotação para a primavera, é uma anotação para o pacote de integração de Srping de Jersey; Devemos fornecer um método definido para anotar os atributos, caso contrário, a anotação falhará.
5. Classe de manipulador de exceção unificada: ExceptionMappersupport.java
pacote com.iteye.redhacker.jersey.jaxrs; importar javax.servlet.servletContext; importar javax.servlet.http.httpServletReQuest; import javax.ws.rs.core.Context; import.ws.rs.core.mediarypes; javax.ws.rs.core.Response.status; importar javax.ws.rs.ext.exceptionMapper; importar javax.ws.rs.ext.provider; importar org.apache.log4j.logger; importação org.springframework.web.context.webapplicationConxtConxtConxtConxtConxtConxtwration; com.iteye.redhacker.jersey.exception.baseexception; importar com.iteye.redhacker.jersey.exception.ExceptionCode; importar com.sun.jersey.api.notfoundExceptores;/** *** Logger.getLogger (ExceptionMappersupport.class); String final estática privada context_attribute = webApplicationContext.root_web_application_context_attribute; @ContextPrivate HttpServleTreQuest request; @CenstPrivate Mandrestrate servletContexttate; manuseio*/public Resposta TorSponse (Exceção de exceção) {String message = ExceptionCode.internal_server_error; statuscode = status.internal_server_error; webApplicationContext context_Atception (WebApplicationContext) servletContext.getAttribute (BASETRIBUTT_ATTRIBUT); // manipulação (Baseexception) Exception; String code = BasEexception.getCode (); object [] args = BasEexception.getValues (); message = context.getMessage (code, args, excepction.getMessage (), satternCode. // Exceção verificada e exceções desmarcadas são registradas no logger.error (mensagem, exceção); Retornar Response.OK (Mensagem, MediaType.Text_Plain) .status (StatusCode) .build ();}}Nesta classe, lidamos com a exceção desmarcada que definimos e também lidamos com exceções desconhecidas do sistema (incluindo exceções desconhecidas desmarcadas e exceções verificadas). Nosso método de processamento é: a. Registre o log de exceção; b. Envie um código de status de erro padrão HTTP padrão e uma mensagem de erro ao cliente, e o cliente lida com as informações de erro por si só. Vale ressaltar que esse método de processamento é defendido pelo REST e usa adequadamente o código de status padrão HTTP;
Nesta classe, também usamos o componente de configuração internacional da Spring para internacionalizar a chave de erro lançada pelo sistema, que é propício à atualização de internacionalização de nosso projeto.
6. Classe base de exceção personalizada: baseexception.java
pacote com.iteye.redhacker.jersey.exception;/*** Classe base de exceção, as exceções de tempo de execução de cada módulo são herdadas desta classe*/public class Baseexception estende o tempo de execução {/*** o serialversionUid*/private static long longVersionuid = 1381325477777777770 STATIONS STATIO / ** * Chave da mensagem */ código de sequência privada; / ** * Mensagem params */ objeto privado [] valores; / ** * @return the code */ public string getCode () {Código de return; } / ** * Código @param O código para definir * / public void setCode (código da string) {this.code = code; } / *** @RETURN Os valores* / public Object [] getValues () {retorna valores; } / ** * @param valoriza os valores a serem definidos * / public void SetValues (valores object []) {this.values = valores; } public basEexception (mensagem de string, causa jogável, código da string, valores objeto []) {super (mensagem, causa); this.code = code; this.values = valores; }}Esta classe define o modelo básico da classe de exceção do projeto e outras exceções herdam dela. Vale a pena notar que ele utiliza de maneira inteligente alguns recursos da configuração internacional e pode até lançar uma mensagem de erro definida abaixo e reutilizar a mensagem de erro passando parâmetros:
{0} {1} Erro do parâmetro
7. Outras exceções são basicamente as mesmas, mas os tipos são diferentes. Vamos dar uma olhada no DaoException.java
pacote com.iteye.redhacker.jersey.Exception; public class DaoException estende Baseexception {/** * Construtores * * Código @param * Código de erro */public DaoException (String Code) {Super (Code * Exception, interface, Código, NULL);}/** * Error * Constructors * * @Param Causa * Interface * Interface * {super(code, cause, code, null);}/** * Constructors * * @param code * Error code * @param values * A set of exception information pending parameters */public DaoException(String code, Object[] values) {super(code, null, code, values);}/** * Constructors * * @param cause * Exception interface* @param code * Error code * @param values * A set of exception information pending Parâmetros */public DaoException (causa jogável, código da string, valores do objeto []) {super (código, nulo, código, valores);} private estático final serialversionUID);Ele herda Baseexception. Quando essa exceção é lançada, fazemos diretamente julgamentos preliminares com o nome da exceção, e o erro vem da camada DAO.
8. Errmsg.Properties é usado para definir informações de exceção. Vamos dar uma olhada:
read.File.Failed = Leia o arquivo falhou read.config.failed = leia o item de configuração falhado deve.be.less.than.10 = O parâmetro deve ser menor que 10colse.File.Failed = Reset Faille Solicitação.NOT.FOUND = O serviço correspondente não foi encontrado
Iii. Implantação e teste
Você pode baixar o código -fonte no anexo deste artigo. Depois de importar o Eclipse, verifique o código -fonte.
A implantação é muito simples, basta adicionar seu tomcat/config/server.xml:
<dost> ... <context path = "/a" Reloadable = "true" docbase = "d:/workspace/test/jerseyexceptionMappertest/web"/> </host>
Basta começar o Tomcat!
Faça dois testes:
1.
2.
Para o primeiro teste, você também pode ver o seguinte erro de exceção no log:
[2013-08-15 00:25:55] [Erro] O parâmetro deve ser menor que 10com.iteye.redhacker.jersey.exception.serviceException: must.be.lel. com.iteye.redhacker.jersey.delegate.testresources.sayhello (testResources.java:21) em sun.reflect.nativemethodaccessoriMpl.invoke0 (método nativo) em sun.reflect.emeTemEthodAccessorImpl.inVoke Sun.reflect.DelegatingMethodAccessorimpl.invoke (DelegatingMethodAccessorimpl.java:25) em java.lang.reflect.method.invoke (Method.java:597) em com.sun.jersey.spi.container.javamethodinVokerFactory $ 1.inVoke (javamethodinvokerfactory.java:60) em com.sun.jersey.spi.container.javamethodinVoker $ 1.inVoke (javamethodinVacker.JavameThodinVoker $ 1.invoke (javamethodinVacker.javager.javamethodinvoker $ 1.invoke (javamethodinvackinVactor com.sun.jersey.server.impl.model.method.dispatch.abstractresourcemethoddispatchprovider $ typeoutInvoker._dispatch (abstractResourceMethoddispatchprovider.java:185) em com.sun.jersey.server.impl.model.method.dispatch.resourcejavamethoddispatcher.dispatch (ResourceJavameThodDispatcher.java:75) em com.sun.jersey.server.impl.uri.rules.httpmethodrule.accept (httpmethodrule.java:288) em com.sun.jersey.server.impl.uri.rules.resourcouclassrule.accept (resourclect.mpl.uri.rules.resourcouclassrule.accept (reswerCeclR. com.sun.jersey.server.impl.uri.rules.RightHandPathRule.CEcept (RightHandPathrule.java:147) em com.sun.jersey.server.impl.uri.Rules.rootresourCeclassesRule.Accept (rootsourcecs.urcec.rootresourclecsRule.accept (rootsourccecCec. com.sun.jersey.server.impl.application.webApplicationImpl._handlerequest (webApplicationImpl.java:1483) em com.sun.jersey.server.implication.application.webapplicationImpl._Handlerequest (webAppLicationMimmimmimmimmlic.MPlication.WebAppLicationImpl._Handlerequest (webApplicationMimMimmimmiMimmimmlication.WebAppLicationImP. com.sun.jersey.server.impl.application.webApplicationImpl.handlerequest (webApplicationImpl.java:1363) em com.sun.jersey.server.implication.application.webApplicationImpl.HandleQuest (webAppLicationAmPlication.JAVACATIONS.WEBAPPLICATIONIMPLICATIONSPLICATION3.JAVAMPLICATION3.WEBAPLICATIONIMPLICATION1.JAPLICATION1
Para outros testes, você pode experimentá -lo, como excluir deliberadamente o teste.properties. Quando o arquivo a ser lido não pode ser encontrado, como a exceção verificada é convertida em uma exceção desmarcada autodefinida e o registra, retornando o código de status de erro HTTP padrão e informações de erro ao cliente.
4. Resumo
1. Não é difícil ver através da estrutura de Jersey que, no desenvolvimento do projeto da web, lidamos com a exceção verificada e a exceção desmarcada o mais uniformemente possível no nível da estrutura, para que possamos prestar mais atenção à implementação dos negócios.
2. Se for um projeto que não seja da Web, acho que o designer de arquitetura do programa também deve tentar lidar com exceções de maneira uniforme; Se não for tratado uniformemente, quando uma exceção verificada for encontrada, devemos lidar com isso adequadamente, em vez de simplesmente fazer um e.printstacktrace (); Se não pudermos recuperar a exceção, devemos pelo menos registrar completamente as informações de erro da exceção no arquivo de log para que os erros sejam verificados quando os programas subsequentes falharem.
Texto completo (final)