博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tomcat的servlet读取请求参数
阅读量:7122 次
发布时间:2019-06-28

本文共 12834 字,大约阅读时间需要 42 分钟。

读取url上的queryString

org/apache/tomcat/embed/tomcat-embed-core/8.0.33/tomcat-embed-core-8.0.33-sources.jar!/org/apache/catalina/core/ApplicationDispatcher.java

private void doDispatch(ServletRequest request, ServletResponse response) throws ServletException, IOException private void doForward(ServletRequest request, ServletResponse response)        throws ServletException, IOExceptionprivate void doInclude(ServletRequest request, ServletResponse response)            throws ServletException, IOException

这里看doDispatch

private void doDispatch(ServletRequest request, ServletResponse response)            throws ServletException, IOException {        // Set up to handle the specified request and response        State state = new State(request, response, false);        // Create a wrapped response to use for this request        wrapResponse(state);        ApplicationHttpRequest wrequest =            (ApplicationHttpRequest) wrapRequest(state);        if (queryString != null) {            wrequest.setQueryParams(queryString);        }        wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR,                DispatcherType.ASYNC);        wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR,                getCombinedPath());        wrequest.setContextPath(context.getPath());        wrequest.setRequestURI(requestURI);        wrequest.setServletPath(servletPath);        wrequest.setPathInfo(pathInfo);        if (queryString != null) {            wrequest.setQueryString(queryString);            wrequest.setQueryParams(queryString);        }        invoke(state.outerRequest, state.outerResponse, state);    }

ApplicationDispatcher.doDispatch-->ApplicationHttpRequest.setQueryString -->ApplicationHttpRequest.parseParameters -->mergeParameters

private void mergeParameters() {        if ((queryParamString == null) || (queryParamString.length() < 1))            return;        // Parse the query string from the dispatch target        Parameters paramParser = new Parameters();        MessageBytes queryMB = MessageBytes.newInstance();        queryMB.setString(queryParamString);        String encoding = getCharacterEncoding();        // No need to process null value, as ISO-8859-1 is the default encoding        // in MessageBytes.toBytes().        if (encoding != null) {            try {                queryMB.setCharset(B2CConverter.getCharset(encoding));            } catch (UnsupportedEncodingException ignored) {                // Fall-back to ISO-8859-1            }        }        paramParser.setQuery(queryMB);        paramParser.setQueryStringEncoding(encoding);        paramParser.handleQueryParameters();        // Insert the additional parameters from the dispatch target        Enumeration
dispParamNames = paramParser.getParameterNames(); while (dispParamNames.hasMoreElements()) { String dispParamName = dispParamNames.nextElement(); String[] dispParamValues = paramParser.getParameterValues(dispParamName); String[] originalValues = parameters.get(dispParamName); if (originalValues == null) { parameters.put(dispParamName, dispParamValues); continue; } parameters.put(dispParamName, mergeValues(dispParamValues, originalValues)); } }

读取post及body的参数

org/apache/tomcat/embed/tomcat-embed-core/8.0.33/tomcat-embed-core-8.0.33-sources.jar!/org/apache/catalina/connector/Request.java

/**     * Parse request parameters.     */    protected void parseParameters() {        parametersParsed = true;        Parameters parameters = coyoteRequest.getParameters();        boolean success = false;        try {            // Set this every time in case limit has been changed via JMX            parameters.setLimit(getConnector().getMaxParameterCount());            // 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) {                    parameters.setQueryStringEncoding(enc);                }            } else {                parameters.setEncoding                    (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);                if (useBodyEncodingForURI) {                    parameters.setQueryStringEncoding                        (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);                }            }            parameters.handleQueryParameters();            if (usingInputStream || usingReader) {                success = true;                return;            }            if( !getConnector().isParseBodyMethod(getMethod()) ) {                success = true;                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 ("multipart/form-data".equals(contentType)) {                parseParts(false);                success = true;                return;            }            if (!("application/x-www-form-urlencoded".equals(contentType))) {                success = true;                return;            }            int len = getContentLength();            if (len > 0) {                int maxPostSize = connector.getMaxPostSize();                if ((maxPostSize >= 0) && (len > maxPostSize)) {                    Context context = getContext();                    if (context != null && context.getLogger().isDebugEnabled()) {                        context.getLogger().debug(                                sm.getString("coyoteRequest.postTooLarge"));                    }                    checkSwallowInput();                    parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);                    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) {                        parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE);                        return;                    }                } catch (IOException e) {                    // Client disconnect                    Context context = getContext();                    if (context != null && context.getLogger().isDebugEnabled()) {                        context.getLogger().debug(                                sm.getString("coyoteRequest.parseParameters"),                                e);                    }                    parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);                    return;                }                parameters.processParameters(formData, 0, len);            } else if ("chunked".equalsIgnoreCase(                    coyoteRequest.getHeader("transfer-encoding"))) {                byte[] formData = null;                try {                    formData = readChunkedPostBody();                } catch (IllegalStateException ise) {                    // chunkedPostTooLarge error                    parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);                    Context context = getContext();                    if (context != null && context.getLogger().isDebugEnabled()) {                        context.getLogger().debug(                                sm.getString("coyoteRequest.parseParameters"),                                ise);                    }                    return;                } catch (IOException e) {                    // Client disconnect                    parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);                    Context context = getContext();                    if (context != null && context.getLogger().isDebugEnabled()) {                        context.getLogger().debug(                                sm.getString("coyoteRequest.parseParameters"),                                e);                    }                    return;                }                if (formData != null) {                    parameters.processParameters(formData, 0, formData.length);                }            }            success = true;        } finally {            if (!success) {                parameters.setParseFailedReason(FailReason.UNKNOWN);            }        }    }

readPostBody

/**     * Read post body in an array.     */    protected int readPostBody(byte body[], int len)        throws IOException {        int offset = 0;        do {            int inputLen = getStream().read(body, offset, len - offset);            if (inputLen <= 0) {                return offset;            }            offset += inputLen;        } while ((len - offset) > 0);        return len;    }

readChunkedPostBody

/**     * Read chunked post body.     */    protected byte[] readChunkedPostBody() throws IOException {        ByteChunk body = new ByteChunk();        byte[] buffer = new byte[CACHED_POST_LEN];        int len = 0;        while (len > -1) {            len = getStream().read(buffer, 0, CACHED_POST_LEN);            if (connector.getMaxPostSize() >= 0 &&                    (body.getLength() + len) > connector.getMaxPostSize()) {                // Too much data                checkSwallowInput();                throw new IllegalStateException(                        sm.getString("coyoteRequest.chunkedPostTooLarge"));            }            if (len > 0) {                body.append(buffer, 0, len);            }        }        if (body.getLength() == 0) {            return null;        }        if (body.getLength() < body.getBuffer().length) {            int length = body.getLength();            byte[] result = new byte[length];            System.arraycopy(body.getBuffer(), 0, result, 0, length);            return result;        }        return body.getBuffer();    }

parameters.processParameters(formData, 0, formData.length);

-->addParameter

public void addParameter( String key, String value )            throws IllegalStateException {        if( key==null ) {            return;        }        parameterCount ++;        if (limit > -1 && parameterCount > limit) {            // Processing this parameter will push us over the limit. ISE is            // what Request.parseParts() uses for requests that are too big            setParseFailedReason(FailReason.TOO_MANY_PARAMETERS);            throw new IllegalStateException(sm.getString(                    "parameters.maxCountFail", Integer.valueOf(limit)));        }        ArrayList
values = paramHashValues.get(key); if (values == null) { values = new ArrayList<>(1); paramHashValues.put(key, values); } values.add(value); }

然后再这里调用

public Enumeration
getParameterNames() { handleQueryParameters(); return Collections.enumeration(paramHashValues.keySet()); }

而Request的getParameterNames则委托Parameters的getParameterNames

public Enumeration
getParameterNames() { if (!parametersParsed) { parseParameters(); } return coyoteRequest.getParameters().getParameterNames(); }

最后,有个统一的merge过程,见上头的mergeParameters。

usingReader以及usingInputStream标志位

getReader

@Override    public BufferedReader getReader() throws IOException {        if (usingInputStream) {            throw new IllegalStateException                (sm.getString("coyoteRequest.getReader.ise"));        }        usingReader = true;        inputBuffer.checkConverter();        if (reader == null) {            reader = new CoyoteReader(inputBuffer);        }        return reader;    }

getInputStream

@Override    public ServletInputStream getInputStream() throws IOException {        if (usingReader) {            throw new IllegalStateException                (sm.getString("coyoteRequest.getInputStream.ise"));        }        usingInputStream = true;        if (inputStream == null) {            inputStream = new CoyoteInputStream(inputBuffer);        }        return inputStream;    }

Servlet Request的 getInputStream() getReader() getParameter(),在读取post方法的参数时,使用了任意一个,再调用其他两个方法是读取不到参数的。getParameter单线程上可重复使用,多线程的话可能会有异常,因为该方法依赖parametersParsed,这个boolean的参数不是原子的。

docs

转载地址:http://tksel.baihongyu.com/

你可能感兴趣的文章
RE管理器root explorer基础操作教程
查看>>
TFS首次安装与配置,极其注意事项<个人备用>
查看>>
重温Android——调节屏幕亮度
查看>>
设计模式六大原则(1):单一职责原则
查看>>
当机器人具有自我知觉,并能自适应环境,真的不可怕吗?
查看>>
selenium环境搭建,浏览器驱动安装
查看>>
C# 递归函数详细介绍及使用方法
查看>>
web api 开发之 filter
查看>>
第十章:内核同步方法
查看>>
SQL中创建外键约束
查看>>
【网络编程】网络协议简析
查看>>
PHP 中Cookie和Session的使用
查看>>
Struts2注解
查看>>
Vue.js 判断对象属性是否存,不存在添加
查看>>
第十一周作业
查看>>
2-设置文件类型扩展名
查看>>
[python基础]关于中文编码和解码那点事儿
查看>>
MySQL集群架构-DRBD+headbeat +lvs+keepalived
查看>>
[LUOGU] P2886 [USACO07NOV]牛继电器Cow Relays
查看>>
31. Next Permutation
查看>>