I have a RESTlet application embedded in a Tomcat server and clients are complaining that % symbols in @FormParm parameters are doubly decoded in the RESTlet framework causing a server error 500.

My questions are: Do the clients need to doubly encode percent symbols (e.g. send xx%2525xx to represent the five character sequence "xx%xx")? If so, is this a bug in the RESTlet framework or the common way of encoding form parameters? If not, how am I misusing the RESTlet framework?

My API looks like

//... many imports omitted.
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;

@Path("/{session}/foo/")
@Transactional(propagation = Propagation.REQUIRED)

 /**  ........
  */
public class DocumentService extends BaseService {
// ...
     */
  @POST
  @Path("/{path:.*}/")
  @Consumes({"application/x-www-form-urlencoded"})
  @Produces({"application/json"})
  public Response alterDocument(final @Context UriInfo ui, 
    final @Context HttpHeaders hh,
    final @PathParam("session") String sessionToken,
    final @PathParam("path") String path,
    @FormParam("name") String name) throws WebApplicationException {
      /// code here not reached on call described below ....
    }

A curl command like:

curl -H "Accept: application/json" -d "name=100%25+working" http://${host}/api/sessionx21/foo/home/

Generates a server-side stack trace that looks like:

Apr 2, 2012 5:15:20 PM org.restlet.ext.jaxrs.internal.util.ExceptionHandler methodInvokeException WARNING: Can not invoke the resource method java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: " w"    at java.net.URLDecoder.decode(URLDecoder.java:173)    at org.restlet.data.Reference.decode(Reference.java:170)    at org.restlet.data.Reference.decode(Reference.java:143)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList$AbstractParamGetter.convertParamValue(ParameterList.java:186)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList$AbstractParamGetter.convertParamValue(ParameterList.java:166)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList$FormOrQueryParamGetter.getParamValue(ParameterList.java:529)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList$FormParamGetter.getParamValue(ParameterList.java:561)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList$AbstractParamGetter.getValue(ParameterList.java:409)    at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList.get(ParameterList.java:1096)    at org.restlet.ext.jaxrs.internal.wrappers.AbstractMethodWrapper.internalInvoke(AbstractMethodWrapper.java:166)

My pom.xml file contains

    <repository>
      <id>maven-restlet</id>
      <name>Public online Restlet repository</name>
      <url>http://maven.restlet.org</url>
    </repository>
....
       <jaxb.version>2.1</jaxb.version>
有帮助吗?

解决方案

I know this question posted long time ago, but maybe someone will still find it useful. I had the same problem today.

After digging the restlet code - it seems like there is a bug of url-decoding the parameters twice. Workaround for this is to annotate the method with @Encoded. This annotation mark not to decode the paramaters, so it will only be decoded once.

@POST
@Path("/{path:.*}/")
@Encoded
@Consumes({"application/x-www-form-urlencoded"})
@Produces({"application/json"})
public Response alterDocument(final @Context UriInfo ui, 
  final @Context HttpHeaders hh,
  final @PathParam("session") String sessionToken,
  final @PathParam("path") String path,
  @FormParam("name") String name) throws WebApplicationException {
    /// code here not reached on call described below ....
 }

其他提示

I know this is a very old question, but the issue still exists in Restlet's JAX-RS implementation today. It's definitely a bug, so I've formalized a bug report with Restlet. Here's to hoping it will be fixed in an upcoming release!

Bug report with all relevant implementation details here:

http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4375&dsMessageId=3091010

i run into this bug,too.my solution is changed the pom dependency from restlet-ext-jaxrs 2.0.9 to restlet-ext-jaxrs 2.0.9-snapshot.the diference of these two jar file is the ParameterList class' AbstractParamGetter method.The former one has the external code snippet:

  if(decode() && paramValue != null)
            paramValue = Reference.decode(paramValue);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top