如何在Java Jersey REST服务中强制使用queryparams?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Java Jersey REST服务中强制使用queryparams?相关的知识,希望对你有一定的参考价值。

我有一个REST API,可以接受3个查询参数。在没有任何一个查询参数的情况下调用查询时,API将执行并返回结果。我们如何强制使用queryparams?如何添加验证以检查是否存在所有参数?另外,请告诉我最好的方法。

答案

在一个非常简单的层面上,你可以注入HttpServletRequest并检查自己:

@GET
public Response example(@Context HttpServletRequest request, 
                        @QueryParam("name") String name) {
  if (null == request.getParameter("name")) {
    ResponseBuilder builder = Response.status(404);
    return builder.build();
  }
  // Do something with name
}

或者你可以使用AOP实现更精细的东西。 Here's是一篇关于更多选项的博客文章。

另一答案

jersey不提供开箱即用的强制参数检查功能。但是你可以做一些像实现自己的注释来实现它。以下是注释代码:

@Target(value = ElementType.METHOD)  
 @Retention(value = RetentionPolicy.RUNTIME)  
 public @interface Required {  
    String[] value();  
 }  

你还需要一个过滤器,下面是代码:

 public class RequiredParamResourceFilterFactory implements ResourceFilterFactory {  
   @Context  
   private transient HttpServletRequest servletRequest;  
   private class RequiredParamFilter implements ResourceFilter, ContainerRequestFilter {  
     private final String[] requiredParams;  
     protected List<String> parametersValueMissing;  
     private RequiredParamFilter(String[] requiredParams) {  
       this.requiredParams = requiredParams;  
     }  
     @Override  
     public ContainerRequest filter(ContainerRequest containerRequest) {  
       boolean missingMandatoryParameter = false;  
       List<String> missingParameters = new ArrayList<String>();  
       List<String> requiredParametersValueMissing = new ArrayList<String>();  
       List<String> URLParameters = getURLParameters(containerRequest.getQueryParameters());  
       List<String> methodRequiredParameters = Arrays.asList(requiredParams);  
       if (methodRequiredParameters != null) {  
         for (String methodRequiredParam : methodRequiredParameters) {  
           if (URLParameters == null) {  
             missingMandatoryParameter = true; //we will check this flag before returning result set to caller  
             missingParameters.add(methodRequiredParam);  
           } else if (!URLParameters.contains(methodRequiredParam)) {  
             missingMandatoryParameter = true; //we will check this flag before returning result set to caller  
             missingParameters.add(methodRequiredParam);  
             //Add to required parameters value missing List, only if the parameter is mandatory and value is not provided  
             // in the URL  
           } else if (parametersValueMissing.contains(methodRequiredParam)) {  
             requiredParametersValueMissing.add(methodRequiredParam);  
           }  
         }  
         if (missingMandatoryParameter && requiredParametersValueMissing.size() > 0) {  
           throw new YourCustomException("Missing Parameters = " + StringHelper.ArrayToString(missingParameters) +  
               "
Parameter value missing for " + StringHelper.ArrayToString(requiredParametersValueMissing));  
         } else if (missingMandatoryParameter) {  
           throw new YourCustomException("Missing Parameters = " + StringHelper.ArrayToString(missingParameters), MisbarErrorCode.VALIDATION_WRONG_INPUT_ERROR, "Customers");  
         } else if (requiredParametersValueMissing != null &&  
             requiredParametersValueMissing.size() > 0) {  
           throw new YourCustomException("Parameter value missing for " + StringHelper.ArrayToString(requiredParametersValueMissing));  
         }  
       }  
       return containerRequest;  
     }  
     @Override  
     public ContainerRequestFilter getRequestFilter() {  
       return this;  
     }  
     @Override  
     public ContainerResponseFilter getResponseFilter() {  
       return null;  
     }  
     /**  
      * To fetch the parameters sent to webservice call, these will be used to find if required parameter  
      * are present or not  
      *  
      * @param queryParams the queryparams sent  
      * @return all the parameters sent in URL  
      */  
     private List<String> getURLParameters(MultivaluedMap<String,String> queryParams) {  
       parametersValueMissing = new ArrayList<String>();  
       List<String> arr = new ArrayList<String>();  
       for(String key:queryParams.keySet())  
       {  
         arr.add(key);  
         if(queryParams.get(key)==null)  
           parametersValueMissing.add(key);  
       }  
       if(!arr.isEmpty())  
         return arr;  
       return null;  
     }  
   }  
   @Override  
   public List<ResourceFilter> create(AbstractMethod am) {  
     Required required = am.getAnnotation(Required.class);  
     if(required!=null)  
     {  
       return Collections.<ResourceFilter>singletonList(new RequiredParamFilter(required.value()));  
     }  
     return null;  
   }  
 }  

下面的示例显示了如何使用此注释,因此在下面的webservice中; file_id和count是必需参数:

@GET  
   @Produces(MediaType.APPLICATION_JSON+";charset=utf-8")  
   @Cacheable(isCacheable = true)  
   @Path("posts/clusters")  
   @Required({"file_id","count"})  
   @Timed  
   public Response getClusters(  
       @QueryParam("file_id") Integer fileId,  
       @QueryParam("count") Integer count,  
       @DefaultValue("-1")@QueryParam("start_time") Long startTime){  
 ;  
 }  

如果webservice调用中未提供必需参数,则会收到如下所示的错误,并提及缺少的参数名称:

{
message: "Missing Parameters = file_id, count",
errorCode: "600"
}

希望这能解决你的问题。

以上是关于如何在Java Jersey REST服务中强制使用queryparams?的主要内容,如果未能解决你的问题,请参考以下文章

Jersey REST 服务上的用户身份验证

如何在java REST API中用GZip和Jersey压缩相应

Jersey+Spring 实现rest 接口 服务调用

带有 XML 参数的 REST 服务操作上的 HTTP 错误 415 不受支持的媒体类型(Jersey + Jetty)

如何使用Jersey在REST Web服务中为服务类指定多个包名称

笔记:创建Jersey REST 服务,基于Maven