Au REPOS du ressort du service: récupération de JSON à partir de la Demande
Je suis la construction d'un service REST sur Spring 3.1. Je suis à l'aide de @EnableWebMVC annotation. Depuis mon service ne sera accepter JSON demandes, je tiens également à faire un dump de la demande entrante dans une collection MongoDB pour l'enregistrement (et, plus tard, pour la transformation de données). Je voudrais accéder à la crue JSON Demande (qui je pourrais faire sur un non-printemps de la mise en œuvre à l'aide de "@Contenu HttpServletRequest request" comme un paramètre de méthode).
Je suis un Printemps débutant. Donc, de bien vouloir m'aider avec les directions pour atteindre cet objectif. Merci!
Mise à JOUR: Le problème n'est pas complètement résolu. Seulement mes tests avec avoir travaillé. Il échoue avec la POSTE. Donc décoché la case accepté de répondre à
La question est, même si je créer un HttpServletRequestWrapper, je ne peut pas suivre la demande après que j'processus et envelopper la demande. Voici ce qui arrive:
Intercepteur:
public class DBLogInterceptor extends HandlerInterceptorAdapter {
MyRequestWrapper requestWrapper;
private final static Logger logger = Logger.getLogger(DBLogInterceptor.class);
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception
{
requestWrapper = new MyRequestWrapper(request);
//Code removed, but it just dumps requestWrapper.getBody() into DB
return super.preHandle(requestWrapper, response, handler);
}
}
HTTP POST méthode de service
@RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
@ResponseBody
public String updateEntity(@RequestBody Employee emp) {
//Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
Maintenant, je reçois une exception chaque fois que j'envoie un POST:
12:04:53,821 DEBUG DBLogInterceptor:22 - {"name":"Van Damme","dept":"Applied Martial Arts"}
12:04:53,843 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.test.webapp.login.domain.Employee] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@154174f9]
12:04:53,850 DEBUG ExceptionHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Stream closed
12:04:53,854 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,854 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,859 DEBUG DispatcherServlet:910 - Could not complete request
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224)
at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785)
at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1914)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Je m'attendais à la HttpServletRequestWrapper
de s'occuper de la mise en cache à la demande. Mais il ne se produise pas, en quelque sorte.
OriginalL'auteur user1323865 | 2012-05-05
Vous devez vous connecter pour publier un commentaire.
À l'aide de la HttpServletRequest objet, vous pouvez obtenir l'accès à l'URL, le client a utilisé pour faire la demande, la méthode utilisée (GET, POST, PUT, etc), la chaîne de requête, et les en-têtes.
Obtenir le RequestBody peut-être un peu plus difficile et peut nécessiter l'utilisation de HttpServletRequestWrapper objet. Depuis le corps de la requête ne peut être lu qu'une seule fois, vous aurez besoin de prolonger le wrapper pour y accéder, afin que votre cible contrôleur peut toujours y accéder plus tard à désérialiser votre JSON dans POJO objets.
Pour accéder à la demande dans un emplacement central, vous pouvez utiliser un Filtre ou un Printemps de l'Intercepteur. Ces deux sont invoqués avant la demande de délégués à la manette, et les deux ont accès à la servlet.
Voici un enregistrement réel exemple à l'aide d'un Printemps de l'Intercepteur:
Dans le LoggerInterceptor, vous pouvez utiliser le code suivant pour accéder à la demande:
Juste remarqué la unaccept. N'est ce pas de plus à résoudre votre problème? 😉
yep, j'avais fait des tests uniquement avec GET (stupide moi). J'ai mis à jour la question avec plus de détails. Pourriez-vous s'il vous plaît aider?
FINALISATION: jmort253 la réponse de travailler avec un bit de modification: remplacer le ressort de l'intercepteur avec javax.servlet.Filtre << enveloppez-la demande
Je reçois des flux est fermé exception , quelqu'un peut s'il vous plaît aider!
OriginalL'auteur jmort253
Je doute si
HttpServletRequestWrapper
peut jamais travailler... jetez un oeil à la DispatcherServlet mise en œuvre:Il passe la référence à "
processedRequest
" encore, qui se réfère à unHttpServletRequest
demande dont le flux a déjà été lu.OriginalL'auteur user1323865
Je sais que c'est une vieille question, mais pour ceux d'entre vous qui sont toujours à la recherche d'une solution, cela a fonctionné pour moi:
Ensuite, il suffit de vous inscrire le filtre dans web.xml et vous avez terminé. Tous les crédits à: http://wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431 (j'ai juste fait quelques correctifs mineurs).
OriginalL'auteur Aurasphere
Actuellement dans spring-mvc pensions, les intercepteurs sont invoqués dans DispatcherServlet#doDispatch(...):
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
Puis-je définir ma propre
DispatcherServlet
, et remplacerdoDispatch(...)
à injecter unHttpRequestWrapper
avec unByteArrayInputStream
surgetInputStream()
?Ce travail pour la situation ci-dessus?
OriginalL'auteur JayabalanAaron
Je fais un Ouputstream version sans aucune dépendance à la 3e partie libs pour en faciliter la réutilisation. Vous pouvez utiliser cette 2 classe wrapper pour obtenir la demande & le corps de la réponse facilement.
Mais de toute façon, je dois utiliser un filtre pour ce faire, au lieu de l'intercepteur. Parce que @user1323865 mentionné, au printemps 4, le processedRequest est utilisé dans les deux intercepteurs et de gestionnaire, de sorte que vous ne pouvez pas utiliser ces méthodes pour l'intercepteur.
Vous pouvez aussi trouver de l'aide dans ce lien si vous êtes à l'aide de l'Écrivain version à la place.
Capturer et enregistrer le corps de la réponse
OriginalL'auteur Happier
Hé, pouvez-vous essayer avec cette:
Ici: il vous prouver URI avec le '/', il permet d'effectuer toutes les opérations à effectuer. comme après la mise à jour et supprimer avec la même URI valeur.
OriginalL'auteur user3094823
Vous avez besoin pour mettre en œuvre les requestWrapper comme suit:
et puis à l'intérieur de la chaîne.doFilter méthode de la classe de filtre passe la requestWrapper objet au lieu de l'objet de la requête comme suit:
Donc de la résolution de l'IOStream fermé exception.
OriginalL'auteur KayV
Une façon simple de le faire serait d'obtenir le corps de la requête en tant que Chaîne et ensuite d'analyser comme un objet Java. Vous pouvez utiliser cette Chaîne alors que vous le souhaitez.
Donc dans votre exemple:
Une remarque, si vous en avez besoin d'une liste, vous pouvez utiliser:
OriginalL'auteur Giannis Smirnios
Vous pouvez simplement utiliser :
OriginalL'auteur zeeshank1
Dans mes expériences,de développer simplement comme suit:
En utilisant le filtre de manière à wrapper ServletRequest,alors vous pouvez repeatly utilisation se demander flux d'entrée.
OriginalL'auteur user8804204