【问题标题】:Parsing a Content-Type header in Java without validating the charset在 Java 中解析 Content-Type 标头而不验证字符集
【发布时间】:2020-04-01 21:24:55
【问题描述】:

给定一个 HTTP 标头,例如:

Content-Type: text/plain; charset=something

我想使用完全符合 RFC 的解析来提取 MIME 类型和字符集,但不“验证”字符集。通过验证,我的意思是我不想使用 Java 的内部字符集机制,以防 Java 不知道字符集(但可能对其他应用程序仍然有意义)。以下代码不起作用,因为它执行此验证:

import org.apache.http.entity.ContentType;

String header = "text/plain; charset=something";

ContentType contentType = ContentType.parse(header);
Charset contentTypeCharset = contentType.getCharset();

System.out.println(contentType.getMimeType());
System.out.println(contentTypeCharset == null ? null : contentTypeCharset.toString());

这会抛出java.nio.charset.UnsupportedCharsetException: something

【问题讨论】:

    标签: java mime-types


    【解决方案1】:

    或者,仍然可以使用Apache's parse 并捕获UnsupportedCharsetException 以使用getCharsetName() 提取名称

    import org.apache.http.entity.ContentType;
    
    String header = "text/plain; charset=something";
    
    String charsetName;
    String mimeType;
    
    try {
      ContentType contentType = ContentType.parse(header); // here exception may be thrown
       mimeType = contentType.getMimeType();
       Charset charset = contentType.getCharset();
       charsetName = charset != null ? charset.name() : null;
    } catch( UnsupportedCharsetException e) {
        charsetName = e.getCharsetName(); // extract unsupported charsetName
        mimeType = header.substring(0, header.indexOf(';')); // in case of exception, mimeType needs to be parsed separately
    }
    

    缺点是mimeType也需要在UnsupportedCharsetException的情况下进行不同的提取。

    【讨论】:

    • 我将header.substring(...) 部分视为标题“手动解析”的一种形式。如果有人这样做,那还不如手动提取字符集。在最初的问题中,我想使用经过验证的、经过测试的库来做到这一点,而不是重新发明轮子。
    • 解决方案是使用 标准库 及其顶级函数覆盖标题 Content-Type 的常见用例。回退到手动解析会捕获(罕见的)异常。
    【解决方案2】:

    要进行解析,可以使用较低级别的解析类:

    import org.apache.http.HeaderElement;
    import org.apache.http.NameValuePair;
    import org.apache.http.message.BasicHeaderValueParser;
    
    String header = "text/plain; charset=something";
    
    HeaderElement headerElement = BasicHeaderValueParser.parseHeaderElement(header, null);
    String mimeType = headerElement.getName();
    String charset = null;
    for (NameValuePair param : headerElement.getParameters()) {
        if (param.getName().equalsIgnoreCase("charset")) {
            String s = param.getValue();
            if (!StringUtils.isBlank(s)) {
                charset = s;
            }
            break;
        }
    }
    
    System.out.println(mimeType);
    System.out.println(charset);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 2012-10-06
      • 2015-11-26
      • 1970-01-01
      • 2011-12-19
      • 2023-01-26
      • 2011-12-04
      • 1970-01-01
      相关资源
      最近更新 更多