এইচটিটিপিআরএল সংযোগ থেকে ইনপুট স্ট্রিম অবজেক্ট পাওয়ার সময় ফাইলনটফাউন্ডএক্সেপশন


109

আমি এইচটিটিপিআরএল সংযোগ (জাভাতে সিআরএল ব্যবহার করার জন্য) ব্যবহার করে ইউআরএলকে একটি পোস্টের অনুরোধ প্রেরণের চেষ্টা করছি। অনুরোধের বিষয়বস্তু এক্সএমএল এবং শেষ পর্যায়ে, অ্যাপ্লিকেশনটি এক্সএমএল প্রসেস করে এবং ডাটাবেসে একটি রেকর্ড সঞ্চয় করে এবং তারপরে এক্সএমএল স্ট্রিং আকারে একটি প্রতিক্রিয়া প্রেরণ করে। অ্যাপ্লিকেশন স্থানীয়ভাবে অ্যাপাচি-টমক্যাটে হোস্ট করা হয়েছে।

আমি যখন টার্মিনাল থেকে এই কোডটি কার্যকর করি তখন প্রত্যাশার সাথে একটি সারি ডিবিতে যুক্ত হয়। সংযোগটি থেকে ইনপুট স্ট্রিম পাওয়ার সময় একটি ব্যতিক্রম নীচে ছুঁড়ে দেওয়া হয়েছে

java.io.FileNotFoundException: http://localhost:8080/myapp/service/generate
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1401)
    at org.kodeplay.helloworld.HttpCurl.main(HttpCurl.java:30)

কোডটি এখানে

public class HttpCurl {
    public static void main(String [] args) {

        HttpURLConnection con;

        try {
            con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);

            File xmlFile = new File("test.xml");

            String xml = ReadWriteTextFile.getContents(xmlFile);                

            con.getOutputStream().write(xml.getBytes("UTF-8"));
            InputStream response = con.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(response));
            for (String line ; (line = reader.readLine()) != null;) {
                System.out.println(line);
            }
            reader.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  }

এটি বিভ্রান্তিকর কারণ ব্যতিক্রমটি লাইনের সাথে সনাক্ত করা হয়েছে InputStream response = con.getInputStream();এবং কোনও ফাইল ফাইল নটফাউন্ডএক্সসেপশন এর সাথে জড়িত বলে মনে হচ্ছে না।

আমি যখন কোনও এক্সএমএল ফাইলের সাথে সরাসরি কোনও সংযোগ খোলার চেষ্টা করি তখন এটি ব্যতিক্রম হয় না।

পরিষেবা অ্যাপটি প্রতিক্রিয়া এক্সএমএল তৈরি করতে বসন্ত কাঠামো এবং জ্যাক্সবি 2 মার্শালার ব্যবহার করে।

ReadWriteTextFile ক্লাসটি এখান থেকে নেওয়া হয়েছে

ধন্যবাদ।

সম্পাদনা: আচ্ছা এটি ডিবিতে ডেটা সংরক্ষণ করে এবং একই সাথে 404 টি প্রতিক্রিয়া স্থিতি কোডটি প্রেরণ করে।

আমি পিএইচপি ব্যবহার করে কার্ল করার চেষ্টা করেছিলাম এবং প্রিন্ট আউটটি CURLINFO_HTTP_CODE200 এ পরিণত হয়।

আমি এটির ডিবাগিং সম্পর্কে কীভাবে যেতে পারি? পরিষেবা এবং ক্লায়েন্ট উভয়ই স্থানীয় সার্ভারে রয়েছে।

সমাধান হয়েছে: আমি নিজেই উত্তরটির উল্লেখ করার পরে সমস্যার সমাধান করতে পারলাম ।

দেখে মনে হচ্ছে এইচটিটিএপিআরএল সংযোগটি কোনও মানহীন পোর্টের সাথে কোনও ইউআরএলে সংযোগ করার সময় সর্বদা 404 টি প্রতিক্রিয়া দেয়।

এই লাইনগুলি যুক্ত করা এটি সমাধান করেছে

con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
con.setRequestProperty("Accept","*/*");

1
"আমি যখন টার্মিনাল থেকে এই কোডটি কার্যকর করি" - কোন কোড? কী কাজ করছে না কী কাজ করছে তা অস্পষ্ট।
জন স্কিটি

এইচটিপি কার্কেল হ'ল ক্লাসটির নাম যা এই মূল পদ্ধতিতে রয়েছে। এই ক্লাসটি সংকলিত এবং টার্মিনাল থেকে চালিত হয়
নাইকভিন

