注入服务的REST端点 - 在哪里抛出自定义WebServiceException?

时间:2016-07-27 11:23:50

标签: java rest exception jersey guice

我有REST端点,它注入了服务。

@Singleton
@Path("/v1/service")
public class MyService {

    @Inject
    private TokenService tokenService;

    @Inject
    private InfoService infoService;

    @GET
    @Path("/info")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public InfoResponse getInfo(@HeaderParam("Authorization") String token){

        tokenService.validateToken(token);

        List<String> info = infoService.getInfo();

        // processing info code, throwing WebServiceException if something wrong

       return new InfoResponse(info);
    }
}

其中一些验证数据,例如令牌,如果不正确,则抛出RestServiceException异常。异常由ExceptionMapper处理,因此返回适当的Response。其他服务返回/处理信息。

我的自定义异常类以及其他字段:

public class RestServiceException extends WebServiceException {

    public Integer httpStatus;

    public String message;
}

示例服务方法:

public User getUser(Long userId){

    User user = userMapper.getUser(userId);

    if (user == null){
        String msg = "Invalid user: " + userId;
        logger.debug(msg);
        throw new RestServiceException(HttpStatus.SC_NOT_FOUND, InternalStatus.INVALID_USER, msg);
    }

    return user;
}

在注入的服务中抛出RestServiceException是一种好习惯吗?如何设计代码以方便测试?在哪里放置验证方法 - 服务或静态类?

1 个答案:

答案 0 :(得分:1)

  

在注入的服务中抛出WebServiceException是不错的做法?

我不会。

  1. 使服务不能在jax-rs应用程序之外重用(对您来说可能没什么问题)。
  2. 打破&#34;分层&#34;架构规则;较低的水平不应该知道关于上层的任何事情。您应该抛出一个正常的服务级别异常,如果要包装WebApplicationException,则从那里捕获资源中的异常,然后执行此操作。

    也许只是抛出WebApplicationException并未考虑&#34;了解上层&#34;,但我个人觉得它确实如此,因为异常类型特定于上层。< / p>

  3.   

    如何设计代码以方便测试?

    使用构造函数注入而不是字段注入。如果需要,可以更轻松地为资源提供模拟服务。

    public class MyService {
    
        private final TokenService tokenService;
        private final InfoService infoService;
    
        @Inject
        public MyService(TokenService tokenService,
                         InfoService infoService) {
            this.tokenService = tokenService;
            this.infoService = infoService;
        }
    }
    
      

    在哪里放置验证方法 - 服务或静态类?

    这并没有多大意义。如果通过&#34;静态类&#34;你的意思是单身模式单身,然后绝对不是那个。使用控制反转你当前正在做的方式是更好的选择。

    更新

    我想我读错了你的问题。出于某种原因,我将您的WebServiceException视为JAX-RS WebApplicationException

    我猜我上面提到的规则并不适用。但我可能会将异常的名称更改为WebServiceException以外的其他名称。这与上层&#34; web&#34;层。将特定于该服务的异常命名为。

    关于在资源级别处理例外情况,如果您不想要,则在ExceptionMapper正在处理它时,您不需要对其执行任何操作。或者,如果需要,可以将其包裹起来并将其包装在WebApplicationException

    您可以查看this post的底部,其中列出了WebApplicationException的所有子类。如果需要,可以将异常包装在其中一个中并抛出它。这些例外都是映射到状态代码。