Frage

Ich bin Abbilden meines Wunsches des JSON POST-Daten in ein Objekt mit Spring @RequestBody Annotation und MappingJacksonHttpMessageConverter. Doch nach, dass ich mag die Daten in String Form lesen einige zusätzliche Authentifizierung zu tun. Aber wenn die Rangierung geschehen ist, ist die InputStream in HttpServletRequest leer. Sobald ich das Lesen von POST-Daten in ein @RequestBody Werke String Parameter aus dem Verfahren entfernen, wie erwartet.

Muss ich Kompromisse eingehen müssen, indem die @RequestBody Aufgeben und dabei die Bindung irgendwie manuell oder ist es eine elegantere Lösung?

War es hilfreich?

Lösung

Also, im Grunde benötigen Sie einen Hash-Wert des Anforderungstext zu berechnen. Die elegante Art und Weise, es zu tun ist, einen Dekorateur zum InputStream anzuwenden.

Zum Beispiel in einer Handler-Methode (in diesem Fall können Sie nicht @RequestBody und Bedarf verwenden HttpMessageConverter manuell erstellen):

@RequestMapping(...)
public void handle(HttpServletRequest request) throws IOException {
    final HashingInputStreamDecorator d = 
        new HashingInputStreamDecorator(request.getInputStream(), secretKey);
    HttpServletRequest wrapper = new HttpServletRequestWrapper(request) {
        @Override
        public ServletInputStream getInputStream() throws IOException {
            return d;
        }
    };

    HttpMessageConverter conv = ...;
    Foo requestBody = (Foo) conv.read(Foo.class, new ServletServerHttpRequest(wrapper));
    String hash = d.getHash();

    ...
}

wobei hash inkrementell in überschriebenen read Methoden der HashingInputStreamDecorator berechnet wird.

Sie können auch @RequestBody verwenden, wenn Sie einen Filter erstellen Sie den Dekorateur anzuwenden. In diesem Fall kann die decorator berechnete Hash zu der Handler-Methode als Anforderungs Attribut übergeben. Allerdings müssen Sie diese Filter zur Karte sorgfältig sie gelten nur für die Anfragen an bestimmten Behandlungsmethode.

Andere Tipps

In Ihrem UrlMapping bean können Sie die Liste zusätzlicher Abfangjäger deklarieren:

  <bean id="urlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
      <list>
        <bean class="org.foo.MyAuthInterceptor"/>
      </list>
    </property>
  </bean>

Diese Abfangjäger haben Zugriff auf HttpServletRequest, obwohl, wenn Sie aus dem Stream lesen die Chancen, dass Parameter Mapper sind nicht in der Lage sein, es zu lesen.

public class AuthInterceptor extends HandlerInterceptorAdapter {

  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    ...
  }

  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) {
    ...
  }
}

Wenn ich das richtig verstehe, eine gemeinsame Art und Weise verwendet, um mit JAX-RS (die Spring MVC in Bezug auf verbindliche Anfragen ein wenig ähnlich ist) ist zum ersten „bind“ in einem Zwischen roh Typ (in der Regel byte [], aber String funktioniert auch) und manuell von dem Objekt zu binden, zu Grunde liegende Daten Bindemittel (Jackson) verwendet wird. Ich oft tue dies der Lage sein, voll Bindungsfehlerbehandlung von Daten anpassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top