如何删除类方法中的try / catch重复?

时间:2015-11-13 04:36:41

标签: java rest design-patterns

我有RESTeasy服务。并且已经使用try catch对方法实现了简单的错误处理,并且觉得它不是很好。我注意到我尝试抓住所有方法的重复。所以我想问一下如何避免重复(减少代码大小)try catch但不丢失功能。

@Path("/rest")
@Logged
@Produces("application/json")
public class CounterRestService {

  @POST
  @Path("/create")
  public CounterResponce create(@QueryParam("name") String name) {
    try {
        CounterService.getInstance().put(name);
        return new CounterResponce();
    } catch (Exception e){
        return new CounterResponce("error", e.getMessage());
    }   
}

@POST
@Path("/insert")
public CounterResponce create(Counter counter) {
    try {
        CounterService.getInstance().put(counter);
        return new CounterResponce();
    } catch (Exception e){
        return new CounterResponce("error", e.getMessage());
    }
}

@DELETE
@Path("/delete")
public CounterResponce delete(@QueryParam("name") String name) {
    try {
        CounterService.getInstance().remove(name);
        return new CounterResponce();
    } catch (Exception e){
        return new CounterResponce("error", e.getMessage());
    }
}
... // other methods with some try catch pattern

响应

public class CounterResponce {
private String status;

@JsonSerialize(include=Inclusion.NON_NULL)
private Object data;

public CounterResponce() {
    this.status = "ok";
}

public CounterResponce(Object o) {
    this.status = "ok";
    this.data = o;
}

public CounterResponce(String status, Object o){
    this.status = status;
    this.data = o;
}

public String getStatus() {
    return status;
}
public void setStatus(String status) {
    this.status = status;
}
public Object getData() {
    return data;
}
public void setData(Object data) {
    this.data = data;
}
}

例外来源

public class CounterService {

private Map<String, StatisticCounter> counters = new HashMap<String, StatisticCounter>();

private static CounterService instance = null;

protected CounterService() {}

public static CounterService getInstance() {
      if(instance == null) {
         instance = new CounterService();
      }
      return instance;
}

public StatisticCounter get(String name){
    StatisticCounter c =  counters.get(name);
    if(c == null)throw new IllegalArgumentException("Counter "+name+" not exist");
    return c;
}

public void put(String name){
    if(name==null)throw new IllegalArgumentException("null can`t be as name");
    if(counters.get(name)!=null)throw new IllegalArgumentException("Counter "+name+" exist");
    counters.put(name, new Counter(name));
 }...

2 个答案:

答案 0 :(得分:1)

  1. 介绍一种私有方法,例如&#34; apply&#34;如果您使用Java 8,它可以将函数作为参数。此方法将集中处理错误处理和/或映射,响应映射和响应生成代码。
  2. 从create方法和delete方法中,调用此apply方法并将您希望执行的所需计数器操作作为lambda表达式传递。

答案 1 :(得分:1)

你问题中的评论指向了一个好的方向。由于答案没有提及,我将在这个答案中总结一般的想法。

扩展WebApplicationException

JAX-RS允许定义Java异常到HTTP错误响应的直接映射。通过扩展WebApplicationException,您可以创建特定于应用程序的异常,使用状态代码和可选消息构建HTTP响应作为响应的主体。

以下异常使用404状态代码构建HTTP响应:

public class CustomerNotFoundException extends WebApplicationException {

    /**
    * Create a HTTP 404 (Not Found) exception.
    */
    public CustomerNotFoundException() {
      super(Responses.notFound().build());
    }

    /**
    * Create a HTTP 404 (Not Found) exception.
    * @param message the String that is the entity of the 404 response.
    */
    public CustomerNotFoundException(String message) {
      super(Response.status(Responses.NOT_FOUND).
      entity(message).type("text/plain").build());
    }
}

WebApplicationException是一个RuntimeException,并不需要包含在try - catch块中或在throws子句中声明:

@Path("customers/{customerId}")
public Customer findCustomer(@PathParam("customerId") Long customerId) {
    Customer customer = customerService.find(customerId);
    if (customer == null) {
        throw new CustomerNotFoundException("Customer not found with ID " + customerId);
    }
    return customer;
}

创建ExceptionMapper s

在其他情况下,抛出WebApplicationException的实例或扩展WebApplicationException的类可能不合适,相反,最好将现有的异常映射到响应。

对于这种情况,可以使用自定义异常映射提供程序。提供者必须实现ExceptionMapper<E extends Throwable>接口。例如,以下内容将JAP EntityNotFoundException映射到HTTP 404响应:

@Provider
public class EntityNotFoundExceptionMapper 
    implements ExceptionMapper<EntityNotFoundException> {

    @Override
    public Response toResponse(EntityNotFoundException ex) {
      return Response.status(404).entity(ex.getMessage()).type("text/plain").build();
    }
}

当抛出EntityNotFoundException时,将调用EntityNotFoundExceptionMapper实例的toResponse(E)方法。

@Provider注释声明该类是JAX-RS运行时感兴趣的。可以将此类添加到配置的Application实例的类集中。