帖子参数变为空(随机)

时间:2009-12-27 14:41:35

标签: web-applications struts2

我的Web应用程序是使用Struts2开发的,直到最近才运行良好。突然其中一个模块开始出现故障。

故障模块是“更新学生详细信息”页面。这个页面有很多字段,如'schoolName','degreeName'等。

School 1: <input name="schoolName">

School 2: <input name="schoolName">

..... 
School n: <input name="schoolName">

如前所述,该页面直到最近一直运行良好。现在,'schoolName','degreeName'等的一个/多个值在服务器端被接收为“”(EMPTY STRING)。

为了调试,我在eclipse中使用了firebug和远程调试。我发现后置参数在客户端是正确的。例如,在其中一份提交文件中,后参数如下(我从firebug中注意到它们)。

Content-Type: multipart/form-data; boundary=---------------------------2921238217421 
Content-Length: 48893 

<OTHER_PARAMETERS> <!--Truncated for clarity --> 

-----------------------------2921238217421 
Content-Disposition: form-data; name="schoolName" 

ABC Institute 
-----------------------------2921238217421 
Content-Disposition: form-data; name="schoolName" 

Test School 
-----------------------------2921238217421 
Content-Disposition: form-data; name="schoolName" 

XYZ 
-----------------------------2921238217421 
Content-Disposition: form-data; name="schoolName" 

Texas Institute 
-----------------------------2921238217421 
Content-Disposition: form-data; name="schoolName" 

XXXX School 

-----------------------------2921238217421-- 

但在服务器端,请求参数如下:

schoolName=[ABC Institute, Test School, XYZ, , XXXX School], 
在这种特殊情况下,“德克萨斯研究所”被收到“”(EMPTY STRING)。这不是一贯发生的。即成为NULL(或空字符串)似乎随机给我的参数 - 一个实例中,参数schoolName [3]成为空如上所示,参数schoolName [2]另一个提交等有时中变得无效,没有一个参数无效。

以下是操作定义中的拦截器列表。

List of interceptors: 
----------------------
FileUploadInterceptor
org.apache.struts2.interceptor.FileUploadInterceptor
ServletConfigInterceptor
org.apache.struts2.interceptor.ServletConfigInterceptor  StaticParametersInterceptor
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor
ParametersInterceptor
com.opensymphony.xwork2.interceptor.ParametersInterceptor
MyCustomInterceptor
com.xxxx.yyyy.interceptors.GetLoggedOnUserInterceptor

这个问题对我来说似乎很奇怪,而且我无法对问题的确切原因进行归零。在这方面的任何帮助将受到高度赞赏。提前致谢。

谢谢, 拉古拉姆

2 个答案:

答案 0 :(得分:1)

更新。

我的表单发送一个多部分请求(需要在表单上启用文件上传)。我决定记录来到服务器的后期数据。我修改了RequestDumperFilter.java来记录多部分的帖子数据。添加此过滤器后,参数丢失问题似乎已停止(150个表单中的0个丢失)。我删除了过滤器,并能够再次重现该问题。

谢谢, 拉古拉姆

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package filters;


import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.xml.ws.RequestWrapper;

import com.oreilly.servlet.multipart.BufferedServletInputStream;



/**
 * Example filter that dumps interesting state information about a request
 * to the associated servlet context log file, before allowing the servlet
 * to process the request in the usual way.  This can be installed as needed
 * to assist in debugging problems.
 *
 * @author Craig McClanahan
 * @version $Revision: 500674 $ $Date: 2007-01-28 00:15:00 +0100 (dim., 28 janv. 2007) $
 */

public final class RequestDumperFilter implements Filter {


    // ----------------------------------------------------- Instance Variables


    /**
     * The filter configuration object we are associated with.  If this value
     * is null, this filter instance is not currently configured.
     */
    private FilterConfig filterConfig = null;

    // --------------------------------------------------------- Public Methods


    /**
     * Take this filter out of service.
     */
    public void destroy() {

        this.filterConfig = null;

    }


