2009-12-27 2 views
1

Мое веб-приложение разработано с помощью Struts2, и до недавнего времени он работал нормально. Внезапно один из модулей начал работать неправильно.Почтовые параметры становятся нулевыми (случайными)

Неисправный модуль - это страница «Обновить данные о студентах». На этой странице есть много полей, таких как «schoolName», «degreeName» и т. Д.

School 1: <input name="schoolName"> 

School 2: <input name="schoolName"> 

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

Как упоминалось ранее, страница работала отлично до недавнего времени. Теперь один/многие из значений «schoolName», «degreeName» и т. Д. Принимаются как «» (EMPTY STRING) на стороне сервера.

Для отладки я использовал firebug и удаленную отладку в eclipse. Я считаю, что пост-параметры правильны на стороне клиента. Например, во время одного из представлений пост-параметры были ниже (я заметил их из 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-- 

Но на стороне сервера, запрос PARAMS был ниже:

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

«Техасский институт» был получен как «» (пустая строка) в данном конкретном случае. Это происходит не последовательно. Параметры, которые становятся NULL (или EMPTY STRING) кажутся случайными для меня - в одном случае параметр 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 

Этот вопрос кажется довольно странным для меня, и я не был в состоянии нуля-в на точную причину проблемы. Любая помощь в этом отношении будет высоко оценена. Заранее спасибо.

Спасибо, Raghuram

+1

Я предлагаю вам сначала устранить проблемы с сетевой передачей, захватив трафик на сервере с помощью Wireshark, чтобы убедиться, что вы получаете все данные в адаптере.Если данные выглядят ОК, то вам, вероятно, придется загрузить источник Struts2 и отладить в перехватчики, чтобы посмотреть, что происходит. Вопрос: Есть ли лишняя пустая строка после 'XXXX School'? –

+0

>>> Вопрос: Есть ли лишняя пустая строка после школы XXXX? К сожалению, нет. Нет лишней пустой строки. –

ответ

1

обновление.

Моя форма отправляет многопользовательский запрос (необходим, поскольку загрузка файла включена в форме). Я решил записать данные, которые поступают на сервер. Я модифицировал RequestDumperFilter.java для регистрации данных многостраничного сообщения. После того, как я добавил этот фильтр, проблема с потере параметров, похоже, прекратилась (0 потеря из 150 представлений формы). Я удалил фильтр и смог снова воспроизвести проблему.

Спасибо, Рагурама

/* 
* 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

Что об этом TOMCAT ошибке: https://issues.apache.org/bugzilla/show_bug.cgi?id=37794

Если HTTP/1.1 клиент POST с передачей кодированием: фрагментированный в сервлет, семьи getParameter() и Методы getQueryString() не могут получить корректный результат , не возвращая ничего. Напротив, чтение до конца файла на входном потоке сервлетов дает правильный результат.

Исправление составляет 6.0.21.

Смежные вопросы