`
jimmee
  • 浏览: 540031 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

tomcat参数编码处理过程

    博客分类:
  • J2SE
阅读更多
1. org.apache.coyote.http11.Http11Processor.process
处理请求的数据
 
2. org.apache.coyote.http11.InternalInputBuffer.parseRequestLine()
 
  // 例如:127.0.0.1:8080/test.jsp?a=%E4%B8%AD%E5%9B%BD
        request.unparsedURI().setBytes(buf, start, end - start);
        if (questionPos >= 0) {
         // queryString: a=%E4%B8%AD%E5%9B%BD
            request.queryString().setBytes(buf, questionPos + 1,
                                         end - questionPos - 1);
            // requestURI: 127.0.0.1:8080/test.jsp
            request.requestURI().setBytes(buf, start, questionPos - start);
        } else {
            request.requestURI().setBytes(buf, start, end - start);
        }
 
3. org.apache.catalina.connector.CoyoteAdapter
 
public void service(org.apache.coyote.Request req,
                     org.apache.coyote.Response res)
 
 /**
     * Service method.
     */
    public void service(org.apache.coyote.Request req,
                     org.apache.coyote.Response res)
        throws Exception {
 
        Request request = (Request) req.getNote(ADAPTER_NOTES);
        Response response = (Response) res.getNote(ADAPTER_NOTES);
 
        if (request == null) {
 
            // Create objects
            request = (Request) connector.createRequest();
            request.setCoyoteRequest(req);
            response = (Response) connector.createResponse();
            response.setCoyoteResponse(res);
 
            // Link objects
            request.setResponse(response);
            response.setRequest(request);
 
            // Set as notes
            req.setNote(ADAPTER_NOTES, request);
            res.setNote(ADAPTER_NOTES, response);
 
            // Set query string encoding // 设置了queryString的编码
            req.getParameters().setQueryStringEncoding
                (connector.getURIEncoding());
 
        }
 
        if (connector.getXpoweredBy()) {
            response.addHeader("X-Powered-By", POWERED_BY);
        }
 
    /**
     * Parse additional request parameters.
     */
    protected boolean postParseRequest(org.apache.coyote.Request req,
                                       Request request,
                             org.apache.coyote.Response res,
                                       Response response)
 
3. 解析参数
 
org.apache.catalina.connector.Request.parseParameters
 
 /**
     * Parse request parameters.
     */
    protected void parseParameters() {
 
        parametersParsed = true;
 
        Parameters parameters = coyoteRequest.getParameters();
 
        // getCharacterEncoding() may have been overridden to search for
        // hidden form field containing request encoding
        String enc = getCharacterEncoding();
 
        boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
        if (enc != null) {
         // 设置参数的编码
            parameters.setEncoding(enc);
            if (useBodyEncodingForURI) { // 如果此选项设置了的话, 设置queryStr的编码
                parameters.setQueryStringEncoding(enc);
            }
        } else {
            parameters.setEncoding
                (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
            if (useBodyEncodingForURI) {
                parameters.setQueryStringEncoding
                    (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
            }
        }
       
        // 解析query str
        parameters.handleQueryParameters();
 
        if (usingInputStream || usingReader)
            return;
       
        // 不是post, 直接返回
        if (!getMethod().equalsIgnoreCase("POST"))
            return;
 
        String contentType = getContentType();
        if (contentType == null)
            contentType = "";
        int semicolon = contentType.indexOf(';');
        if (semicolon >= 0) {
            contentType = contentType.substring(0, semicolon).trim();
        } else {
            contentType = contentType.trim();
        }
       
        // 当不是表单数据时, 返回
        if (!("application/x-www-form-urlencoded".equals(contentType)))
            return;
       
        // 是表单数据, 读取解析
        int len = getContentLength();
 
        if (len > 0) {
            int maxPostSize = connector.getMaxPostSize();
            if ((maxPostSize > 0) && (len > maxPostSize)) {
                if (context.getLogger().isDebugEnabled()) {
                    context.getLogger().debug(
                            sm.getString("coyoteRequest.postTooLarge"));
                }
                return;
            }
            byte[] formData = null;
            if (len < CACHED_POST_LEN) {
                if (postData == null)
                    postData = new byte[CACHED_POST_LEN];
                formData = postData;
            } else {
                formData = new byte[len];
            }
            try {
                if (readPostBody(formData, len) != len) {
                    return;
                }
            } catch (IOException e) {
                // Client disconnect
                if (context.getLogger().isDebugEnabled()) {
                    context.getLogger().debug(
                            sm.getString("coyoteRequest.parseParameters"), e);
                }
                return;
            }
            parameters.processParameters(formData, 0, len);
        } else if ("chunked".equalsIgnoreCase(
                coyoteRequest.getHeader("transfer-encoding"))) {
            byte[] formData = null;
            try {
                formData = readChunkedPostBody();
            } catch (IOException e) {
                // Client disconnect
                if (context.getLogger().isDebugEnabled()) {
                    context.getLogger().debug(
                            sm.getString("coyoteRequest.parseParameters"), e);
                }
                return;
            }
            if (formData != null) {
                parameters.processParameters(formData, 0, formData.length);
            }
        }
 
    }
 
// 使用querystr的encoding
 public void processParameters( MessageBytes data, String encoding ) {
        if( data==null || data.isNull() || data.getLength() <= 0 ) return;
 
        if( data.getType() == MessageBytes.T_BYTES ) {
            ByteChunk bc=data.getByteChunk();
            processParameters( bc.getBytes(), bc.getOffset(),
                               bc.getLength(), encoding);
        } else {
            if (data.getType()!= MessageBytes.T_CHARS )
                data.toChars();
            CharChunk cc=data.getCharChunk();
            processParameters( cc.getChars(), cc.getOffset(),
                               cc.getLength());
        }
    }
 
小结:
1. 所有参数tomcat都会先做url decode(这很正常, 标准情况下, 都要做url编码, 可同时保证特殊字符的正确传送, 不管get传参还是post传参)
字符 特殊字符的含义 URL编码 
# 用来标志特定的文档位置 %23 
% 对特殊字符进行编码 %25 
& 分隔不同的变量值对 %26 
+ 在变量值中表示空格 %2B 
\ 表示目录路径 %2F 
= 用来连接键和值 %3D 
? 表示查询字符串的开始 %3F
2. 做url编码时, 肯定有指定的字符集(这里假定为utf-8), 如果后端的处理字符集与此字符集不同, 一般来说, 就有乱码
针对get方式的参数,  有两种方式, 可以正确处理
(1) tomcat的服务器配置URIEncoding="UTF-8"
(2) tomcat的服务器配置useBodyEncodingForURI="true", 读取参数之前, 设置
 request.setCharacterEncoding("utf-8");
针对post方式的参数, 只要设置如下即可:
 request.setCharacterEncoding("utf-8");
 
分享到:
评论

相关推荐

    tomcat字符编码总结

    - **URIEncoding**: 在`server.xml`配置文件中设置,用于处理URL中的参数编码。 - **Web应用的编码**: 可以通过`web.xml`中的过滤器设置或在JSP页面中直接指定。 - **系统环境编码**: 影响Tomcat的内部处理,默认...

    tomcat编码问题

    要解决这个问题,我们需要理解Tomcat处理字符编码的过程,并采取相应的配置调整。 首先,Tomcat默认的字符集可能并不包含GBK,GBK是中国大陆广泛使用的汉字编码标准,它包含了更多的中文字符。因此,当请求参数或...

    tomcat日志乱码处理方法总结

    2. **Tomcat启动参数设置错误**:Tomcat通过一系列启动脚本进行初始化,其中涉及到字符编码的配置。 3. **Tomcat内部日志配置不当**:默认情况下,Tomcat使用的是Apache JULI(Java Util Logging Implementation)...

    修改Tomcat运行时jvm编码问题

    例如,项目源代码、数据库、文件系统以及网络通信等环节均采用UTF-8编码,但在某些环境下(如Windows),JVM的默认编码可能是GBK,这就会造成数据在处理过程中出现乱码。 解决方法: 1. **Linux环境**: 在Linux...

    关于\"form表单提交数据编码方式和tomcat接受数据解码方式的思考\"一文的纠错

    在深入理解Tomcat处理编码的机制时,还需要关注Tomcat内部对Servlet请求对象`HttpServletRequest`的处理。`getParameter()`和`getParameterValues()`方法默认使用ISO-8859-1,但可以通过覆盖`ServletRequest`的`set...

    tomcat 下catalina.out 日志乱码问题处理

    `-Dfile.encoding=UTF-8`指示JVM使用UTF-8编码处理文件,包括日志输出;`-Dsun.jnu.encoding=UTF-8`则是设置JNI(Java Native Interface)使用的编码,它会影响JVM与操作系统之间的字符编码转换。 执行这个修改后,...

    Tomcat的jsp编译参数

    总结来说,理解和配置Tomcat的JSP编译参数是优化Java Web应用程序性能、提升开发效率和确保错误处理的关键。通过对`web.xml`的适当调整,你可以定制JSP的编译行为,使其更好地适应项目的需求。同时,了解这些参数也...

    tomcat request.getParameter 乱码

    - `URIEncoding="UTF-8"`:用于指定URL中的参数编码方式为UTF-8。 - `useBodyEncodingForURI="true"`:表示在处理URI中的参数时也使用指定的编码方式。 ##### 2. 其他补充措施 除了修改`server.xml`文件外,还可以...

    tomcat显示出现中文乱码问题.docx

    首先,我们需要理解Tomcat的字符编码处理流程。Tomcat在接收HTTP请求时,会根据`Connector`元素的`useBodyEncodingForURI`属性和`URIEncoding`属性来确定请求参数的编码方式。默认情况下,`useBodyEncodingForURI`是...

    编码问题处理

    ### 编码问题处理 在IT领域中,尤其是在Java Web应用开发过程中,字符编码的问题是开发者经常遇到的一个挑战。...对于Java开发者而言,掌握字符编码的基础知识以及如何在开发过程中正确处理编码问题是非常重要的。

    tomcat7打补丁版.rar

    6. **SQL注入**:如果Tomcat与数据库交互时未正确处理用户输入,可能会引发SQL注入。补丁会确保所有用户输入都被安全地转义或参数化。 应用这个补丁的过程通常包括以下几个步骤: 1. **下载补丁**:从官方Apache ...

    MyEclipse+Tomcat_+_Servlet开发

    配置MyEclipse环境可能包括设置编码方式、Tomcat服务器参数等。在【Window】|【Preferences】中可以进行这些设置。对于Tomcat服务器,需在【Servers】中启用并配置其路径。部署项目时,通过MyEclipse的部署工具将...

    深入剖析Tomcat .rar

    二、Tomcat的工作流程 1. **启动**:Tomcat启动时,会读取配置文件(如server.xml和web.xml),解析并加载所有必要的组件和服务。 2. **请求处理**:当HTTP请求到达时,Connector捕获请求,解析请求头和实体,然后...

    apache-tomcat-7.0.108(UTF8).zip

    在使用过程中,你可以根据实际需求配置Tomcat的服务器端口、JVM参数、SSL支持等,以适应不同的部署环境和性能要求。同时,定期检查和更新Tomcat的安全补丁和版本升级,以确保系统的稳定性和安全性。

    使用Tomcat或Nginx搭建视频服务器

    整篇文章通过具体的实践案例,详细说明了如何在不同的操作系统上使用Tomcat和Nginx搭建视频服务器,并通过ffmpeg工具处理视频文件以支持HLS协议的视频点播服务。这是一个涉及Web服务器配置、音视频编码和网络安全等...

    模拟tomcat的工作原理

    在模拟Tomcat的过程中,了解并实现这些步骤可以帮助我们更好地理解Web服务器的工作流程,特别是Java的多线程模型在其中的应用。同时,标签"java tomcat"提示我们需要关注的是与Java和Tomcat相关的技术,例如Servlet...

    tomcat与servlet乱码解决办法

    在Web开发过程中,经常遇到的一个问题就是字符编码的问题,特别是在处理中文字符时,如果编码设置不当,很容易出现乱码的情况。本文主要围绕Tomcat服务器下JSP页面以及Servlet中的乱码问题进行深入分析,并提供相应...

    Java内嵌式Tomcat-TomcatDemo

    然而,在现代开发环境中,为了简化部署流程和提高灵活性,开发者常选择将Tomcat“内嵌”到Java应用中,即"内嵌式Tomcat"。 内嵌式Tomcat的优势在于,它允许开发者直接在Java应用程序内部启动和管理Tomcat服务器,...

    tomcat GET请求与POST请求

    1. **URL编码**:对于GET请求,参数值必须进行URL编码,以确保它们可以安全地包含在URL中。POST请求的参数值通常不需要编码,但为了兼容性和安全性,最好还是进行编码。 2. **幂等性**:设计API时,应尽量使GET请求...

Global site tag (gtag.js) - Google Analytics