Comment récupérer des données de publication brutes à partir de HttpServletRequest dans Java

J’essaie d’obtenir les données de publication en Java. On dirait que ce devrait être l’une des choses les plus simples à faire correctement? Je veux dire, HttpServletRequest.getParameter doit le faire correctement? Alors, comment pouvez-vous obtenir les données post brutes?

J’ai trouvé que HttpServletRequest obtenait des données JSON POST et utilisait le code de Kdeveloper pour extraire les données de publication d’une requête. Cela fonctionne, mais il y a un problème: je ne peux obtenir ces données qu’une seule fois .

Voici la méthode que j’ai faite à partir du code de Kdeveloper:

public static Ssortingng getPostData(HttpServletRequest req) { SsortingngBuilder sb = new SsortingngBuilder(); try { BufferedReader reader = req.getReader(); reader.mark(10000); Ssortingng line; do { line = reader.readLine(); sb.append(line).append("\n"); } while (line != null); reader.reset(); // do NOT close the reader here, or you won't be able to get the post data twice } catch(IOException e) { logger.warn("getPostData couldn't.. get the post data", e); // This has happened if the request's reader is closed } return sb.toSsortingng(); } 

Auparavant, j’avais fermé le lecteur à la fin de cette méthode, mais cela entraînait des exceptions lorsque la méthode était exécutée plusieurs fois sur la même demande. Sans la fermer, aucune exception ne se produit, mais la méthode renvoie une chaîne vide.

Honnêtement, il devrait y avoir juste une méthode req.getPostData () exposée – personne ne pensait que cela serait utile?

Alors, comment puis-je écrire cette méthode pour qu’elle renvoie toujours les données de publication correctes?

Le corps de la requête est disponible par HttpServletRequest#getInputStream() et #getReader() .

 InputStream body = request.getInputStream(); // ... 

Notez que vous ne pouvez le lire qu’une seule fois. Le client ne va pas le renvoyer plusieurs fois. L’appel à getParameter() et ainsi de suite le lira implicitement. Vous devez stocker le corps quelque part et traiter vous-même.

Nous avons eu une situation où IE nous a obligés à publier sous le format text / plain, nous avons donc dû parsingr manuellement les parameters à l’aide de getReader. Le servlet était utilisé pour une longue interrogation. Ainsi, lorsque AsyncContext :: dispatch était exécuté après un délai, il était littéralement republié de la requête les mains vides.

Donc, je viens de stocker le post dans la requête quand il est apparu en utilisant HttpServletRequest :: setAtsortingbute. La méthode getReader vide le tampon, où getParameter vide également le tampon mais stocke automatiquement les parameters.

  Ssortingng input = null; // we have to store the ssortingng, which can only be read one time, because when the // servlet awakens an AsyncContext, it reposts the request and returns here empty handed if ((input = (Ssortingng) request.getAtsortingbute("com.xp.input")) == null) { SsortingngBuilder buffer = new SsortingngBuilder(); BufferedReader reader = request.getReader(); Ssortingng line; while((line = reader.readLine()) != null){ buffer.append(line); } // reqBytes = buffer.toSsortingng().getBytes(); input = buffer.toSsortingng(); request.setAtsortingbute("com.xp.input", input); } if (input == null) { response.setContentType("text/plain"); PrintWriter out = response.getWriter(); out.print("{\"act\":\"fail\",\"msg\":\"invalid\"}"); }