3
আমি একই সমস্যাটি অনুভব করেছি, তবে এখানকার কোনও সমাধানই কাজ করেনি। আমি অবশেষে বুঝতে পেরেছিলাম যে এটি জাভা 1.7.0_05 এর মধ্যে একটি সমস্যা এবং সর্বশেষতম সংস্করণ 1.7.0_21 এ আপডেট হয়েছে এবং সমস্যাটি চলে গেল। আমি বুঝতে পারলাম জাভা ১.6-এ সমস্যাটি ঘটেনি। এখনও আটকে থাকা কারও জন্য কেবল একটি FYI I
স্টিভেন

বলছি! উত্তরের চেয়ে প্রশ্নে "সমাধান করা" মন্তব্য দেখুন!
김준호

উত্তর:


130

আমি আপনার স্প্রিং / জ্যাকএক্সবি সংমিশ্রণ সম্পর্কে জানি না, তবে গড়ে ওঠা আরএসইটি ওয়েব সার্ভিস পোষ্ট / পুটে কোনও প্রতিক্রিয়া দেবে না, কেবল একটি প্রতিক্রিয়ার স্থিতি । আপনি এটি শরীরের পরিবর্তে নির্ধারণ করতে চাই।

প্রতিস্থাপন করা

InputStream response = con.getInputStream();

দ্বারা

int status = con.getResponseCode();

সমস্ত উপলভ্য স্থিতি কোড এবং তাদের অর্থ পূর্ববর্তী লিঙ্ক হিসাবে এইচটিটিপি স্পেকগুলিতে উপলব্ধ। ওয়েব সার্ভিস নিজেই এমন কিছু ডকুমেন্টেশন সহ উপস্থিত হওয়া উচিত যা ওয়েবসার্চিসমূহ দ্বারা সমর্থিত সমস্ত স্থিতি কোড এবং তাদের বিশেষ অর্থ যদি থাকে তবে ওভারভিউ করে।

যদি স্থিতিটি শুরু হয় 4nnবা 5nn, আপনি getErrorStream()প্রতিক্রিয়া বডিটি পড়ার পরিবর্তে ব্যবহার করতে চান যাতে ত্রুটির বিবরণ থাকতে পারে।

InputStream error = con.getErrorStream();

ঠিক আছে আমি এটি চেষ্টা করেছি এবং এটি 404 স্থিতি ফিরিয়েছে! কিন্তু আশ্চর্যের বিষয়, এটি ডিবিতেও সঞ্চয় করছে! এছাড়াও আপনি যা উল্লেখ করেছেন তা থেকে, এর অর্থ কি কোনও REST পরিষেবা কেবল একটি স্থিতি কোড ফেরত দেবে? পোস্টটি সফল হলে আমি যদি এক্সএমএল বৈধতা ত্রুটি বার্তা বা url এর মতো আরও তথ্য ফিরে আসতে চাই তবে কী হবে?
নাইকোভিন

হ্যাঁ, POST / PUT / ইত্যাদির মতো পরিবর্তনের অনুরোধগুলিতে এটি সাধারণত কোনও দেহ ফেরত দেয় না। আপনি সাধারণত ইনপুট বা ত্রুটি প্রবাহটি পড়ার আগে প্রতিক্রিয়া স্থিতি নির্ধারণ করতে চান। আমি উত্তরে কিছু বিশদ যুক্ত করেছি। তবে যদি এটি সত্যিকারের স্থিতি 404 ফিরে আসে তবে সম্ভবত ওয়েবসার্ভিসে কিছু ত্রুটি রয়েছে। আমি এর রক্ষণাবেক্ষণকারীকে রিপোর্ট করব।
বালুস সি

এক্ষেত্রে পরিষেবাটির রক্ষণাবেক্ষণকারী আমার হয়ে যায়! .. ঠিক আছে আমি পিএইচপি ব্যবহার করে কার্ল করার চেষ্টা করেছি এবং এটি 200 ফেরত আসে (আমার প্রশ্নটি সম্পাদনা করেছে) এছাড়াও getErrorStream()প্রস্তাবিত হিসাবে চেষ্টা করেছি । এটি একটি নালপয়েন্টার এক্সসেপশন অন ছুড়ে দেয় new InputStreamReader(con.getErrorStream())
নাইকোভিন

