HttpServletRequest থেকে পোষ্ট অনুরোধের বডিটি পান


114

আমি এইচটিটিপি সার্ভেলকুইয়েস্ট অবজেক্ট থেকে পুরো শরীরটি পাওয়ার চেষ্টা করছি।

আমি যে কোডটি অনুসরণ করছি তা দেখতে এটির মতো দেখাচ্ছে:

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 --header "MD5: abcd" -F "fileupload=@filename.txt 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 )কিছুই ফেরায় না, এবং তাই স্ট্রিংবুফারে আমার কিছুই যুক্ত হয় না।

উত্তর:


191

জাভা 8 এ, আপনি এটি একটি সহজ এবং পরিষ্কার উপায়ে করতে পারেন:

if ("POST".equalsIgnoreCase(request.getMethod())) 
{
   test = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
}

7
কোনও তৃতীয় পক্ষের নির্ভরতা ছাড়াই খাঁটি জাভা হওয়ার কারণে আমি এই সমাধানটি পছন্দ করি।
lu_ko

49
যদিও মনে রাখবেন যে আমরা অনুরোধের বডিটি getReaderইতিমধ্যে বলা হয়ে থাকতে পারে তা আর পড়তে পারি না ।
নিখিল সাহু

1
আমরা কীভাবে আবার নতুন ফর্ম্যাট করা HTTP পোষ্ট ডেটা অনুরোধে ফিরে যেতে পারি?
প্রাক_এ

1
আমি এই সমাধানটি চেষ্টা করেছি তবে এটি একটি অত্যন্ত মারাত্মক প্রব্লেম প্রবর্তন করেছে, আমি এই কোডটি একবারে প্যার রিকোয়েস্ট ফিল্টারের ভিতরে তথ্য লগ করার জন্য ব্যবহার করেছি এবং যখন আমি এটি ব্যবহার করি তখন আমার সমস্ত পোস্ট পদ্ধতিতে আমার সমস্ত পোস্ট মডেলঅ্যাট্রিবিউটেড বাইন্ডিংয়ের সমস্ত ক্ষেত্রে বাতিল হয়ে যায় অবজেক্ট .আমি এই পদ্ধতির ব্যবহার করার পরামর্শ দিচ্ছি না।
মোহাম্মদ ফাতি

আমাদের কি পাঠককে বন্ধ করা উচিত নয়?
অ্যারিস্টো_শ

46

কমন্স-আইও সহ সহজ উপায়।

IOUtils.toString(request.getReader());

https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/IOUtils.html


পাঠকের আউটপুট কেমন হবে (উদাহরণস্বরূপ কীগুলি দেখায় বা না দেখায়) তার উদাহরণ দিতে পারলে আমি সহায়তা করব
আর্থারজি

এটি আমার পক্ষে কাজ করেছে। আমি নিশ্চিত করতে পারি যে এই সমাধানটি একটি সাধারণ দৃশ্য এড়িয়ে চলেছে যেখানে বাফারড্রেডার.রেডলাইন () কোনও আপাত কারণ ছাড়াই "স্তব্ধ"
নরেন

হাই @ ডেভিডডোমিংগো, এটি 100% কাজ করে, আমি পড়তে পারি যে আপনি এটির উপরে দেওয়া প্রতিক্রিয়াতে একই মন্তব্য করছেন (যা কাজ করে)। আপনার কোডের কোথাও (সম্ভাব্য ফিল্টারগুলি) পরীক্ষা করুন বা সম্ভবত বসন্তের কারণে, getReader () পদ্ধতিটি আগে কল করা হয়নি কারণ আপনি যদি এটির দ্বিগুণ বা আরও বেশি বার কল করেন তবে এটি কেবল প্রথমটি পেডলোড দেয়।
দানি

হাই @ দানি, সে কারণেই এটি কার্যকর হয় না। পাঠক খালি। আমি মনে করি যে কোনও শেষ পয়েন্টে আপনি সক্ষম হবার আগে রেস্টকন্ট্রোলার এটি পড়ে। দেহ পাওয়ার সহজতম উপায় হ'ল এইচটিপিএনটিটি ব্যবহার করে।
ডেভিড ডোমিংগো

31

সচেতন হন, আপনার কোডটি বেশ কোলাহলপূর্ণ। আমি জানি যে থ্রেডটি পুরানো, তবে প্রচুর লোক যাইহোক এটি পড়বে। আপনি পেয়ারার লাইব্রেরিটি ব্যবহার করে একই জিনিসটি করতে পারেন :

    if ("POST".equalsIgnoreCase(request.getMethod())) {
        test = CharStreams.toString(request.getReader());
    }

3
সম্ভবত বিবেচনা করুনif(RequestMethod.POST.name().equalsIgnoreCase(...)) { ... }
ম্যাডব্রেকস

আমি java.lang.IllegalStateException পেয়েছি: getReader () ইতিমধ্যে এই অনুরোধটির জন্য ডাকা হয়েছে
Pra_A

18

আপনি যদি চান তবে সমস্তই পোষ্ট অনুরোধের বডি, আপনি এই জাতীয় পদ্ধতি ব্যবহার করতে পারেন:

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 "";
}

ক্রেডিট: https://stackoverflow.com/a/5445161/1389219


1
অ্যাকাউন্টে request.getInputStream()অনুরোধ করুন যেমন অনুরোধের অক্ষর এনকোডিংকে সম্মান করে না request.getReader()। লিঙ্কের জন্য যদিও +1।
ভাদজিম

পুট পদ্ধতির সমতুল্য কী হওয়া উচিত?
দেবনাথন

10

এটি জিইটি এবং পোস্ট উভয়ের পক্ষে কাজ করে:

@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 "";
}

9

যদি অনুরোধের শরীরটি খালি থাকে তবে এর সহজ অর্থ হল এটি ইতিমধ্যে আগেই গ্রাস হয়ে গেছে। উদাহরণস্বরূপ, ক request.getParameter(), getParameterValues()বা getParameterMap()কল দ্বারা। আপনার কোড থেকে এই কলগুলি করার জন্য কেবল লাইনগুলি সরিয়ে দিন।


এটি কেবলমাত্র যদি কোনও ফাইল আপলোড না হয় তবে এটি কাজ করে, curlউদাহরণস্বরূপ, না?
ডেভ নিউটন

1
আমি এই জিনিস চেষ্টা করেছিলাম। তবে তবুও আমি পোষ্ট বডি পাচ্ছি না। আমি নিশ্চিত কিছু একটা ভুলে যাচ্ছি। কেবল যোগ করতে: আমি বিকাশের জন্য টেপস্ট্রি ব্যবহার করছি।
পটেল ভাবিন

3

এটি সমস্ত এইচটিটিপি পদ্ধতিতে কাজ করবে।

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;
    }
}

0

আমি সেই পরিস্থিতি এইভাবে সমাধান করেছি। আমি একটি ব্যবহারের পদ্ধতি তৈরি করেছি যা অনুরোধ সংস্থা থেকে নিষ্কাশিত কোনও বস্তু ফেরত দেয়, অবজেক্টম্যাপারের রিডভ্যালু পদ্ধতিটি ব্যবহার করে যা একজন রিডার প্রাপ্তিতে সক্ষম।

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;
}

1
পোর্টাল ইউটিল কী?
ফেরি ক্রেনেনবার্গে

আমি বাজি ধরছি এটি লাইফ্রে, লাইফ্রে-নির্দিষ্ট এপিআই
এমভিএমএন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.