web-dev-qa-db-de.com

Wie man Jersey-Interzeptoren verwendet, um die Anfrage zu erhalten

Ich verwende REST-Jersey in meinem Projekt. Alle POST -Daten werden im JSON-Format gesendet und serverseitig in den entsprechenden Beans nicht zugeordnet. Etwas wie das:

Anfrage an Server senden:

    $('a#sayHelloPost').click(function(event){
        event.preventDefault();
        var mangaData = {
            title:'Bleach',
            author:'Kubo Tite'
        }
        var formData=JSON.stringify(mangaData);
        console.log(formData);
        $.ajax({
                url:'rest/cred/sayposthello',
                type: 'POST',
                data: formData,
                dataType: 'json',
                contentType:'application/json'
        })
});

Nutzlast:

{"title":"Bleach","author":"Kubo Tite"}

Server-Ende:

@POST
@Path("/sayposthello")
@Produces(MediaType.APPLICATION_JSON)
public Response sayPostHello(MangaBean mb){
    System.out.println(mb);
    return Response.status(200).build();
}

MangaBean:

public class MangaBean {
    private String title;
    private String author;
    @Override
    public String toString() {
        return "MangaBean [title=" + title + ", author=" + author + "]";
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
}

Ausgabe auf der Konsole:

MangaBean [title=Bleach, author=Kubo Tite]

Ich habe die REST-Interceptor-Implementierung von hier erhalten.

public class JerseyFilter implements ContainerRequestFilter{

    @Override
    public ContainerRequest filter(ContainerRequest req) {
        return req;
    }

} 

Ich möchte auf die Nutzlast (Anfragekörper) im Interceptor zugreifen. Da die Daten im JSON-Format vorliegen, sind sie nicht als Anforderungsparameter verfügbar. Gibt es eine Möglichkeit, den Anforderungstext in der Interceptor-Methode zu erhalten? Bitte Rat.

15
Mono Jamoon

Hier ist eine Möglichkeit, die Sie implementieren können, sehr ähnlich wie Jersey die Protokollierungsfilter implementiert. Sie können die Entität lesen und auf die Anfrage zurück kleben, damit Sie sie nicht versehentlich in Ihrem Filter verbrauchen.

import com.Sun.jersey.api.container.ContainerException;
import com.Sun.jersey.core.util.ReaderWriter;
import com.Sun.jersey.spi.container.ContainerRequest;
import com.Sun.jersey.spi.container.ContainerRequestFilter;

import Java.io.ByteArrayInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.IOException;
import Java.io.InputStream;

public class JerseyFilter implements ContainerRequestFilter {

    @Override
    public ContainerRequest filter(ContainerRequest request) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream in = request.getEntityInputStream();
        final StringBuilder b = new StringBuilder();
        try {
            if (in.available() > 0) {
                ReaderWriter.writeTo(in, out);

                byte[] requestEntity = out.toByteArray();
                printEntity(b, requestEntity);

                request.setEntityInputStream(new ByteArrayInputStream(requestEntity));
            }
            return request;
        } catch (IOException ex) {
            throw new ContainerException(ex);
        }

    }

    private void printEntity(StringBuilder b, byte[] entity) throws IOException {
        if (entity.length == 0)
            return;
        b.append(new String(entity)).append("\n");
        System.out.println("#### Intercepted Entity ####");
        System.out.println(b.toString());
    }
}
27

Sie können den POST Body aus dem Requests-Eingabestrom erhalten. Versuchen Sie Folgendes:

        @Override
        public ContainerRequest filter(ContainerRequest req) {
            try{

            StringWriter writer = new StringWriter();       
                IOUtils.copy(req.getEntityInputStream(), writer, "UTF-8");

            //This is your POST Body as String      
            String body = writer.toString();

                }
            catch (IOException e) {}
         return req; }
4
azraelAT

Sie können den Inhalt nur einmal lesen, da es sich um einen Eingabestrom handelt. Wenn Sie es im Interceptor abholen, können Sie es nicht im Haupt-Parsing bereitstellen.

Sie müssen einen Filter erstellen, der die Daten liest und allen anderen zur Verfügung stellt, die sie benötigen. Grundlegende Schritte sind:

  • erstellen Sie in Ihrem Filter eine neue Unterklasse von HttpServletRequestWrapper, die die Eingabe in einen Puffer einliest und getInputStream () überschreibt, um einen neuen Eingabestrom für diesen Puffer bereitzustellen
  • gib deine neue Unterklasse durch die Kette
2
jgm

Verwenden Sie nicht die Methode in.available(), um die Gesamtbytes von Inputstream zu überprüfen. Einige Clients setzen diesen Wert nicht. In diesem Fall ist dies jedoch ein Problem, obwohl der Eingabestream des Nachrichtentexts vorhanden ist.

 InputStream in = request.getEntityInputStream();
        final StringBuilder b = new StringBuilder();
        try {
            if (in.available() > 0)

Verwenden Sie den folgenden Code 

String json = IOUtils.toString(requestContext.getEntityStream(), Charsets.UTF_8);
            messageBody = json;
            InputStream in = IOUtils.toInputStream(json);
            requestContext.setEntityStream(in);
2
SyParth