দুঃখিত, আমি স্প্রিং ওয়েব সার্ভিসগুলির সাথে ফ্যামিলিয়ার নই। আমি কেবল জাএক্স-ডাব্লুএস / আরএসের সাথে স্ট্যান্ডার্ড জাভা ইই 5/6 এপিআইয়ের অভিজ্ঞতা পেয়েছি। আমি এক্সএমএল ফাইল প্রসেসিংয়ের জন্য দায়ী পদ্ধতিটিতে ব্রেকআপপয়েন্ট রাখার পরামর্শ দেব এবং তারপরে সেখান থেকে আরও দূরে যেতে চাই।
বালুসসি

এই আচরণটি খুব অ-দরকারী বলে মনে হচ্ছে, বিশেষত যেহেতু এটি আরও জেনেরিক URLConnectionসমস্যাযুক্ত বিষয়গুলির উল্লেখ করে । আমি ভাবছি কেন জাভা ছেলেরা কেবল এই লাইনের সাথে বাস্তবায়ন করল getInputStream()না । তবে যাই হোক; তথ্যমূলক উত্তর, +1। HttpUrlConnectionreturn responseCode == 200 ? super.getInputStream() : this.getErrorStream()
aroth

51

FileNotFound ওয়েব সার্ভার একটি 404 ফেরত ইঙ্গিত দেওয়ার জন্য ব্যবহৃত হতভাগা ব্যতিক্রম।


1
ওপি কর্তৃক বর্ণিত সারণিতে ডিবিতে কেন সারি যুক্ত হবে তা ব্যাখ্যা করে না।
বালুসসি

@ বালুসসি: যদি না সার্ভারটি একটি সারি যোগ করে এবং তারপরে একটি 404 ফিরিয়ে দেয়
জন স্কিটি

হ্যাঁ মনে হচ্ছে এটি এইভাবে আচরণ করছে। এর মানে কী ?
নাইকিভিন

@নায়েকোভিন: এটি বলা শক্ত, তবে এটি স্থানীয়ভাবে চলছে এমন একটি পরিষেবা, আপনি নিজে এটি ডিবাগ করতে সক্ষম হবেন।
জন স্কিটি

7
এইচটিপিআরএল সংযোগ 403 টি প্রতিক্রিয়া (এবং সম্ভবত অন্যদের) জন্য ফাইলনটফাউন্ডএক্সেপশনও ছুঁড়েছে। (প্রতিক্রিয়া সংস্থাটি খালি না হলেও , মনে হয়)) যাইহোক, getResponseCode()ফোন করার আগে সর্বদা তদন্ত করুন getInputStream()
জোনিক

29

ভবিষ্যতে এই সমস্যার যে কারও কাছেও কারণ হ'ল স্থিতি কোডটি 404 ছিল (বা আমার ক্ষেত্রে এটি ছিল 500)। এটি InpuStreamস্থিতি কোড 200 না হলে ফাংশনটি একটি ত্রুটি ফেলবে বলে মনে হয় ।

আমার ক্ষেত্রে আমি নিজের সার্ভারটি নিয়ন্ত্রণ করি এবং একটি ত্রুটি ঘটেছে তা নির্দেশ করার জন্য একটি 500 স্থিতি কোড ফিরিয়ে দিচ্ছিলাম। আমার ত্রুটির বর্ণনা দিয়ে একটি স্ট্রিং মেসেজ সহ কোনও দেহ প্রেরণ করা সত্ত্বেও, inputstreamদেহ সম্পূর্ণরূপে পঠনযোগ্য না হয়েও একটি ত্রুটি নিক্ষেপ করেছে।

আপনি যদি নিজের সার্ভারটি নিয়ন্ত্রণ করেন তবে আমি মনে করি এটি 200 স্ট্যাটাস কোড প্রেরণ করে এবং তারপরে স্ট্রিং ত্রুটির প্রতিক্রিয়া যা ছিল তা হ্যান্ডল করার মাধ্যমে এটি পরিচালনা করা যেতে পারে।


21
স্পষ্টতই, আপনি কেবল এটি ভুলভাবে পরিচালনা করছেন। আপনার ঠিক আছে কিনা তা যাচাই করার জন্য আপনার কানেকশন.জেট রেসপনস কোড ব্যবহার করা উচিত। তারপরে getInputStream এর পরিবর্তে ত্রুটিযুক্ত বডি পেতে কানেকশন.সেটআরআর স্ট্রিম ব্যবহার করুন। (বা আপনি getResponseMessage ব্যবহার করতে পারেন) আপনার যদি 200 টি স্ট্যাটাস কোডটি ত্রুটিযুক্ত না হয় তবে প্রেরণা হিসাবে HTTP ত্রুটি কোডগুলি ব্যবহার করা উচিত নয়।
rekh127

5

