使Jersey 2.x拒绝具有错误内容长度的请求的最佳方法?

艾迪·伯恩(Edy Bourne)

我需要使Jersey拒绝内容长度不正确的请求。我正在使用ContainerRequestFilter过滤器检查内容长度,如下所示:

public class ContentLengthRequiredRequestFilter implements ContainerRequestFilter {
    private static Logger LOG = LoggerFactory.getLogger(ContentLengthRequiredRequestFilter.class);


    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        if (requestContext.getMethod() == javax.ws.rs.HttpMethod.POST
                || requestContext.getMethod() == javax.ws.rs.HttpMethod.PUT) {
            int givenContentLength = requestContext.getLength();

            if (givenContentLength == -1) {
                // no content-length given, but it is is required for PUT and POST requests
        requestContext.abortWith(Response.status(Response.Status.LENGTH_REQUIRED).entity("No content-length provided.").build());

            } else {
                // now check if the given content-length is actually correct.
                // since I only have a reference to an entity stream, it seems to be that
                // reading the entire stream and then resetting it is not a good solution.

                // Should I be checking this somewhere else, perhaps somewhere the entity is already available or where I can get the total size of the body without causing the stream to be read twice? Or is there a better way to get the body size here?

            }

        }

    }
}

如您在代码块注释中看到的,我是否应该在其他地方进行检查,也许是该实体已经可用的某个地方,还是可以在不导致两次读取流的情况下获取主体的总大小的地方?还是有更好的方法来获得身材?

谢谢!!

米哈尔·加伊多斯(Michal Gajdos)

如果您不想缓冲传入的实体(输入流),请看一下ReaderInterceptor接口。仅在传入请求包含实体(通常为POST,PUT)的情况下才调用此合同的实例。在拦截器中,您几乎可以对实体执行任何操作。一个简单的代码段(并非涵盖所有情况)如下所示:

public class MyInterceptor implements ReaderInterceptor {

    @Override
    public Object aroundReadFrom(final ReaderInterceptorContext context) throws IOException, WebApplicationException {
        final InputStream old = context.getInputStream();
        final String first = context.getHeaders().getFirst("Content-Length");
        final Long declared = first == null ? -1 : Long.valueOf(first);

        context.setInputStream(new InputStream() {

            private long length = 0;
            private int mark = 0;

            @Override
            public int read() throws IOException {
                final int read = old.read();
                readAndCheck(read != -1 ? 1 : 0);
                return read;
            }

            @Override
            public int read(final byte[] b) throws IOException {
                final int read = old.read(b);
                readAndCheck(read != -1 ? read : 0);
                return read;
            }

            @Override
            public int read(final byte[] b, final int off, final int len) throws IOException {
                final int read = old.read(b, off, len);
                readAndCheck(read != -1 ? read : 0);
                return read;
            }

            @Override
            public long skip(final long n) throws IOException {
                final long skip = old.skip(n);
                readAndCheck(skip != -1 ? skip : 0);
                return skip;
            }

            @Override
            public int available() throws IOException {
                return old.available();
            }

            @Override
            public void close() throws IOException {
                old.close();
            }

            @Override
            public synchronized void mark(final int readlimit) {
                mark += readlimit;
                old.mark(readlimit);
            }

            @Override
            public synchronized void reset() throws IOException {
                this.length = 0;
                readAndCheck(mark);
                old.reset();
            }

            @Override
            public boolean markSupported() {
                return old.markSupported();
            }

            private void readAndCheck(final long read) {
                this.length += read;

                if (this.length > declared) {
                    throw new WebApplicationException(
                            Response.status(Response.Status.LENGTH_REQUIRED)
                                    .entity("No content-length provided.")
                                    .build());
                }
            }
        });

        final Object entity = context.proceed();

        context.setInputStream(old);

        return entity;
    }
}

在上面的拦截器中,我设置了自己的输入流,该输入流对从原始输入流读取的字节数进行计数和检查。但是,此实现还取决于基础容器如何处理输入流(即,在读取输入流时是否还检查内容长度)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

自省Jersey资源模型Jersey 2.x

来自分类Dev

带有ResourceConfig的Swagger Core Jersey 2.X

来自分类Dev

带有Jersey 2 ClassNotFoundException的REST应用:com.sun.jersey.spi.container.servlet.ServletContainer

来自分类Dev

将 ClientFilter 从 Jersey 移动到 Jersey 2

来自分类Dev

无法使用Spring Boot和Jersey 2提供静态内容

来自分类Dev

JAXRS / Jersey 2-验证错误不会调用ExceptionMapper

来自分类Dev

如何调试Jersey 2.x Client Api

来自分类Dev

如何使用Jersey 2.x设置连接并读取超时?

来自分类Dev

Swagger是否也适用于Jersey 2.x?

来自分类Dev

在Weblogic 12.1.1上使用Jersey 2.x Web服务

来自分类Dev

Jersey 2.x,使用Pojo作为POST的参数

来自分类Dev

Jersey 2.x(2.6)所需的Maven依赖项

来自分类Dev

如何在jersey 2.x版本中配置CDI?

来自分类Dev

如何在Jersey 2.x中返回对象

来自分类Dev

Jersey 2.x @Context / Scala 中的依赖注入

来自分类常见问题

Jersey2 @BeanParam比其他方法慢得多

来自分类Dev

在Jersey 2中将主体注入资源方法

来自分类Dev

引导Jersey 2(使用Jetty)的正确方法是什么?

来自分类Dev

使用Jersey 2的REST API

来自分类Dev

使用Jersey 2上传文件

来自分类Dev

Jersey REST 404错误

来自分类Dev

Jersey REST扩展方法

来自分类Dev

带有属性的Jersey 2.x自定义注入注释

来自分类Dev

具有Jersey2.0或更高版本的Mule Jersey模块

来自分类Dev

如何从Jersey-2请求过滤器访问检票口会话?

来自分类Dev

Jersey 2 请求过滤器在此代码中不起作用

来自分类Dev

从Spring-Jersey 1.x迁移到2.x

来自分类Dev

警告:Jersey2.x客户端上的JAXP功能XMLConstants.FEATURE_SECURE_PROCESSING

来自分类Dev

获得Jersey 2.x POJO JSON支持以与Jetty一起使用

Related 相关文章

热门标签

归档