tomcat源码阅读之request(一)

    周末没啥事儿,打开很早之前下载的tomcat 7.52源码,随意打开几个以前没有阅读过的类走马观花式的看了看。在看HttpServletRequest tomcat实现的时候发现一个关于setCharacterEncoding字符集的挺有意思的小细节,记录一下。

    平时大家如果在遇到乱码的时候,都会使用request.setCharacterEncoding这个方法来设置一下代码编码格式。今天在看这个类代码的时候,发现如下细节:

    setCharacterEncoding方法的部分代码如下,就是验证一下字符集是否有效,并将新的字符集参数设置到解码器需要的地方:

    public void setCharacterEncoding(String enc)
        throws UnsupportedEncodingException {
        if (usingReader) {
            return;
        }
        // Ensure that the specified encoding is valid
        byte buffer[] = new byte[1];
        buffer[0] = (byte) 'a';
        // Confirm that the encoding name is valid
        B2CConverter.getCharset(enc);
        // Save the validated encoding
        coyoteRequest.setCharacterEncoding(enc);
    }

    而getParameter方法最终的代码如下:

    public String getParameter(String name ) {
        handleQueryParameters();
        ArrayList<String> values = paramHashValues.get(name);
        if (values != null) {
            if(values.size() == 0) {
                return "";
            }
            return values.get(0);
        } else {
            return null;
        }
    }
    public void handleQueryParameters() {
        if( didQueryParameters ) {
            return;
        }
        didQueryParameters=true;
        if( queryMB==null || queryMB.isNull() ) {
            return;
        }
        if(log.isDebugEnabled()) {
            log.debug("Decoding query " + decodedQuery + " " +
                    queryStringEncoding);
        }
        try {
            decodedQuery.duplicate( queryMB );
        } catch (IOException e) {
            // Can't happen, as decodedQuery can't overflow
            e.printStackTrace();
        }
        processParameters( decodedQuery, queryStringEncoding );
    }

     从上面的两段代码可以看到:request.getParameter这个方法的实现是在该方法第一次调用的时候会去解析当前的表单数据,解析数据的时候会用到上面提到的setCharacterEncoding方法设置的encoding,也就是说如果先调用getParameter在去setCharacterEncoding的话,应当是不起作用的。之前虽然没没有这样做过,通过这个小细节突然想到了这个问题,记录下来,希望有朋友遇到这种错误的情况时有所帮助。