অন্য যে কারও পক্ষে এই হোঁচট খাচ্ছে, এসওএপি সার্ভিসে এসওএপি অনুরোধ শিরোনাম প্রেরণের চেষ্টা করার সময় আমার সাথে একই ঘটনা ঘটেছে। সমস্যাটি কোডটিতে একটি ভুল আদেশ ছিল, আমি এক্সএমএল বডি প্রেরণের আগে প্রথমে ইনপুট স্ট্রিমটির অনুরোধ করেছি। নীচে টুকরো টুকরো কোডে, লাইনটি InputStream in = conn.getInputStream();তত্ক্ষণাত্ এসেছিল ByteArrayOutputStream out = new ByteArrayOutputStream();যার পরে জিনিসগুলির সঠিক ক্রম।

ByteArrayOutputStream out = new ByteArrayOutputStream();
// send SOAP request as part of HTTP body 
byte[] data = request.getHttpBody().getBytes("UTF-8");
conn.getOutputStream().write(data); 

if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
  Log.d(TAG, "http response code is " + conn.getResponseCode());
  return null;
}

InputStream in = conn.getInputStream();

FileNotFound এই ক্ষেত্রে এইচটিটিপি প্রতিক্রিয়া কোড 400 এনকোড করার একটি দুর্ভাগ্যজনক উপায় ছিল।


ফাইলনটফাউন্ডটি ছিল কারণ সংযোগটির কোনও আপ্ট স্ট্রিম নেই। 400 এর এনকোডিং প্রতিক্রিয়া কোডের সাথে এর কোনও সম্পর্ক ছিল না get আপনি getResponseCode () দিয়ে প্রতিক্রিয়া কোডটি পেতে পারেন। তারপরে এটি যদি HTTP_OK না হয় তবে আপনার দেহটি সংযোগ.আরআরস্ট্রস্ট্রিম () দিয়ে পাওয়া উচিত বা রেসপন্সমেজেজ () পাওয়া উচিত
রেখ 127

new ByteArrayOutputStream()এটির সাথে কিছুই করার নেই। ইস্যুটি হল এর মধ্যে getInputStream()এবং হিসাবে আদেশ getResponseCode()
লার্নের মারকুইস

4

এই ক্ষেত্রে ফাইলনটফাউন্ডের অর্থ আপনি আপনার সার্ভার থেকে একটি 404 পেয়েছেন - এটি কি এমন হতে পারে যে সার্ভারটি "পোস্ট" অনুরোধ পছন্দ করে না?


তবে এটি ডিবিতে একটি রেকর্ড সংরক্ষণ করে। Jaxb2Marshaller এখানে সমস্যা হতে পারে?
নাইকোভিন

2
এটি কেবল 404s এর জন্য ঘটে না। এটি খালি শরীরের সাথে কোনও প্রতিক্রিয়ার জন্যও ঘটে।
ডেভ ক্যামেরন 16

3
এই উত্তরটি দুর্ভাগ্যক্রমে ভুল wrong এই পরিস্থিতিতে ফাইলনটফাউন্ডের অর্থ কেবলমাত্র প্রতিক্রিয়া কোড 399 এর উপরে থাকলে এইচটিপিআরএল সংযোগ # getInputStream () বলা হয়েছিল, যখন এই পরিস্থিতিতে HTTPURL সংযোগ # getErrorStream () বলা উচিত ছিল। ওও, সার্ভার যদি পোষ্টগুলি গ্রহণ না করে তবে এটি 405 পদ্ধতি অনুমোদিত নয় returned ফাইল নটফাউন্ডের সাথে কোনও সম্পর্ক নেই।
মিশাল এম

0

সমাধান: আপনি যদি এটি জানতে চান তবে আপনার পিসির আইপির জন্য লোকালহোস্ট
পরিবর্তন করুন : উইন্ডোজ + r> সেমিডি> ipconfig উদাহরণ: HTTP: // 192.168.0.107 /directory/service/program.php?action=send কিছু মাত্র 192.168 প্রতিস্থাপন করুন আপনার নিজের আইপির জন্য .0.107 ( 127.0.0.1 চেষ্টা করবেন না কারণ এটি লোকালহোস্টের সমান )



-4

পরিবর্তন করুন

con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection();

প্রতি

con = (HttpURLConnection) new URL("http://YOUR_IP:8080/myapp/service/generate").openConnection();

2
এটা পরিবর্তন কেন? ওপি স্পষ্টভাবে জানিয়েছে যে স্থানীয়ভাবে পরিষেবাটি চলছে।
লার্নের মারকুইস

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