• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: WOFileUpload and 5.4
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WOFileUpload and 5.4


  • Subject: Re: WOFileUpload and 5.4
  • From: William Hatch <email@hidden>
  • Date: Thu, 30 Oct 2008 19:26:19 -0400

Thanks Jake, I'll try that. But, it's not working at all for me; either under tomcat or as a typical woa. The component has a data and filePath binding, inside a typical wo form; the enctype is properly set, submit button bound to a component action. On submit (the upload) the page refreshes, but it's as if the method is never called; log statements don't show up; nothing. I can understand the .war issue, due to the WOServletAdaptor, but then why wouldn't it work as a normal .woa either? (sorry for the typing out loud;-)

Bill



On Oct 30, 2008, at 5:49 PM, Jake MacMullin wrote:

There is a bug in WO 5.4 with how HTTP headers are handled when deployed in a servlet container. I reported this (5711936) and it has been marked as resolved in 'the latest seed release of Xcode 3.1, Developer preview 2. So perhaps this is the bug you are running in to. Here's how it manifested itself to me:

When WebObjects applications are deployed in servlet containers, the WebObjects application does not receive requests or generate responses directly. Instead, the WOServletAdaptor sits in between the WebObjects application and the servlet container. All requests and responses are sent to the servlet container, which then dispatches them to the WOServletAdaptor, which dispatches them to the underlying WebObjects application. Responses are handled in the same way, but in the opposite direction. A bug exists in how the WOServletAdaptor and the WOMessage and WORequest classes handle HTTP headers. It seems that WOMessage and WORequest expect all headers to be lower-case - and that the WOServletAdaptor does not make sure all headers are lower-case. This results in posts from a form whose enctype is "multipart/form-data" failing to update any of the variables bound to form fields. Steps to Reproduce: 1. Create a new WebObjects project 2. Modify the main component as follows: HTML: <wo:WOForm> <wo:WOTextField value = "[message]"></ wo:WOTextField> <wo:WOSubmitButton action = "[sayHello]"></ wo:WOSubmitButton> </wo:WOForm> <wo:WOForm enctype = "multipart/ form-data"> <wo:WOTextField value = "[message]"></wo:WOTextField> <wo:WOSubmitButton action = "[sayHello]"></wo:WOSubmitButton> </ wo:WOForm> <wo:WOString value = "[message]"></wo:WOString> Java: public String message; public Main(WOContext context) { super(context); } public WOComponent sayHello() { message = "hello, " + message + "!"; NSDictionary headers = this.context().request().headers(); for(int i=0;i<headers.allKeys().count();i++) { String header = (String) headers.allKeys().objectAtIndex(i); System.out.println(header + ": "); System.out.println(headers.valueForKey(header)); System .out.println(this.context().request().headerForKey(header)); } return(this); } 3. Build the application as both a .woa and a .war 4. Deploy the applications. Expected Results: Type something in the forms and click on sumbit. Both forms should behave in the same way and you should see "hello, " plus whatever you typed. The console should show all the headers with the values repeated. Actual Results: When a WebObjects application is deployed in a servlet container, the following rather strange situation occurs: When this is deployed as a .woa, it produces the following correct output: <snip> content-type: ( multipart/form-data; boundary=---- WebKitFormBoundaryZdrwLAre6TArzAid ) multipart/form-data; boundary=----WebKitFormBoundaryZdrwLAre6TArzAid </snip> But when it is run in a servlet container, it produces the following, obviously incorrect output: <snip> Content-Type: ( multipart/form-data; boundary=----WebKitFormBoundaryonU48QK5I46+pA1T ) null </snip> A problem exists because the valueForHeader() method in WOMessage assumes all headers are lower-case, so when WORequest attempts to determine if the request isMultipartFormData(), it does so by asking for the contentType() - which results in a call to valueForHeader(), which in turn calls the get() method of the underlying TreeMap of _httpHeaders, but mistakenly does so with a lower-case version of the key: (List)_httpHeaders.get(aKey.toString().toLowerCase()) The result of all of this is that if you specify the "enctype" of your form as "multipart/form-data" none of the bindings for your form will get values.

