How to get form Parameter in der request-filter

Ich versuche, den form-Parameter einer Anfrage in eine Anfrage filter:

@Override
public ContainerRequest filter(final ContainerRequest request) {

    final Form formParameters = request.getFormParameters();

    //logic

    return request;
}

Jedoch die form scheint immer leer zu sein. Die HttpRequestContext.getFormParameters() Dokumentation sagt:

Get form Parameter der Anfrage-Entität.

Diese Methode wird sichergestellt, dass der Antrag Entität ist gepuffert, so dass es sein kann, verbraucht die applicaton.

Gibt:
die Parameter form, wenn es eine Anforderung Einheit und der content type "application/x-www-form-urlencoded", sonst eine Instanz, die keine Parameter zurückgegeben werden.

Meine Ressource ist versehen mit @Consumes("application/x-www-form-urlencoded"), obwohl es wird nicht abgeglichen wurden, bis nach der Anforderung filter - ist es das, warum funktioniert das nicht?

Ich habe versucht zu tun, einige Forschung, aber konnten keine schlüssigen Beweise dafür, ob dies möglich ist. Es war dieser 4-jährige Diskussion, in denen Paul Sandoz sagt:

Wenn Sie in der Jersey-Filter oder mit der HttpRequestContext können Sie den form-Parameter wie folgt: [broken link zu Jersey 1.1.1 HttpRequestContext.getFormParameters]

Fand ich auch diese 3-jährige Diskussion über, wie man multipart/form-data Formular-Felder in einem filter "Anforderung". In es, Paul Sandoz verwendet den folgenden code:

//Buffer
InputStream in = request.getEntityInputStream();
if (in.getClass() != ByteArrayInputStream.class) {
    //Buffer input
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
        ReaderWriter.writeTo(in, baos);
    } catch (IOException ex) {
        throw new ContainerException(ex);
    }
    in = new ByteArrayInputStream(baos.toByteArray());
    request.setEntityInputStream(in);
}

//Read entity
FormDataMultiPart multiPart = request.getEntity(FormDataMultiPart.class);

Ich habe versucht, zu emulieren, dass der Ansatz für Form statt, aber das Ergebnis request.getEntityInputStream() ist immer ein leerer stream. Und schaut der Quellcode von getFormParameters, dass die Methode ist in der Tat die gleiche Sache schon:

@Override
public Form getFormParameters() {
    if (MediaTypes.typeEquals(MediaType.APPLICATION_FORM_URLENCODED_TYPE, getMediaType())) {
        InputStream in = getEntityInputStream();
        if (in.getClass() != ByteArrayInputStream.class) {
            //Buffer input
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            try {
                ReaderWriter.writeTo(in, byteArrayOutputStream);
            } catch (IOException e) {
                throw new IllegalArgumentException(e);
            }

            in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            setEntityInputStream(in);
        }

        ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream) in;
        Form f = getEntity(Form.class);
        byteArrayInputStream.reset();
        return f;
    } else {
        return new Form();
    }
}

Ich kann nicht herausfinden, was schlürfen bis die Einheit Eingabe-stream, bevor ich um es zu bekommen. Etwas in Jersey werden müssen konsumieren, weil es den form-Parametern werden später weitergereicht an die Ressource-Methode. Was mache ich hier falsch, oder ist das unmöglich (und warum)?

EDIT: Hier ist ein Beispiel für eine Anfrage gesendet:

POST /test/post-stuff HTTP/1.1
Host: local.my.application.com:8443
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

form_param_1=foo&form_param_2=bar

Hier ist die (etwas redundant) request-Erfassung:

INFO: 1 * Server in-bound request
1 > POST https://local.my.application.com:8443/test/post-stuff
1 > host: local.my.application.com:8443
1 > connection: keep-alive
1 > content-length: 33
1 > cache-control: no-cache
1 > origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
1 > user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
1 > content-type: application/x-www-form-urlencoded
1 > accept: */*
1 > accept-encoding: gzip,deflate,sdch
1 > accept-language: en-US,en;q=0.8
1 > cookie: [omitted]
1 > 

Hier sind die Antwort-Header der Anforderung, einschließlich der Jersey-Trace:

Content-Type →application/json;charset=UTF-8
Date →Fri, 09 Aug 2013 18:00:17 GMT
Location →https://local.my.application.com:8443/test/post-stuff/
Server →Apache-Coyote/1.1
Transfer-Encoding →chunked
X-Jersey-Trace-000 →accept root resource classes: "/post-stuff"
X-Jersey-Trace-001 →match path "/post-stuff" -> "/post\-stuff(/.*)?", [...], "(/.*)?"
X-Jersey-Trace-002 →accept right hand path java.util.regex.Matcher[pattern=/post\-stuff(/.*)? region=0,11 lastmatch=/post-stuff]: "/post-stuff" -> "/post-stuff" : ""
X-Jersey-Trace-003 →accept resource: "post-stuff" -> @Path("/post-stuff") com.application.my.jersey.resource.TestResource@7612e9d2
X-Jersey-Trace-004 →match path "" -> ""
X-Jersey-Trace-005 →accept resource methods: "post-stuff", POST -> com.application.my.jersey.resource.TestResource@7612e9d2
X-Jersey-Trace-006 →matched resource method: public javax.ws.rs.core.Response com.application.my.jersey.resource.TestResource.execute(java.lang.String,java.lang.String)
X-Jersey-Trace-007 →matched message body reader: class com.sun.jersey.api.representation.Form, "application/x-www-form-urlencoded" -> com.sun.jersey.core.impl.provider.entity.FormProvider@b98df1f
X-Jersey-Trace-008 →matched message body writer: java.lang.String@f62, "application/json" -> com.sun.jersey.core.impl.provider.entity.StringProvider@1c5ddffa

Hier ist die (unauffällig) servlet config:

<servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.application.my.jersey</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
        <param-value>com.application.my.jersey.MyFilterFactory</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.config.feature.Trace</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Hier ist die Beispiel-resource:

@Path("/post-stuff")
@Produces(MediaType.APPLICATION_JSON)
public final class TestResource {

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response execute(
            @FormParam("form_param_1") final String formParam1,
            @FormParam("form_param_2") final String formParam2
    ) {
        return Response.created(URI.create("/")).entity("{}").build();
    }
}

Bin ich mit Jersey 1.17.


Für diejenigen, die interessiert sind, ich bin versucht zu Rollen, meine eigene erforderlich überprüfung der parameter, wie beschrieben in JERSEY-351. Meine Lösung hier arbeitete für die Abfrage, cookie und header Parameter - form params halten sich auf mich.

  • Können Sie uns eine Anfrage, die Sie versenden den rest-Endpunkt.
  • Siehe mein edit, und laß mich wissen, wenn es etwas gibt, was ich bieten kann.
  • formParam1 und formParam2 sind null in Ihrem Ressource-Methode so gut ist? Nur um sicher zu sein MyFilterFactory enthält #filter Methode aus deinem ersten snippet?
  • formParam1 und formParam1 übergeben werden, die in die Ressource-Methode wie erwartet (nicht null). Ja, MyFilterFactory erstellt die Ressource-filter, die erstellt die container request-filter mit, dass filter Umsetzung.
InformationsquelleAutor Paul Bellora | 2013-08-09
Schreibe einen Kommentar