在 ContainerRequestContext entityStream 中读取和设置相同数据后,@FormParameter 数据变为 null

@FormParameter data becomes null after reading and setting the same data in ContainerRequestContext entityStream

我已经实现了过滤器,我已经调用了 ContainerRequestContext 的 getEntityStream 并使用 setEntitystream 设置了准确的值。如果我使用这个过滤器,那么@FormParameter 数据变为空,如果我不使用过滤器,那么一切都会好起来的(因为我没有调用 getEntityStream),我必须使用过滤器来捕获请求数据。

注意:我从 MultivaluedMap formParams 而不是从 @FormParameter 获取表单参数。

环境:- 高枕无忧 API 使用 Jboss Wildfly 8 服务器。

            @Provider
            @Priority(Priorities.LOGGING)
            public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter{

                final static Logger log = Logger.getLogger(CustomLoggingFilter.class);

                @Context
                private ResourceInfo resourceInfo;

                @Override
                public void filter(ContainerRequestContext requestContext)
                        throws IOException {
                    MDC.put("start-time", String.valueOf(System.currentTimeMillis()));

                    String entityParameter = readEntityStream(requestContext);

                    log.info("Entity Parameter :"+entityParameter);
                }

                private String readEntityStream(ContainerRequestContext requestContext){
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    final InputStream inputStream = requestContext.getEntityStream();
                    final StringBuilder builder = new StringBuilder();

                    int read=0;
                    final byte[] data = new byte[4096];
                    try {
                        while ((read = inputStream.read(data)) != -1) {
                            outStream.write(data, 0, read);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    byte[] requestEntity = outStream.toByteArray();
                    if (requestEntity.length == 0) {
                        builder.append("");
                    } else {
                        builder.append(new String(requestEntity));
                    }
                    requestContext.setEntityStream(new ByteArrayInputStream(requestEntity) );
                        return builder.toString();
                    }
                    return null;
                }
            }          



    class customResource
    {

    //// This code is not working
    @POST
    @Path("voiceCallBack")
    @ApiOperation(value = "Voice call back from Twilio")
    public void voiceCallback(@FormParam("param") String param)
    {
        log.info("param:" + param);
    }

    // This code is working

    @POST
    @Path("voiceCallBackMap")
    @ApiOperation(value = "Voice call back from Twilio")
    public void voiceCallbackMap(final MultivaluedMap<String, String> formParams)
    {
        String param = formParams.getFirst("param");
    }
}

请给我建议解决方案并提前致谢。

我在 运行 期间发现实体流实例(来自 http 请求)的类型为 org.apache.catalina.connector.CoyoteInputStream(我正在使用 jboss-as-7.1.1.Final).但是我们正在使用 java.io.ByteArrayInputStream 的实例设置实体流。所以Resteasy无法绑定单独的formparmeters。

有两种解决方案,您可以使用其中的任何一种:

  1. 使用这种方法How to read JBoss Resteasy's servlet request twice while maintaing @FormParam binding?
  2. 像这样获取表单参数:
     @POST
     @Path("voiceCallBackMap")
     @ApiOperation(value = "Voice call back from Twilio")
     public void voiceCallbackMap(final MultivaluedMap<String, String> formParams)

     {
         String param = formParams.getFirst("param");
     }