【问题标题】:Catching duplicate request headers with HttpServletRequest使用 HttpServletRequest 捕获重复的请求标头
【发布时间】:2012-09-29 11:08:24
【问题描述】:

我遇到了HttpServlet 请求的问题。我有一个用于检索请求标头的应用程序。如果应用程序发现重复的标头名称,它应该抛出一个错误。然而,经过一番谷歌搜索,我发现HttpServletRequest 忽略了重复的标题名称,并继续获取它遇到的第一个标题名称。我能做些什么来捕获那些重复的请求标头吗?

我使用 Tomcat 6 作为应用程序容器。

这是代码:

int headerChecker=0;
for(Enumeration<String>names = request.getHeaderNames(); names.hasMoreElements(); ) {
    String name = (String)names.nextElement();
    if(name.equalsIgnoreCase("abcd")){
        headerChecker++; // add 1 to headerChecker if abcd header is encountered
    }
    for(Enumeration<String>values = request.getHeaders(name); values.hasMoreElements(); ) {
        String value=(String)values.nextElement();
        System.out.println("name: "+name+"\tvalue: "+value);
        }
    }

    if(headerChecker! = 1){
        logger.error("abcd is duplicated, returning HTTP 404");
    } else {
        //...proceed with application
    }
}

这是日志:

name:  host   value: localhost:8080  name: user-agent value:
CocoaRestClient/8 CFNetwork/520.4.3 Darwin/11.4.2 (x86_64)
(MacBookPro9%2C2)  name: content-length value: 23  name: accept   value:

**name: abcd  value: 1234556**  name: accept-language value: en-us  name: accept-encoding value: gzip, deflate  name: content-type    value:
application/x-www-form-urlencoded  name: connection value: keep-alive

这是测试截图:

编辑:这里是 servlet

public class HeaderServlet extends HttpServlet
{
public void doPost(HttpServletRequest req, HttpServletResponse res)
{
    doGet(req, res);
}

public void doGet(HttpServletRequest req, HttpServletResponse res)
{
int xmsisdnChecker = 0;
String value = "";  
for(Enumeration<String> names = req.getHeaderNames();names.hasMoreElements();){
    String name = (String) names.nextElement(); 
    Enumeration<String> values = req.getHeaders(name);
    if(values != null)
    {
        while(values.hasMoreElements()) {
            if(name.equalsIgnoreCase("abcd"))
            {
                xmsisdnChecker++;
                System.out.println("ee: " + xmsisdnChecker) ;
            }

            value = (String) values.nextElement();

            System.out.println("header name: " + name + "\theader value: " + value);
        }

    }   
  }
}   
}

【问题讨论】:

    标签: java servlets tomcat6


    【解决方案1】:

    不,HttpServletRequest 不会忽略重复的标题 - 它会收集它们。

    来自HttpServletRequest.getHeaders(String)

    将指定请求头的所有值作为字符串对象的枚举返回。

    客户端可以将某些标头(例如 Accept-Language)作为多个标头发送,每个标头具有不同的值,而不是将标头作为逗号分隔列表发送。

    听起来您只需要调用getHeaderNames() 来检索所有存在的标头,然后使用每个名称调用getHeaders(String),并查看返回的枚举是否包含多个条目。

    【讨论】:

    • 感谢您的输入,但是,我已经在我的代码中这样做了,但仍然没有捕获那些重复的标题名称。另外,我的请求标头实际上是一个自定义标头名称。
    • 它不应该有任何区别,它是一个自定义标题名称 - 它应该可以正常工作。请显示您使用的代码,并说明您使用的是哪个 servlet 容器。
    • @user1708189:确实不应该有太多代码 - 您应该能够轻松地编辑您的问题以包含代码。我实际上建议将它提取到一个 没有别的 的 servlet 中,这样您就可以发布完整的 servlet,我们可以尝试复制问题。
    • 好的,先生。编辑我的问题。
    【解决方案2】:

    你的增量是在错误的地方。 HttpServletRequest 将所有值收集在一起,并将它们显示为单个标头的多个值。您应该在循环值的内部循环内测试并增加headerChecker。外层循环只会遇到 'abcd' 一次。

    【讨论】:

    • 我尝试将检查器放在内部循环中,但仍然只检测到一个标题。
    • @user1708189 那么你只得到了那个标题的一个值,所以没有重复。
    • 我有 2 个名称相同但值不同的标头,但只检测到一个,因此我的检查器只增加一次,但应该增加两次,因为存在同名的 2 个标头名称。
    • @user1708189 该循环要么只打印出一个值,要么将计数器增加两次,或者没有如上所示编码。在第一种和第二种情况下,您没有问题。
    • 不,EJP 先生,计数器只增加了一次。此外,第一个代码是在实际应用程序上,第二个代码是 John Skeet 爵士建议的测试 servlet,如您所建议的,在内循环中带有 headerChecker。
    猜你喜欢
    • 1970-01-01
    • 2011-02-21
    • 2021-07-08
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多