Whilst this is reported as fixed, I'm still using a work-around in my app (as I haven't upgraded it to a fixed version of WO yet) - so if this is the bug you're encountering, the work-around might help you too.


I wrote a subclass of WOServletAdaptor that converts all the header keys to lowercase before calling 'super'. You just need to include this class in your project and modify the web.xml that is created to reference your WOServletAdaptor subclass instead of the default one.

MyServletAdaptor.java:

package au.id.jmacmullin;

import java.io.IOException;

import javax.servlet.ServletException;

import com.webobjects.jspservlet.WOServletAdaptor;

public class MyServletAdaptor extends WOServletAdaptor {

public MyServletAdaptor() throws ServletException {
super();
}

// over-rides the default implementation to first convert all the header keys to lower-case, before calling super
public void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws IOException, javax.servlet.ServletException {
LowercaseHeaderKeysWrapper requestWrapper = new LowercaseHeaderKeysWrapper(request);
super.doPost(requestWrapper, response);
}

}



LowercaseHeaderKeysWrapper.java:

package au.id.jmacmullin;

import java.util.Enumeration;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class LowercaseHeaderKeysWrapper extends HttpServletRequestWrapper {

public LowercaseHeaderKeysWrapper(HttpServletRequest request) {
super(request);
}

public Enumeration getHeaderNames() {
Vector headerNames = new Vector();
Enumeration existingNames = super.getHeaderNames();
while(existingNames.hasMoreElements()) {
headerNames.add(((String) existingNames.nextElement()).toLowerCase());
}
return(headerNames.elements());
}

public Enumeration getHeaders(String name) {
Enumeration returnVals;

// try and find a header with the exact name
Enumeration existingHeaders = super.getHeaders(name);
if(existingHeaders!=null && existingHeaders.hasMoreElements()) {
returnVals = existingHeaders;
} else {

StringBuilder sb = new StringBuilder();

// try and find a header with different capitalisation
String[] words = name.split("-");
for(int i=0;i<words.length;i++) {
sb.append(words[i].substring(0, 1).toUpperCase());
sb.append(words[i].substring(1));
if(i<words.length-1) {
sb.append("-");
}
}
String camelCaseHeaderKey = sb.toString();

returnVals = super.getHeaders(camelCaseHeaderKey);
}

return(returnVals);
}
}


web.xml:

...
<!-- The WebObjects Servlet that interfaces between the Servlet container
world and the WebObjects world. -->
<servlet>
<servlet-name>MyServletAdaptor</servlet-name>
<servlet-class>au.id.jmacmullin.MyServletAdaptor</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
...


Hope this helps,

Jake

On 31/10/2008, at 8:11 AM, Chuck Hill wrote:


On Oct 30, 2008, at 12:30 PM, William Hatch wrote:

5.4.3, using a pretty recent Wonder build. Deployed under either tomcat or as regular .woa, development in Eclipse....

Nothing happens when I click "Upload".

Meaning no request to the server? A request to the server but no data sent? Data is sent but the component does not see it? Something else?



I came across a thread by Mike discussing the perils of not binding filePath along with data, and that's not the case here; both are bound, although filePath is completely not used. This same exact component worked fine in 5.3. I also came across some other scary posts regarding encoding, and one regarding WOServeletAdaptor issues with WOFileUpload under 5.4 So what's the new new trick for getting this to fly again?


I don't recall having problems with uploads moving an app from 5.3.3 to 5.4.3.

Chuck


-- Chuck Hill Senior Consultant / VP Development

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems.
http://www.global-village.net/products/practical_webobjects







_______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden


_______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >WOFileUpload and 5.4 (From: William Hatch <email@hidden>)
 >Re: WOFileUpload and 5.4 (From: Chuck Hill <email@hidden>)
 >Re: WOFileUpload and 5.4 (From: Jake MacMullin <email@hidden>)

  • Prev by Date: Re: Charting question
  • Next by Date: Re: WOFileUpload and 5.4
  • Previous by thread: Re: WOFileUpload and 5.4
  • Next by thread: Re: WOFileUpload and 5.4
  • Index(es):
    • Date
    • Thread