Hay un problema con los subprocesos asincrónicos que utilizan Solicitud

descripción general

Si requestlo pasamos a un hilo asíncrono, es posible que no consigamos los parámetros, y provocará solicitudes posteriores, y habrá problemas al usar este hilo.
La razón es que requestlos objetos se reutilizan.

Análisis de código fuente

1. Obtener parámetros

Veamos primero un método muy importante: getParameterla primera vez que se llama al método, los parámetros se analizarán y luego ya no se analizarán.

package org.apache.catalina.connector;

public class Request implements HttpServletRequest {
    
    
    /**
     * 请求参数解析标志(默认为false)
     */
    protected boolean parametersParsed = false;

    @Override
    public String getParameter(String name) {
    
    
    
        if (!parametersParsed) {
    
     //判断是否已经解析参数,如果没解析,则进行解析。
            parseParameters();
        }

        return coyoteRequest.getParameters().getParameter(name);

    }
}

inserte la descripción de la imagen aquí

2. Análisis de parámetros

Es este método el que realmente analiza los parámetros parameters.handleQueryParameters();.

    /**
     * 解析请求参数
     */
    protected void parseParameters() {
    
    

        parametersParsed = true;

        Parameters parameters = coyoteRequest.getParameters();
        boolean success = false;
        try {
    
    
        	......
            parameters.handleQueryParameters(); //真正解析参数的方法
            ......
            success = true;
        } finally {
    
    
            if (!success) {
    
    
                parameters.setParseFailedReason(FailReason.UNKNOWN);
            }
        }

    }

3. Procese la cadena de consulta como un parámetro

    /**
     * 将查询字符串处理为参数
     */
    public void handleQueryParameters() {
    
    
        if (didQueryParameters) {
    
     //判断是否已经处理过了
            return;
        }

        didQueryParameters = true;

        ......
        processParameters(decodedQuery, queryStringCharset);
    }

inserte la descripción de la imagen aquí

4. Agregar parámetros a paramHashValues

Cuando el programa se ejecuta aquí, los parámetros se agregarán a paramHashValueseste map, y cuando se obtienen los parámetros, se mapobtienen directamente de este.

private final Map<String,ArrayList<String>> paramHashValues =
            new LinkedHashMap<>();
            
    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<String> values = paramHashValues.get(key);
        if (values == null) {
    
    
            values = new ArrayList<>(1);
            paramHashValues.put(key, values);
        }
        values.add(value);
    }

5. Solicitud de liberación

El código de la solicitud final irá a este lugar, y los parámetros de la solicitud se borrarán aquí, y luego se reutilizará para la próxima solicitud.
El método se llama reciclar, lo que indica que está reciclando, en el que los parámetros de almacenamiento del mapa se borrarán y didQueryParameters se establecerá en falso nuevamente.

    public void recycle() {
    
    
        parameterCount = 0;
        paramHashValues.clear();
        didQueryParameters = false;
        charset = DEFAULT_BODY_CHARSET;
        decodedQuery.recycle();
        parseFailedReason = null;
    }

Hay indicaciones de que la solicitud se recicla en tomcat.

Referencia:
https://blog.csdn.net/JavaMonsterr/article/details/126033884

Supongo que te gusta

Origin blog.csdn.net/qq_25775675/article/details/126973115
Recomendado
Clasificación