getting form data as a populated javabean

I am aware of the use of the @FormParam annotation on method parameters, but I think you should be able to have objects completely populated from the form contents.

Assume class "User" is defined like so:

class User {
 public User() { }
 String name;
 String password;
  // getters and setters go here

}

Now say your client will be submitting something like this:

POST /users HTTP/1.1
Content-type: application/x-www-form-urlencoded
.. other headers ..

name=jeff&password=qweqqeqwe


Now you should be able to declare a resource method like this:

@PATH("/users")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(user) {
   // code goes about its business with a fully populated user object

}

This is how I would expect things to work, from having dealt with numerous web application frameworks.

The exceptions I get when I try something like this suggest to me that it's trying to parse the form data as JAXB, which obviously isn't right.

Is there some magical way to do this that I just haven't found yet? Short of writing your own MessageBodyReader to deal with the raw form data. I've tried that, but which seems like more than should be required since Jersey already knows how to parse forms.

I feel like I must be missing something obvious.

Just for reference, here is the code I gimped up to make this sorta work. Yes, deprecated HttpUtils, I know. I didn't really feel like digging to find the non-deprecated proper replacement.

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;

import java.util.*;

import org.apache.commons.beanutils.*;

import javax.servlet.http.HttpUtils;


@Provider
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public class FormReader implements MessageBodyReader {

	public boolean isReadable(Class arg0, Type arg1, Annotation[] arg2) {
		return true;
	}

	public Object readFrom(Class arg0, Type arg1, Annotation[] arg2,
			MediaType arg3, MultivaluedMap arg4, final InputStream arg5)
			throws IOException, WebApplicationException {
		
		try {
		
			Object bean = arg0.newInstance();
	
			Object contentLength = arg4.getFirst("Content-Length");
			
			int length = Integer.parseInt( String.valueOf(contentLength));

			javax.servlet.ServletInputStream sin =
				new javax.servlet.ServletInputStream() {
					@Override
					public int read() throws IOException {
						return arg5.read();
					}
			};
			
			Map badIdea = HttpUtils.parsePostData(length, sin);

			BeanUtils.populate(bean, badIdea);
			
			return bean;
		
		} catch(InstantiationException e) {
			throw new WebApplicationException(e);
		} catch (IllegalAccessException e) {
			throw new WebApplicationException(e);
		} catch (InvocationTargetException e) {
			throw new WebApplicationException(e);
		}
		
	}
	
	

}

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Sign up or Log in to add a comment or watch this page.


The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

Copyright 1994-2009 Sun Microsystems, Inc.
Powered by Atlassian Confluence
Sun Guidelines on Public Discourse Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact