2009-12-27 4 views
1

Mon application Web est développée avec Struts2 et elle fonctionnait bien jusqu'à récemment. Tout à coup, un des modules a commencé à fonctionner mal.Les paramètres Post deviennent null (au hasard)

Le module de dysfonctionnement est la page «Mettre à jour les détails de l'élève». Cette page a beaucoup de champs comme 'schoolName', 'degreeName', etc.

School 1: <input name="schoolName"> 

School 2: <input name="schoolName"> 

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

Comme mentionné précédemment, la page fonctionnait parfaitement bien jusqu'à récemment. Maintenant, une/plusieurs des valeurs de 'schoolName', 'degreeName', etc. sont reçues en tant que "" (EMPTY STRING) du côté serveur. Pour le débogage, j'ai utilisé firebug et le débogage à distance dans eclipse. Je trouve que les post-paramètres sont corrects du côté client. Par exemple, au cours de l'une des soumissions, les post-paramètres étaient comme ci-dessous (je les ai noté de 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-- 

Mais sur le côté serveur, les params de demande étaient comme ci-dessous:

schoolName=[ABC Institute, Test School, XYZ, , XXXX School], 

"Institut Texas" a été reçu comme "" (STRING VIDES) dans ce cas particulier. Cela ne se produit pas systématiquement. Les paramètres qui deviennent NULL (ou EMPTY STRING) me semblent aléatoires - pendant une instance, le paramètre schoolName [3] devient nul comme illustré ci-dessus, le paramètre schoolName [2] devient nul pendant une autre soumission, etc. les paramètres sont annulés.

Voici la liste des intercepteurs dans la définition d'action.

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 

Ce problème semble plutôt bizarre pour moi et je n'ai pas été en mesure de zéro dans la cause exacte de la question. Toute aide à cet égard serait grandement appréciée. Merci d'avance.

Merci, Raghuram

+1

Je vous suggère d'abord d'éliminer les problèmes de transmission réseau en capturant le trafic sur le serveur en utilisant Wireshark pour vous assurer que vous recevez toutes les données à l'adaptateur.Si les données semblent correctes, vous devrez probablement charger la source Struts2 et déboguer dans les intercepteurs pour voir ce qui se passe. Une question: Est-ce que la ligne blanche supplémentaire après 'XXXX School' est vraiment là? –

+0

>>> Une question: Est-ce que la ligne blanche supplémentaire après XXXX School est vraiment là? Désolé, NON. Il n'y a pas de ligne vide supplémentaire. –

Répondre

1

Une mise à jour.

Mon formulaire envoie une requête en plusieurs parties (nécessaire puisque le téléchargement de fichier est activé sur le formulaire). J'ai décidé d'enregistrer les post-données qui arrivent sur le serveur. J'ai modifié RequestDumperFilter.java pour consigner les données de publication en plusieurs parties. Après avoir ajouté ce filtre, le problème de perte de paramètres semble avoir cessé (0 perte sur 150 soumissions de formulaire). J'ai retiré le filtre et j'ai pu reproduire le problème à nouveau.

Merci, Raghuram

/* 
* 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); 
    } 

    } 


} 
0

Qu'en est-ce bug tomcat: https://issues.apache.org/bugzilla/show_bug.cgi?id=37794

Lorsqu'un client HTTP/1.1 POST avec codage de transfert: morcelées à un servlet, la famille getParameter() et Les méthodes getQueryString() ne parviennent pas à récupérer le résultat correct en ne renvoyant rien. En revanche, la lecture jusqu'à la fin du fichier sur le flux d'entrée des servlets produit un résultat correct.

Le correctif est en 6.0.21.