    /**
     * Time the processing that is performed by all subsequent filters in the
     * current filter stack, including the ultimately invoked servlet.
     *
     * @param request The servlet request we are processing
     * @param result The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
    throws IOException, ServletException {

        if (filterConfig == null)
        return;

    // Render the generic servlet request properties
    StringWriter sw = new StringWriter();
    PrintWriter writer = new PrintWriter(sw);
    writer.println("Request Received at " +
               (new Timestamp(System.currentTimeMillis())));
    writer.println(" characterEncoding=" + request.getCharacterEncoding());
    writer.println("     contentLength=" + request.getContentLength());
    writer.println("       contentType=" + request.getContentType());
    writer.println("            locale=" + request.getLocale());
    writer.print("           locales=");
    Enumeration locales = request.getLocales();
    boolean first = true;
    while (locales.hasMoreElements()) {
        Locale locale = (Locale) locales.nextElement();
        if (first)
            first = false;
        else
            writer.print(", ");
        writer.print(locale.toString());
    }
    writer.println();
    Enumeration names = request.getParameterNames();
    while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        writer.print("         parameter=" + name + "=");
        String values[] = request.getParameterValues(name);
        for (int i = 0; i < values.length; i++) {
            if (i > 0)
            writer.print(", ");
        writer.print(values[i]);
        }
        writer.println();
    }
    writer.println("          protocol=" + request.getProtocol());
    writer.println("        remoteAddr=" + request.getRemoteAddr());
    writer.println("        remoteHost=" + request.getRemoteHost());
    writer.println("            scheme=" + request.getScheme());
    writer.println("        serverName=" + request.getServerName());
    writer.println("        serverPort=" + request.getServerPort());
    writer.println("          isSecure=" + request.isSecure());

    // Render the HTTP servlet request properties
    if (request instanceof HttpServletRequest) {
        writer.println("---------------------------------------------");
        HttpServletRequest hrequest = (HttpServletRequest) request;
        writer.println("       contextPath=" + hrequest.getContextPath());
        Cookie cookies[] = hrequest.getCookies();
            if (cookies == null)
                cookies = new Cookie[0];
        for (int i = 0; i < cookies.length; i++) {
            writer.println("            cookie=" + cookies[i].getName() +
                   "=" + cookies[i].getValue());
        }
        names = hrequest.getHeaderNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
        String value = hrequest.getHeader(name);
            writer.println("            header=" + name + "=" + value);
        }
        writer.println("            method=" + hrequest.getMethod());
        writer.println("          pathInfo=" + hrequest.getPathInfo());
        writer.println("       queryString=" + hrequest.getQueryString());
        writer.println("        remoteUser=" + hrequest.getRemoteUser());
        writer.println("requestedSessionId=" +
               hrequest.getRequestedSessionId());
        writer.println("        requestURI=" + hrequest.getRequestURI());
        writer.println("       servletPath=" + hrequest.getServletPath());


        /*
        The following section is added by me to print the post data of a multipart request.
        */
        writer.println("=============================================");
        writer.println("POST-DATA:");
        writer.println("----------");
        String line;
        BufferedRequestWrapper bufferedRequest= new BufferedRequestWrapper(hrequest);
        //Here obtain InputStream to process POST data!
        InputStream is = bufferedRequest.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        while((line = br.readLine()) != null){
              writer.println(line);
        }
        writer.println("=============================================");
        // Log the resulting string
        writer.flush();
        filterConfig.getServletContext().log(sw.getBuffer().toString());
        // Pass control on to the next filter
        chain.doFilter(bufferedRequest, response);

    }
    else
    {
        writer.println("=============================================");

        // Log the resulting string
        writer.flush();
        filterConfig.getServletContext().log(sw.getBuffer().toString());

        // Pass control on to the next filter
            chain.doFilter(request, response);
    }
    }


    /**
     * Place this filter into service.
     *
     * @param filterConfig The filter configuration object
     */
    public void init(FilterConfig filterConfig) throws ServletException {

    this.filterConfig = filterConfig;

    }


    /**
     * Return a String representation of this object.
     */
    public String toString() {

    if (filterConfig == null)
        return ("RequestDumperFilter()");
    StringBuffer sb = new StringBuffer("RequestDumperFilter(");
    sb.append(filterConfig);
    sb.append(")");
    return (sb.toString());

    }

    public class BufferedRequestWrapper extends HttpServletRequestWrapper {

        ByteArrayInputStream bais;
        ByteArrayOutputStream baos;
        BufferedServletInputStream bsis;
        byte [] buffer; 

        public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
        super(req);
        // Read InputStream and store its content in a buffer.
        InputStream is = req.getInputStream();
        baos = new ByteArrayOutputStream();
        byte buf[] = new byte[1024];
        int letti;
        while ((letti=is.read(buf))>0) baos.write(buf,0,letti);
        buffer = baos.toByteArray();
        }

        public ServletInputStream getInputStream() {
        try {
        // Generate a new InputStream by stored buffer
        bais = new ByteArrayInputStream(buffer);
        // Istantiate a subclass of ServletInputStream
        // (Only ServletInputStream or subclasses of it are accepted by the servlet engine!)
        bsis = new BufferedServletInputStream(bais); 
        } 
        catch (Exception ex) {
        ex.printStackTrace();
        } 
        finally {
        return bsis;
        }
        }

        }

    /*
    Subclass of ServletInputStream needed by the servlet engine.
    All inputStream methods are wrapped and are delegated to 
    the ByteArrayInputStream (obtained as constructor parameter)!
    */
    public class BufferedServletInputStream extends ServletInputStream {

    ByteArrayInputStream bais;

    public BufferedServletInputStream(ByteArrayInputStream bais) {
    this.bais = bais;
    }

    public int available() {
    return bais.available();
    }

    public int read() {
    return bais.read();
    }

    public int read(byte[] buf,int off,int len) {
    return bais.read(buf,off,len);
    }

    }


}

答案 1 :(得分:0)

这个tomcat bug怎么样:https://issues.apache.org/bugzilla/show_bug.cgi?id=37794

当带有transfer-encoding的HTTP / 1.1客户端POST:chunked到servlet时, getParameter()系列和getQueryString()方法无法检索 通过什么都不返回正确的结相反,阅读直到文件结束 在servlets输入流上产生正确的结果。

修复程序在6.0.21中。