mvc - servletcontext java ejemplo
Cómo recuperar datos de entrada sin procesar de HttpServletRequest en java (2)
Estoy tratando de obtener los datos de la publicación en Java. Parece que debería ser una de las cosas más simples de hacer, ¿verdad? Quiero decir, HttpServletRequest.getParameter tiene que hacerlo ¿verdad? Entonces, ¿cómo puedes obtener los datos de publicación sin procesar?
Encontré que HttpServletRequest obtiene datos de JSON POST y usé el código de Kdeveloper para extraer los datos de la publicación de una solicitud. Funciona, pero hay una trampa: solo puedo obtener los datos de la publicación una vez .
Aquí está el método que hice del código de Kdeveloper:
public static String getPostData(HttpServletRequest req) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = req.getReader();
reader.mark(10000);
String 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.toString();
}
Anteriormente, había cerrado el lector al final de este método, pero eso causaba excepciones cuando el método se ejecutaba más de una vez en la misma solicitud. Sin cerrarlo, no se producen excepciones, pero el método devuelve una cadena vacía.
Honestamente, debería haber solo un método req.getPostData () expuesto: ¿nadie pensó que sería útil?
Entonces, ¿cómo puedo escribir este método para que siempre devuelva los datos de publicación correctos?
El cuerpo de la solicitud está disponible por HttpServletRequest#getInputStream()
y #getReader()
.
InputStream body = request.getInputStream();
// ...
Tenga en cuenta que puede leerlo solo una vez. El cliente no va a volver a enviarlo varias veces. Llamar a getParameter()
y así sucesivamente también lo leerá implícitamente. Tienes que guardar el cuerpo en algún lugar y procesarte a ti mismo.
Tuvimos una situación en la que IE nos obligó a publicar como texto / normal, por lo que tuvimos que analizar manualmente los parámetros mediante getReader. El servlet se estaba utilizando para un sondeo largo, por lo que cuando se ejecutó AsyncContext :: dispatch después de un retraso, literalmente se volvió a publicar la solicitud con las manos vacías.
Así que acabo de almacenar la publicación en la solicitud cuando apareció por primera vez utilizando HttpServletRequest :: setAttribute. El método getReader vacía el búfer, donde getParameter vacía el búfer también, pero almacena los parámetros automágicamente.
String input = null;
// we have to store the string, 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 = (String) request.getAttribute("com.xp.input")) == null) {
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while((line = reader.readLine()) != null){
buffer.append(line);
}
// reqBytes = buffer.toString().getBytes();
input = buffer.toString();
request.setAttribute("com.xp.input", input);
}
if (input == null) {
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
out.print("{/"act/":/"fail/",/"msg/":/"invalid/"}");
}