Java 서블릿의 POST 요청에서 요청 페이로드 가져 오기


113

Java 서블릿에 POST 요청을 보내는 javascript 라이브러리가 있지만 doPost메서드에서 요청 페이로드의 내용을 가져올 수없는 것 같습니다. 크롬 개발자 도구에서 모든 콘텐츠는 헤더 탭의 Request Payload 섹션에 있으며 콘텐츠는 거기에 있으며 POST가 doPost 메서드에 의해 수신되고 있음을 알고 있지만 공백으로 표시됩니다.

를 들어 HttpServletRequest 개체, 어떤 방법으로하는 것은 내가 요청 페이로드 데이터를 얻을 수 있습니까?

데이터가 request.getParameter()없거나 request.getAttributes()둘 다 수행


예를 들어 본문에 키워드가있는 경우 어떤 매개 변수를 지정해야합니다. use String keyword = request.getParameter ( "keyword");
justMe

요청을 보내는 JavaScript 코드를 보는 것은 흥미로울 것입니다. 요청 매개 변수를 잘못된 방식으로 구성하고있는 것 같습니다.
BalusC

@Razh 예, 알아요, 제가 시도한 방법을 지정하고 있었어요. BalusC 나는 핸들 분할 파일 업로드에 resumable.js 라이브러리를 사용하고 있습니다
Fasih 아완

4
내가 잘못 이해하고 있지 않다면 입력 스트림에서 읽기 전에 request.getParameter ()를 사용하지 않는 것이 중요합니다. 그렇지 않으면 데이터를 사용할 수 없습니다 (이미 읽음).
Jeach 2013-04-30

답변:


110

간단한 대답 :
getReader ()를 사용하여 요청 본문을 읽습니다.

추가 정보 :
본문의 데이터를 읽는 방법에는 두 가지가 있습니다.

  1. getReader()요청 본문을 읽을 수 있는 BufferedReader 를 반환합니다 .

  2. getInputStream()바이너리 데이터를 읽어야 하는 경우 ServletInputStream을 반환합니다 .

문서에서 참고 : "[Either method]는 본문을 읽기 위해 호출 될 수 있습니다. 둘 다가 아닙니다."


4
어떤 문제, 조금 한 것을 숨겨 있어요
davidfrancis

25
이 게시물은 필터에서 이것을 사용한 다음 다른 어떤 것도 본문을 다시 읽을 수 없다는 것을 발견 한 경우 유용 할 수 있습니다! natch3z.blogspot.co.uk/2009/01/read-request-body-in-filter.html
JonnyRaa

이것은 정말 나쁜 대답입니다.
SgtPooki

1
@SgtPooki는 그 의견에 대한 추론을 자유롭게 추가하십시오.
davidfrancis

@davidfrancis 여기서 당신을 개인적으로 판단하려고하는 것은 아니지만 : 당신은 맥락을 제공하지 않았습니다. 문서에 대한 링크도, 예도 없습니다. 내 의견에 대한 귀하의 답변은 답변 자체보다 더 많은 노력이 필요한 것 같습니다.
SgtPooki

68
String payloadRequest = getBody(request);

이 방법 사용

public static String getBody(HttpServletRequest request) throws IOException {

    String body = null;
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;

    try {
        InputStream inputStream = request.getInputStream();
        if (inputStream != null) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }
        } else {
            stringBuilder.append("");
        }
    } catch (IOException ex) {
        throw ex;
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException ex) {
                throw ex;
            }
        }
    }

    body = stringBuilder.toString();
    return body;
}

6
request.getInputStream()요청 문자 인코딩 을 따르지 않는 것을 고려하십시오 request.getReader(). 따라서이 예에서는 기본 시스템 문자 집합을 사용합니다.
Vadzim 2014

9
new BufferedReader(new InputStreamReader(request.getInputStream()))request.getReader()이미 버퍼링되고 요청 인코딩을 보존 하도록 단순화 할 수 있습니다 .
Vadzim 2014

1
이 솔루션은 예외가 발생 javax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this request했을 때 유용하다는 것을 알았습니다 . 독자가 이미 열려있는 결과로 getReader ()를 호출했을 때.
Benjamin Slabbert

52

요청에서 읽을 때까지 버퍼 리더를 사용할 수 있습니다.

    // Read from request
    StringBuilder buffer = new StringBuilder();
    BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line);
    }
    String data = buffer.toString()

40

자바 8 스트림

String body = request.getReader().lines()
    .reduce("", (accumulator, actual) -> accumulator + actual);

이것은 흥미롭지 만 문자열 연결 측면에서 상당히 비효율적으로 보입니다! 개선 할 수있는 방법이 있습니까?
davidfrancis

11
String body = request.getReader (). lines (). collect (Collectors.joining ()); 작동 할 수도 있습니다. Collectors.joining은 분명히 내부적으로 StringBuilder를 사용합니다.
Oliver Kohll 2016-08-30

3
줄 바꿈을 유지하려면 request.getReader (). lines (). collect (joining ( "\ n"))해야한다고 생각합니다.
마이클 Böckling

Java 8에서는 스트림이 병렬로 처리되므로 순차적 메서드를 추가해야합니다. 그렇지 않으면 데이터의 잘못된 부분을 병합합니다.-String body = request.getReader (). lines (). sequential (). reduce (System.lineSeparator (), ( 누산기, 실제)-> 누산기 + 실제)
Jatin Bodarya

2
당신은 대체 할 수 있습니다 (accumulator, actual) -> accumulator + actualString::concat.
shmosel


12

본문의 내용이 Java 8의 문자열 인 경우 다음을 수행 할 수 있습니다.

String body = request.getReader().lines().collect(Collectors.joining());


5

JSON으로 페이로드를 보낼 수있는 경우 플레이로드를 읽는 가장 편리한 방법입니다.

데이터 클래스 예 :

public class Person {
    String firstName;
    String lastName;
    // Getters and setters ...
}

페이로드 예 (요청 본문) :

{ "firstName" : "John", "lastName" : "Doe" }

서블릿에서 페이로드를 읽는 코드 (com.google.gson. * 필요) :

Person person = new Gson().fromJson(request.getReader(), Person.class);

그게 다야. 좋고 쉽고 깨끗합니다. content-type 헤더를 application / json으로 설정하는 것을 잊지 마십시오.


2

리소스로 Java 8 사용해보기 :

    StringBuilder stringBuilder = new StringBuilder();
    try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
        char[] charBuffer = new char[1024];
        int bytesRead;
        while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
            stringBuilder.append(charBuffer, 0, bytesRead);
        }
    }

1

당신은 필요합니다

request.getParameterMap ()

POST 및 GET-매개 변수를 가져옵니다.

메서드는 Map<String,String[]> .

지도에서 매개 변수를 읽을 수 있습니다.

Map<String, String[]> map = request.getParameterMap();
//Reading the Map
//Works for GET && POST Method
for(String paramName:map.keySet()) {
    String[] paramValues = map.get(paramName);

    //Get Values of Param Name
    for(String valueOfParam:paramValues) {
        //Output the Values
        System.out.println("Value of Param with Name "+paramName+": "+valueOfParam);
    }
}

2
주의 : 매개 변수는 인코딩을 사용하는 경우에만 사용할 수 있습니다 application/x-www-form-urlencoded. 의 multipart/form-data경우 본문 부분에 액세스하여 request.getReader()수동으로 구문 분석해야합니다.
twonkeys
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.