Ответ 1
В Java 8 вы можете сделать это более простым и понятным способом:
if ("POST".equalsIgnoreCase(request.getMethod()))
{
test = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
}
Я пытаюсь получить все тело из объекта HttpServletRequest.
Следующий код выглядит следующим образом:
if ( request.getMethod().equals("POST") )
{
StringBuffer sb = new StringBuffer();
BufferedReader bufferedReader = null;
String content = "";
try {
//InputStream inputStream = request.getInputStream();
//inputStream.available();
//if (inputStream != null) {
bufferedReader = request.getReader() ; //new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead;
while ( (bytesRead = bufferedReader.read(charBuffer)) != -1 ) {
sb.append(charBuffer, 0, bytesRead);
}
//} else {
// sb.append("");
//}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
test = sb.toString();
}
и я тестирую функциональность с curl и wget следующим образом:
curl --header "MD5: abcd" -F "[email protected] http://localhost:8080/abcd.html"
wget --header="MD5: abcd" --post-data='{"imei":"351553012623446","hni":"310150","wdp":false}' http://localhost:8080/abcd.html"
Но while ( (bytesRead = bufferedReader.read(charBuffer)) != -1 )
ничего не возвращает, поэтому я ничего не добавляю к StringBuffer.
В Java 8 вы можете сделать это более простым и понятным способом:
if ("POST".equalsIgnoreCase(request.getMethod()))
{
test = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
}
Простой способ использования commons-io.
IOUtils.toString(request.getReader());
https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/IOUtils.html
Помните, что ваш код довольно шумный. Я знаю, что нить устарела, но многие люди все равно прочтут ее. Вы можете сделать то же самое, используя библиотеку guava, используя:
if ("POST".equalsIgnoreCase(request.getMethod())) {
test = CharStreams.toString(request.getReader());
}
Если все, что вам нужно, это тело запроса POST, вы можете использовать такой метод:
static String extractPostRequestBody(HttpServletRequest request) throws IOException {
if ("POST".equalsIgnoreCase(request.getMethod())) {
Scanner s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
return "";
}
Кредит: fooobar.com/questions/226/...
Если тело запроса пустое, то это просто означает, что оно уже было израсходовано заранее. Например, request.getParameter()
, getParameterValues()
или getParameterMap()
. Просто удалите строки, выполняющие эти вызовы, из вашего кода.
Это работает как для GET, так и для POST:
@Context
private HttpServletRequest httpRequest;
private void printRequest(HttpServletRequest httpRequest) {
System.out.println(" \n\n Headers");
Enumeration headerNames = httpRequest.getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = (String)headerNames.nextElement();
System.out.println(headerName + " = " + httpRequest.getHeader(headerName));
}
System.out.println("\n\nParameters");
Enumeration params = httpRequest.getParameterNames();
while(params.hasMoreElements()){
String paramName = (String)params.nextElement();
System.out.println(paramName + " = " + httpRequest.getParameter(paramName));
}
System.out.println("\n\n Row data");
System.out.println(extractPostRequestBody(httpRequest));
}
static String extractPostRequestBody(HttpServletRequest request) {
if ("POST".equalsIgnoreCase(request.getMethod())) {
Scanner s = null;
try {
s = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
} catch (IOException e) {
e.printStackTrace();
}
return s.hasNext() ? s.next() : "";
}
return "";
}
Если вы пытаетесь разобрать и хотите обрабатывать загрузки файлов, используйте Commons FileUpload - он обрабатывает все синтаксические разборки для вас, оба поля и данные файла.
FWIW, код работает для меня как есть с помощью любой команды.
Что такое весь сервлет и его отображение?
Являются ли команды вы написали опечатки? Они не будут работать так, как есть.
Это будет работать для всех методов HTTP.
public class HttpRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public HttpRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
body = IOUtils.toString(request.getReader());
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getBody().getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
public String getBody() {
return this.body;
}
}
Я решил эту ситуацию таким образом. Я создал метод util, который возвращает объект, извлеченный из тела запроса, с использованием метода readValue ObjectMapper, который способен принимать Reader.
public static <T> T getBody(ResourceRequest request, Class<T> class) {
T objectFromBody = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
HttpServletRequest httpServletRequest = PortalUtil.getHttpServletRequest(request);
objectFromBody = objectMapper.readValue(httpServletRequest.getReader(), class);
} catch (IOException ex) {
log.error("Error message", ex);
}
return objectFromBody;
}