wpadłem na ten sam problem i postanowił, że nie chcą szablonowe gazillion zerowe kontrole rozrzuconych po moim kodu REST, więc to jest to, co postanowiłem zrobić:
- Tworzenie adnotacji, które powoduje wyjątek, który zostanie zgłoszony, gdy nie zostanie podany wymagany parametr.
- Obchodź wyrzucony wyjątek w taki sam sposób, w jaki radzę sobie z wszystkimi innymi wyjątkami wyrzuconymi w moim kodzie REST.
Dla 1), I wdrożone następujące adnotacje:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Required
{
// This is just a marker annotation, so nothing in here.
}
... i następujące JAX-RS ContainerRequestFilter
aby je egzekwować:
import java.lang.reflect.Parameter;
import javax.ws.rs.QueryParam;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
@Provider
public class RequiredParameterFilter implements ContainerRequestFilter
{
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext)
{
// Loop through each parameter
for (Parameter parameter : resourceInfo.getResourceMethod().getParameters())
{
// Check is this parameter is a query parameter
QueryParam queryAnnotation = parameter.getAnnotation(QueryParam.class);
// ... and whether it is a required one
if (queryAnnotation != null && parameter.isAnnotationPresent(Required.class))
{
// ... and whether it was not specified
if (!requestContext.getUriInfo().getQueryParameters().containsKey(queryAnnotation.value()))
{
// We pass the query variable name to the constructor so that the exception can generate a meaningful error message
throw new YourCustomRuntimeException(queryAnnotation.value());
}
}
}
}
}
Musisz się zarejestrować ContainerRequestFilter
w ten sam sposób, w jaki rejestrujesz inne klasy @Provider
z biblioteką JAX-RS. Może RESTEasy robi to automatycznie.
Dla 2), obsłużyć wszystkie wyjątki w czasie wykonywania przy użyciu JAX-RS generyczne ExceptionMapper
:
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class MyExceptionMapper implements ExceptionMapper<RuntimeException>
{
@Override
public Response toResponse(RuntimeException ex)
{
// In this example, we just return the .toString() of the exception.
// You might want to wrap this in a JSON structure if this is a JSON API, for example.
return Response
.status(Response.Status.BAD_REQUEST)
.entity(ex.toString())
.build();
}
}
Tak jak poprzednio, należy zarejestrować klasę z biblioteki JAX-RS.
Można dodać adnotację '@ DefaultValue' i ustawić parametr na odpowiednią wartość, gdy jej brakuje. Jeśli nie możesz mieć wartości domyślnej, a parametr jest naprawdę ważny, być może powinieneś sprawdzić parametr "null" i zwrócić kod statusu "400 żądania". – toniedzwiedz