栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Tomcat中自动检测URI编码

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Tomcat中自动检测URI编码

实现我的目标的复杂方法确实是编写我自己的

javax.servlet.Filter
并将其嵌入过滤器链中。该解决方案符合Tomcat Wiki-
字符编码问题中
提供的Apache
Tomcat建议。

更新(2010-07-31):
此过滤器的第一个版本解释了查询字符串本身,这是一个坏主意。

POST
与其他servlet过滤器(如URL重写)结合使用时,它不能正确处理请求,并且出现问题。该版本将包装最初提供的参数并重新编码。为了使其正常工作,
URIEncoding
(例如在Tomcat中)必须将其配置为
ISO-8859-1

package de.roland_illig.webapps.webapp1;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.nio.charset.CharsetDeprer;import java.nio.charset.CodingErrorAction;import java.nio.charset.IllegalCharsetNameException;import java.nio.charset.UnsupportedCharsetException;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Enumeration;import java.util.linkedHashMap;import java.util.List;import java.util.Map;import java.util.regex.Pattern;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.HttpServletResponse;public class EncodingFilter implements Filter {  private static final Pattern PAT_COMMA = Pattern.compile(",\s*");  private String inputEncodingParameterName = null;  private final List<Charset> encodings = new ArrayList<Charset>();  @Override  @SuppressWarnings("unchecked")  public void init(FilterConfig config) throws ServletException {    String encodingsStr = "UTF-8";    Enumeration<String> en = config.getInitParameterNames();    while (en.hasMoreElements()) {      final String name = en.nextElement();      final String value = config.getInitParameter(name);      if (name.equals("encodings")) {        encodingsStr = value;      } else if (name.equals("inputEncodingParameterName")) {        inputEncodingParameterName = value;      } else {        throw new IllegalArgumentException("Unknown parameter: " + name);      }    }    for (String encoding : PAT_COMMA.split(encodingsStr)) {      Charset charset = Charset.forName(encoding);      encodings.add(charset);    }  }  @SuppressWarnings("unchecked")  @Override  public void doFilter(ServletRequest sreq, ServletResponse sres, FilterChain fc) throws IOException, ServletException {    final HttpServletRequest req = (HttpServletRequest) sreq;    final HttpServletResponse res = (HttpServletResponse) sres;    final Map<String, String[]> params;    try {      params = Util.depreParameters(req.getParameterMap(), encodings, inputEncodingParameterName);    } catch (IOException e) {      res.sendError(400, e.getMessage());      return;    }    HttpServletRequest wrapper = new ParametersWrapper(req, params);    fc.doFilter(wrapper, res);  }  @Override  public void destroy() {    // nothing to do  }  static abstract class Util {    static CharsetDeprer strictDeprer(Charset cs) {      CharsetDeprer dec = cs.newDeprer();      dec.onMalformedInput(CodingErrorAction.REPORT);      dec.onUnmappableCharacter(CodingErrorAction.REPORT);      return dec;    }    static int[] toCodePoints(String str) {      final int len = str.length();      int[] prePoints = new int[len];      int i = 0, j = 0;      while (i < len) {        int cp = Character.prePointAt(str, i);        prePoints[j++] = cp;        i += Character.charCount(cp);      }      return j == len ? prePoints : Arrays.copyOf(prePoints, len);    }    public static String repre(String enpred, CharsetDeprer deprer) throws IOException {      byte[] bytes = new byte[enpred.length()];      int bytescount = 0;      for (int i = 0; i < enpred.length(); i++) {        char c = enpred.charAt(i);        if (!(c <= 'u00FF'))          throw new IOException("Invalid character: #" + (int) c);        bytes[bytescount++] = (byte) c;      }      CharBuffer cbuf = deprer.depre(ByteBuffer.wrap(bytes, 0, bytescount));      String result = cbuf.toString();      return result;    }    static String ensureDefinedUnipre(String s) throws IOException {      for (int cp : toCodePoints(s)) {        if (!Character.isDefined(cp))          throw new IOException("Undefined unipre pre point: " + cp);      }      return s;    }    static Map<String, String[]> depreParameters(Map<String, String[]> originalParams, List<Charset> charsets, String ieName) throws IOException {      Map<String, String[]> params = new linkedHashMap<String, String[]>();      Charset ie = null;      {        String[] values = originalParams.get(ieName);        if (values != null) {          for (String value : values) { if (!value.isEmpty() && value.indexOf('%') == -1) {   try {     if (ie != null)       throw new IOException("Duplicate value for input encoding parameter: " + ie + " and " + value + ".");     ie = Charset.forName(value);   } catch (IllegalCharsetNameException e) {     throw new IOException("Illegal input encoding name: " + value);   } catch (UnsupportedCharsetException e) {     throw new IOException("Unsupported input encoding: " + value);   } }          }        }      }      Charset[] css = (ie != null) ? new Charset[] { ie } : charsets.toArray(new Charset[charsets.size()]);      for (Charset charset : css) {        try {          params.clear();          CharsetDeprer deprer = strictDeprer(charset);          for (Map.Entry<String, String[]> entry : originalParams.entrySet()) { final String enpredName = entry.getKey(); final String name = ensureDefinedUnipre(Util.repre(enpredName, deprer)); for (final String enpredValue : entry.getValue()) {   final String value = ensureDefinedUnipre(Util.repre(enpredValue, deprer));   String[] oldValues = params.get(name);   String[] newValues = (oldValues == null) ? new String[1] : Arrays.copyOf(oldValues, oldValues.length + 1);   newValues[newValues.length - 1] = value;   params.put(name, newValues); }          }          return params;        } catch (IOException e) {          continue;        }      }      List<String> kvs = new ArrayList<String>();      for (Map.Entry<String, String[]> entry : originalParams.entrySet()) {        final String key = entry.getKey();        for (final String value : entry.getValue()) {          kvs.add(key + "=" + value);        }      }      throw new IOException("Could not depre the parameters: " + kvs.toString());    }  }  @SuppressWarnings("unchecked")  static class ParametersWrapper extends HttpServletRequestWrapper {    private final Map<String, String[]> params;    public ParametersWrapper(HttpServletRequest request, Map<String, String[]> params) {      super(request);      this.params = params;    }    @Override    public String getParameter(String name) {      String[] values = params.get(name);      return (values != null && values.length != 0) ? values[0] : null;    }    @Override    public Map getParameterMap() {      return Collections.unmodifiableMap(params);    }    @Override    public Enumeration getParameterNames() {      return Collections.enumeration(params.keySet());    }    @Override    public String[] getParameterValues(String name) {      return params.get(name);    }  }}

尽管代码的大小相当小,但是有些实现细节可能会出错,因此我希望Tomcat已经提供了类似的过滤器。

要激活此过滤器,我将以下内容添加到了我的

web.xml

<filter>  <filter-name>EncodingFilter</filter-name>  <filter-class>de.roland_illig.webapps.webapp1.EncodingFilter</filter-class>  <init-param>    <param-name>encodings</param-name>    <param-value>US-ASCII, UTF-8, EUC-KR, ISO-8859-15, ISO-8859-1</param-value>  </init-param>  <init-param>    <param-name>inputEncodingParameterName</param-name>    <param-value>ie</param-value>  </init-param></filter><filter-mapping>  <filter-name>EncodingFilter</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/409937.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号