我使用RESTEasy JAX-RS实现将Web服务组件部署到JBoss Application Server 7.
是否有注释可用于在JAX-RS中声明必需的@QueryParam参数?而且,如果没有,那么处理缺少这些参数的情况的"标准"方法是什么?
当使用所有必需参数正确调用时,我的Web服务(资源)方法返回JSON字符串化结果,但我不确定向调用者指示缺少必需参数的最佳方法是什么.
yeg*_*256 68
好问题.不幸的是(或者幸运的是)JAX-RS中没有任何机制可以强制使用任何参数.如果没有提供参数,它的值将是NULL
,您的资源应该相应地处理它.我建议用来WebApplicationException
通知你的用户:
@GET
@Path("/some-path")
public String read(@QueryParam("name") String name) {
if (name == null) {
throw new WebApplicationException(
Response.status(HttpURLConnection.HTTP_BAD_REQUEST)
.entity("name parameter is mandatory")
.build()
);
}
// continue with a normal flow
}
Run Code Online (Sandbox Code Playgroud)
Gio*_*tta 59
您可以使用javax.validation
注释通过使用注释强制参数是必需的@javax.validation.constraints.NotNull
.查看Jersey的示例和RESTeasy 的示例.
所以你的方法将变成:
@GET
@Path("/some-path")
public String read(@NotNull @QueryParam("name") String name) {
String something =
// implementation
return something;
}
Run Code Online (Sandbox Code Playgroud)
请注意,JAX-RS提供程序会将异常转换为某些错误代码.它通常可以通过注册您自己的实现来覆盖javax.ws.rs.ext.ExceptionMapper<javax.validation.ValidationException>
.
这提供了一种将强制参数转换为错误响应的集中方式,并且不需要代码重复.
Zer*_*ro3 17
我遇到了同样的问题,并决定我不想在我的REST代码中分散大量的样板空检查,所以这就是我决定做的事情:
对于1),我实现了以下注释:
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.
}
Run Code Online (Sandbox Code Playgroud)
......以及以下JAX-RS ContainerRequestFilter
来强制执行它:
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());
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要以与使用JAX-RS库ContainerRequestFilter
注册其他@Provider
类相同的方式注册.也许RESTEasy会自动为您完成.
对于2),我使用通用JAX-RS处理所有运行时异常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();
}
}
Run Code Online (Sandbox Code Playgroud)
和以前一样,记得用JAX-RS库注册该类.
归档时间: |
|
查看次数: |
80687 次 |
最近记录: |