猿问

如何在GWT的SERVER端添加异常处理程序?

我想包装来自GWT服务器的所有传出异常(仅服务器,客户端上没有任何内容):


public class AuthServiceImpl extends RemoteServiceServlet implements AuthService {

    public String loginAttemt(String username, String password) {

        AwesomeUser user = AwesomeUserDao.forUsername(username);

        if(BCrpyt.checkpw(user.getPasshash(), password)) {

            String code = magicallyGenerateErrorCode();

            logger.error("Invalid login attempt - error code"  + code);

            throw new AwesomeException("password", "Invalid username or password", code);

        }

    }

}


@RemoteServiceRelativePath("auth")

public interface AuthService extends RemoteService {

    String loginAttempt(String username, String password) throws AwesomeException;

}


public interface AuthServiceAsync {

    void loginAttempt(String username, String password, AsyncCallback<String> callback) throws AwesomeException;

}

现在,这可行。在我的客户端上,我只是做这样的事情(getField(String)出于不相关的原因我做了一些自定义,但这很重要)


public void onFailure(Throwable caught) {

    if(caught instanceof AwesomeException) {

        AwesomeException a = (AwesomeException)caught;

        getField(a.getfield()).setErrorText(a.getText());

        getField("error-code").setText(a.getCode());

    }

}

是的,这按预期工作。但是,想一想那user是null-你们中的一些人可能已经读到“哦,伙计,如果用户名不存在,他可能在那里有NPE”,您是绝对正确的。而且可以肯定的是,我确实在为这类事情编写代码。但是,我不会抓住所有这些情况。我想在某个地方添加一个异常处理程序,该异常处理程序捕获所有这些异常并将其包装在其中AwesomeException-特别是这样,我可以将相关的错误代码传递给用户,以便他们可以与支持人员联系以解决问题。我不想依靠程序员总是记住每个可能的null和非法参数以及所有其他运行时异常。我当然不希望他们自满,


(错误代码实际上是一个请求ID-每个请求都有一个ID,并且所有日志消息在打印时都会使用该ID-因此,如果它们报告了错误代码,我们可以非常轻松地查看带有该请求的所有日志消息并解决错误)


我尝试跟踪回调,但最终在RPC类中迷路了。但可以肯定的是,我不是第一个尝试拦截服务器发出的GWT异常的人,对吗?


潇潇雨雨
浏览 135回答 2
2回答

紫衣仙女

除了扩展服务之外RemoteServiceServlet,您还可以创建自己的servlet并委托给RemoteServiceServlet类似的东西:public class GwtServiceServlet extends HttpServlet {&nbsp; &nbsp; public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {&nbsp; &nbsp; &nbsp; &nbsp; Object delegate = ...;&nbsp; &nbsp; &nbsp; &nbsp; RemoteServiceServlet remoteServiceServlet = new RemoteServiceServlet(delegate);&nbsp; &nbsp; &nbsp; &nbsp; remoteServiceServlet.init(getServletConfig());&nbsp; &nbsp; &nbsp; &nbsp; remoteServiceServlet.doPost(request, response);&nbsp; &nbsp; }}delegate服务接口的实现在哪里。由于您正在控制服务实现的创建,因此现在可以将其包装在代理中以转换异常或进行日志记录。

慕盖茨4494581

这可以通过扩展RemoteServiceServlet和在例如processCall(RPCRequest rpcRequest)或中进行异常处理来完成doUnexpectedFailure(Throwable e)。例如:仅针对不属于服务方法签名的异常或错误,或由SecurityException,SerializationExceptions或RPC框架内的其他故障导致的异常或错误调用此方法。意味着这里可以将任何NPE等映射到自定义异常。&nbsp; protected void doUnexpectedFailure(Throwable e) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; getThreadLocalResponse().reset();&nbsp; &nbsp; } catch (IllegalStateException ex) {&nbsp; &nbsp; &nbsp; /*&nbsp; &nbsp; &nbsp; &nbsp;* If we can't reset the request, the only way to signal that something&nbsp; &nbsp; &nbsp; &nbsp;* has gone wrong is to throw an exception from here. It should be the&nbsp; &nbsp; &nbsp; &nbsp;* case that we call the user's implementation code before emitting data&nbsp; &nbsp; &nbsp; &nbsp;* into the response, so the only time that gets tripped is if the object&nbsp; &nbsp; &nbsp; &nbsp;* serialization code blows up.&nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; throw new RuntimeException("Unable to report failure", e);&nbsp; &nbsp; }&nbsp; &nbsp; ServletContext servletContext = getServletContext();&nbsp; &nbsp; String code = magicallyGenerateErrorCode();&nbsp; &nbsp; AwesomeException awesomeException = new AwesomeException("error", "Unexpected Error. Pls contact support", code);&nbsp; &nbsp; RPCServletUtils.writeResponseForUnexpectedFailure(servletContext,&nbsp; &nbsp; &nbsp; &nbsp; getThreadLocalResponse(), awesomeException);&nbsp; }
随时随地看视频慕课网APP

相关分类

Java
我要回答