RESTlet, кажется, дважды декодирует мои параметры формы - PullRequest
2 голосов
/ 03 апреля 2012

У меня есть приложение RESTlet, встроенное в сервер Tomcat, и клиенты жалуются, что символы% в параметрах @FormParm дважды декодируются в среде RESTlet, вызывая ошибку сервера 500.

Мои вопросы: Нужно ли клиентам дважды кодировать символы процента (например, отправить xx% 2525xx, чтобы представить последовательность из пяти символов "xx% xx")? Если так, это ошибка в структуре RESTlet или общий способ кодирования параметров формы? Если нет, то как я неправильно использую фреймворк RESTlet?

Мой API выглядит как

//... 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 ....
    }

Команда curl, например:

curl -H "Принять: application / json" -d "name = 100% 25 + работает" http://${host}/api/sessionx21/foo/home/

Создает трассировку стека на стороне сервера, которая выглядит следующим образом:

2 апреля 2012 г. 17:15:20 org.restlet.ext.jaxrs.internal.util.ExceptionHandler methodInvokeException ВНИМАНИЕ: Невозможно вызвать метод ресурса java.lang.IllegalArgumentException: URLDecoder: недопустимые шестнадцатеричные символы в шаблоне escape (%) - для входной строки: "w" на java.net.URLDecoder.decode (URLDecoder.java:173) на org.restlet.data.Reference.decode (Reference.java:170) на org.restlet.data.Reference.decode (Reference.java:143) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList $ AbstractParamGetter.convertParamValue (ParameterList.java:186) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList $ AbstractParamGetter.convertParamValue (ParameterList.java:166) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList $ FormOrQueryParamGetter.getParamValue (ParameterList.java:529) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList $ FormParamGetter.getParamValue (ParameterList.java:561) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList $ AbstractParamGetter.getValue (ParameterList.java:409) в org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList.get (ParameterList.java:1096) в org.restlet.ext.jaxrs.internal.wrappers.AbstractMethodWrapper.internalInvoke (AbstractMethodWrapper.java:166)

Мой файл pom.xml содержит

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

Ответы [ 3 ]

2 голосов
/ 09 ноября 2014

Я знаю, что это очень старый вопрос, но проблема все еще существует в реализации JAX-RS Рестлета сегодня.Это определенно ошибка, поэтому я формализовал отчет об ошибках в Restlet.Надеюсь, что это будет исправлено в следующем выпуске!

Отчет об ошибке со всеми подробностями реализации здесь:

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

1 голос
/ 14 марта 2013

Я тоже столкнулся с этой ошибкой. В моем решении изменена зависимость pom с restlet-ext-jaxrs 2.0.9 на restlet-ext-jaxrs 2.0.9-snapshot. Различие этих двух jar-файлов заключается в классе ParameterList'AbstractParamGetter метод. Первый из них имеет внешний фрагмент кода:

  if(decode() && paramValue != null)
            paramValue = Reference.decode(paramValue);
1 голос
/ 14 августа 2012

Я знаю этот вопрос, опубликованный давно, но, возможно, кто-то все равно найдет его полезным. У меня была такая же проблема сегодня.

После копания кода рестлета - кажется, что есть ошибка, связанная с двойным декодированием параметров URL. Обходной путь для этого состоит в том, чтобы аннотировать метод с помощью @ Encoded . Эта пометка не предназначена для декодирования параметров, поэтому она будет декодирована только один раз.

@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 ....
 }
...