如何修复 Jersey POST 请求参数警告?

发布于 2024-08-17 06:44:42 字数 477 浏览 2 评论 0原文

我正在使用 Jersey 构建一个非常简单的 REST API,并且我的日志文件中收到了一条我不确定的警告。

警告:servlet POST 请求 统一资源定位符 http://myserver/mycontext/myapi/users/12345?action=delete , 包含表单参数 请求正文,但请求正文有 已被 servlet 或 servlet 过滤器访问请求 参数。仅资源方法 使用@FormParam将起到作用 预期的。资源消耗方法 通过其他方式的请求主体将 没有按预期工作。

我的 web 应用程序仅定义了 Jersey servlet,映射到 /myapi/*

我怎样才能停止这些警告?

I'm building a very simple REST API using Jersey, and I've got a warning in my log files that I'm not sure about.

WARNING: A servlet POST request, to
the URI
http://myserver/mycontext/myapi/users/12345?action=delete,
contains form parameters in the
request body but the request body has
been consumed by the servlet or a
servlet filter accessing the request
parameters. Only resource methods
using @FormParam will work as
expected. Resource methods consuming
the request body by other means will
not work as expected.

My webapp only has the Jersey servlet defined, mapped to /myapi/*

How can I stop these warnings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

情定在深秋 2024-08-24 06:44:42

对我来说,警告是针对 POST application/x-www-form-urlencoded 显示的。我正在使用 Spring Boot,它有一个 HiddenHttpMethodFilter,它在执行其他操作之前执行 getParameter...所以我最终做了这个令人讨厌的覆盖:

@Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new HiddenHttpMethodFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                    FilterChain filterChain) throws ServletException, IOException {
                if ("POST".equals(request.getMethod())
                        && request.getContentType().equals(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
                    filterChain.doFilter(request, response);
                } else {
                    super.doFilterInternal(request, response, filterChain);
                }
            }
        };
    }

For me the warning was showing for POST application/x-www-form-urlencoded. And I am using Spring Boot which has an HiddenHttpMethodFilter that does a getParameter before anything else... So I ended up doing this nasty override:

@Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new HiddenHttpMethodFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                    FilterChain filterChain) throws ServletException, IOException {
                if ("POST".equals(request.getMethod())
                        && request.getContentType().equals(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
                    filterChain.doFilter(request, response);
                } else {
                    super.doFilterInternal(request, response, filterChain);
                }
            }
        };
    }
爱冒险 2024-08-24 06:44:42

此消息旨在警告开发人员请求实体正文已被消耗,因此任何其他读取消息正文的尝试都将失败。

忽略该消息或将其从日志中过滤掉是安全的:

java.util.logging.Logger jerseyLogger =
        java.util.logging.Logger.getLogger(WebComponent.class.getName());
jerseyLogger.setFilter(new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
        boolean isLoggable = true;
        if (record.getMessage().contains("Only resource methods using @FormParam")) {
            isLoggable = false;
        }
        return isLoggable;
    }
});

This message is meant to warn developers about the fact that the request entity body has been consumed, thus any other attempts to read the message body will fail.

It is safe to ignore the message or filter it out from the logs:

java.util.logging.Logger jerseyLogger =
        java.util.logging.Logger.getLogger(WebComponent.class.getName());
jerseyLogger.setFilter(new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
        boolean isLoggable = true;
        if (record.getMessage().contains("Only resource methods using @FormParam")) {
            isLoggable = false;
        }
        return isLoggable;
    }
});
嘦怹 2024-08-24 06:44:42

以下主题描述了您收到的警告。听起来好像您可能在 web.xml 中定义了一个过滤器,该过滤器在 Jersey 之前处理请求。

The following thread describes the warning you are receiving. It sounds as though you might have a filter defined in your web.xml that is processing the request before Jersey does.

葮薆情 2024-08-24 06:44:42

最后通过确保我的请求标头中有 Content-Type: application/json (显然,在客户端)摆脱了这个问题

Finally got rid of this by making sure I had Content-Type: application/json in my request headers (obviously, on the client side)

撩人痒 2024-08-24 06:44:42

我刚刚将 JQuery 中的 ajax 函数设置为 contentType: "application/x-www-form-urlencoded; charset=UTF-8" 因为使用先前的解决方案(没有 Jersey)我有一些编码问题。当我删除该消息时,该消息消失了,一切正常。

I just had my ajax-function in JQuery set to contentType: "application/x-www-form-urlencoded; charset=UTF-8" because with a prior solution (without Jersey) I had some encoding problems. When I removed that the message was gone and everything worked fine.

澉约 2024-08-24 06:44:42

正确的。
所以我一直在遭受这个问题的困扰,并且我一直在尝试以不同的方式解决它,但我不想更改我的 web.xml 设置,只是因为如果我使用 Postman 测试我的应用程序,它会完美地工作,但是当它与 web 应用程序集成时,它会因上述问题而失败(对 URI {MY_URI} 的 servlet 请求在请求正文中包含表单参数,但请求正文已被 servlet 或访问的 servlet 过滤器消耗请求参数。只有使用 @FormParam 的资源方法才能按预期工作。通过其他方式使用请求正文的资源方法将无法按预期工作。

因此,正如 @clijk 提到的,您只需将标头设置为:

"Content-Type":"application/json"
"charset":"UTF-8"

瞧,警告消失了。

谢谢

Right.
So I've been suffering this issue, and I've been trying to solve it on different ways, but I did't want to change my web.xml settings, just because if I was testing my application with Postman it worked perfect, but when it was being integrated with the webapp it fails with the mentioned issue (A servlet request to the URI {MY_URI} contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.)

So as @clijk mentioned, you only have to set your headers as:

"Content-Type":"application/json"
"charset":"UTF-8"

and voilá, the warning it's gone.

Thanks

花海 2024-08-24 06:44:42

此警告是 WebComponent 唯一记录的内容,因此只需在 logback.xml 中或在配置了日志记录的任何位置将日志记录设置为 ERROR 级别或关闭该组件的日志记录即可。您不需要编写自定义过滤器来忽略此特定消息,因为没有从此组件记录其他消息。

org.glassfish.jersey.servlet.WebComponent 版本 2.14 中的源代码片段:

        if(!form.asMap().isEmpty()) {
            containerRequest.setProperty("jersey.config.server.representation.decoded.form", form);
            if(LOGGER.isLoggable(Level.WARNING)) {
                LOGGER.log(Level.WARNING, LocalizationMessages.FORM_PARAM_CONSUMED(containerRequest.getRequestUri()));
            }
        }

用于此警告消息的本地化消息是:

form.param.consumed=A servlet request to the URI {0} contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

在 logback.xml 中关闭 WebComponent 的日志记录,如下所示:

<logger name="org.glassfish.jersey.servlet.WebComponent" level="OFF" additivity="false"/>

This warning is the only thing the WebComponent logs, so just turn logging up to ERROR level or turn off logging for this component in your logback.xml or wherever you have logging configured. You don't need to write a custom filter to ignore this specific message since there are no other messages logged from this component.

Source code snippet from org.glassfish.jersey.servlet.WebComponent version 2.14:

        if(!form.asMap().isEmpty()) {
            containerRequest.setProperty("jersey.config.server.representation.decoded.form", form);
            if(LOGGER.isLoggable(Level.WARNING)) {
                LOGGER.log(Level.WARNING, LocalizationMessages.FORM_PARAM_CONSUMED(containerRequest.getRequestUri()));
            }
        }

The localized message that is used for this warning message is:

form.param.consumed=A servlet request to the URI {0} contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

Turn logging off for the WebComponent in your logback.xml like so:

<logger name="org.glassfish.jersey.servlet.WebComponent" level="OFF" additivity="false"/>
断肠人 2024-08-24 06:44:42

就我而言,当我在方法中将对象日期更改为字符串时,我修复了此错误。

错误:

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") Date date) throws Exception {

已修复

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") String date) throws Exception {

In my case I've fixed this error when I've changed the Object Date to String in the method.

Error:

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") Date date) throws Exception {

Fixed

@POST
@Path("/myPath")
@Produces(MediaType.APPLICATION_JSON)
public List<MyObject> myMethod(@FormParam("StartDate") String date) throws Exception {
娇纵 2024-08-24 06:44:42

将其放入您的资源签名中。或者在您的项目中找到这个字符串,如果使用了 @PUT 或 @POST,那么有人已经使用了这个字符串。这应该有帮助

import javax.ws.rs.Consumes;

@Consumes(MediaType.APPLICATION_JSON)

Put this to your resource signature. Or find this string in your project someone already use this if @PUT or @POST is used. This should help

import javax.ws.rs.Consumes;

@Consumes(MediaType.APPLICATION_JSON)
獨角戲 2024-08-24 06:44:42

这个问题似乎已经在2.38版本中修复了
#5208

This problem seem has been fixed in version 2.38
#5208

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文