Reputation: 7852
I have RESTeasy service. And have implemented simple error handling on methods using try catch
and feel something is not very well with it. I've noticed try catch repetition on all my methods. So I want ask way how to avoid repetition (to reduce code size) of try catch
but not lost functionality.
@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
response
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;
}
}
exceptions source
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));
}...
Upvotes: 1
Views: 2410
Reputation: 131067
The comments in your question are pointing you in a good direction. Since the answers do not mention it, I'll summarize the general idea in this answer.
WebApplicationException
JAX-RS allows to define direct mapping of Java exceptions to HTTP error responses. By extending WebApplicationException
, you can create application specific exceptions that build a HTTP response with the status code and an optional message as the body of the response.
The following exception builds a HTTP response with the 404
status code:
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
is a RuntimeException
and doesn't need to the wrapped in a try
-catch
block or be declared in a throws
clause:
@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
sIn other cases it may not be appropriate to throw instances of WebApplicationException
, or classes that extend WebApplicationException
, and instead it may be preferable to map an existing exception to a response.
For such cases it is possible to use a custom exception mapping provider. The provider must implement the ExceptionMapper<E extends Throwable>
interface. For example, the following maps the JAP EntityNotFoundException
to a HTTP 404
response:
@Provider
public class EntityNotFoundExceptionMapper
implements ExceptionMapper<EntityNotFoundException> {
@Override
public Response toResponse(EntityNotFoundException ex) {
return Response.status(404).entity(ex.getMessage()).type("text/plain").build();
}
}
When an EntityNotFoundException
is thrown, the toResponse(E)
method of the EntityNotFoundExceptionMapper
instance will be invoked.
The @Provider
annotation declares that the class is of interest to the JAX-RS runtime. Such class may be added to the set of classes of the Application
instance that is configured.
Upvotes: 1
Reputation: 195
Upvotes: 1