java.lang.IllegalStateException: প্রতিক্রিয়া প্রতিশ্রুতিবদ্ধ হওয়ার পরে (ফরওয়ার্ড | sendRedirect | সেশন তৈরি করুন) করা যায় না


96

এই পদ্ধতিটি ছুড়ে ফেলে

java.lang.IllegalStateException: প্রতিক্রিয়া প্রতিশ্রুতিবদ্ধ হওয়ার পরে ফরওয়ার্ড করা যায় না

এবং আমি সমস্যাটি চিহ্নিত করতে অক্ষম। কোন সাহায্য?

    int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
    String chkboxVal = "";
    // String FormatId=null;
    Vector vRow = new Vector();
    Vector vRow1 = new Vector();
    String GroupId = "";
    String GroupDesc = "";
    for (int i = 0; i < noOfRows; i++) {
        if ((request.getParameter("chk_select" + i)) == null) {
            chkboxVal = "notticked";
        } else {
            chkboxVal = request.getParameter("chk_select" + i);
            if (chkboxVal.equals("ticked")) {
                fwdurl = "true";
                Statement st1 = con.createStatement();
                GroupId = request.getParameter("GroupId" + i);
                GroupDesc = request.getParameter("GroupDesc" + i);
                ResultSet rs1 = st1
                        .executeQuery("select FileId,Description from cs2k_Files "
                                + " where FileId like 'M%' and co_code = "
                                + ccode);
                ResultSetMetaData rsm = rs1.getMetaData();
                int cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol1 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol1.addElement(rs1.getObject(j));
                    }
                    vRow.addElement(vCol1);
                }
                rs1 = st1
                        .executeQuery("select FileId,NotAllowed from cs2kGroupSub "
                                + " where FileId like 'M%' and GroupId = '"
                                + GroupId + "'" + " and co_code = " + ccode);
                rsm = rs1.getMetaData();
                cCount = rsm.getColumnCount();

                while (rs1.next()) {
                    Vector vCol2 = new Vector();
                    for (int j = 1; j <= cCount; j++) {
                        vCol2.addElement(rs1.getObject(j));
                    }
                    vRow1.addElement(vCol2);
                }

                // throw new Exception("test");

                break;
            }
        }
    }
    if (fwdurl.equals("true")) {
        // throw new Exception("test");
        // response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
        request.setAttribute("GroupId", GroupId);
        request.setAttribute("GroupDesc", GroupDesc);
        request.setAttribute("vRow", vRow);
        request.setAttribute("vRow1", vRow1);
        getServletConfig().getServletContext().getRequestDispatcher(
                "/GroupCopiedUpdt.jsp").forward(request, response);
    }

4
এটি দেখতে দেখতে এটি কঠিন, তবে মনে হচ্ছে আপনি ইতিমধ্যে আপনার ফরোয়ার্ডের আগে কিছু আউটপুট প্রেরণ করেছেন। আপনি কি দয়া করে পুরো কোডটি মুদ্রণ করতে পারেন এবং আপনার যদি কোনও ফিল্টার জায়গা নেই কিনা তা পরীক্ষা করতে পারেন?
কার্তোচ

উত্তর:


245

আরম্ভকারীদের মধ্যে একটি সাধারণ ভুল বোঝাবুঝি হ'ল তারা মনে করেন যে forward(), এ sendRedirect(), বা sendError()যাদুকরভাবে প্রস্থান করে এবং পদ্ধতিটি থেকে "লাফিয়ে" বেরিয়ে আসবে, ফলে কোডের অবশিষ্টাংশকে উপেক্ষা করে। উদাহরণ স্বরূপ:

protected void doXxx() {
    if (someCondition) {
        sendRedirect();
    }
    forward(); // This is STILL invoked when someCondition is true!
}

এটি আসলে সত্য নয়। তারা অবশ্যই অন্য যে কোনও জাভা পদ্ধতির চেয়ে অবশ্যই আলাদা আচরণ করবে না ( System#exit()অবশ্যই প্রত্যাশা )। যখন someConditionউপরের উদাহরণটি হ'ল trueএবং আপনি একই অনুরোধ / প্রতিক্রিয়াটির forward()পরে sendRedirect()বা তারপরে কল করছেন sendError(), তখন সুযোগটি বড় যে আপনি ব্যতিক্রম পাবেন:

java.lang.IllegalStateException: প্রতিক্রিয়া প্রতিশ্রুতিবদ্ধ হওয়ার পরে ফরওয়ার্ড করা যায় না

যদি ifবিবৃতিটি একটি কল করে forward()এবং আপনি পরে কল করে sendRedirect()বা sendError(), তবে নীচে ব্যতিক্রম নিক্ষেপ করা হবে:

java.lang.IllegalStateException: প্রতিক্রিয়া প্রতিশ্রুতিবদ্ধ হওয়ার পরে সেন্ডআরডাইরেক্ট () কল করতে পারবেন না

এটি ঠিক করার জন্য আপনার return;পরে বিবৃতি যুক্ত করতে হবে

protected void doXxx() {
    if (someCondition) {
        sendRedirect();
        return;
    }
    forward();
}

... বা অন্য একটি ব্লক চালু করতে।

protected void doXxx() {
    if (someCondition) {
        sendRedirect();
    } else {
        forward();
    }
}

আপনার কোডে মূল কারণ naildown করার জন্য, শুধু যা কলের জন্য কোন লাইন অনুসন্ধান forward(), sendRedirect()বা sendError()পদ্ধতি ব্লক থেকে প্রস্থান বা কোড অবশেষ কুঁদন ছাড়া। এটি নির্দিষ্ট কোড লাইনের আগে একই সার্লেটের ভিতরে থাকতে পারে তবে কোনও সার্লেট বা ফিল্টারেও যা নির্দিষ্ট সার্লেটের আগে ডাকা হত।

ক্ষেত্রে sendError(), যদি আপনার একমাত্র উদ্দেশ্য প্রতিক্রিয়া স্থিতি নির্ধারণ করা হয় তবে setStatus()পরিবর্তে ব্যবহার করুন।


আর একটি সম্ভাব্য কারণ হ'ল সার্ভলেট প্রতিক্রিয়ার জন্য লিখে যখন একটি forward()ডাকা হবে, বা একে একে একই পদ্ধতিতে ডাকা হয়েছিল।

protected void doXxx() {
    out.write("some string");
    // ... 
    forward(); // Fail!
}

প্রতিক্রিয়া বাফার আকারটি বেশিরভাগ সার্ভারে 2KB এ ডিফল্ট হয়, সুতরাং আপনি যদি এটিতে 2KB এর বেশি লিখে থাকেন তবে তা প্রতিশ্রুতিবদ্ধ forward()হবে এবং একইভাবে ব্যর্থ হবে:

java.lang.IllegalStateException: প্রতিক্রিয়া প্রতিশ্রুতিবদ্ধ হওয়ার পরে ফরওয়ার্ড করা যায় না

সমাধান সুস্পষ্ট, কেবল সার্লেলে প্রতিক্রিয়া লিখবেন না। এটাই জাস্পের দায়িত্ব। আপনি ঠিক request.setAttribute("data", "some string")তেমন অনুরোধের একটি বৈশিষ্ট্য সেট করেছেন এবং তারপরে এটি জেএসপিতে মুদ্রণ করুন ${data}সার্ভলেটগুলি কীভাবে সঠিকভাবে ব্যবহার করতে হয় তা শিখতে আমাদের সার্লেটস উইকি পৃষ্ঠাটিও দেখুন ।


আর একটি সম্ভাব্য কারণ হ'ল সার্ভলেট প্রতিক্রিয়ার জন্য একটি ফাইল ডাউনলোড লেখেন যার পরে যেমন একটি forward()বলা হয়।

protected void doXxx() {
    out.write(bytes);
    // ... 
    forward(); // Fail!
}

এটি প্রযুক্তিগতভাবে সম্ভব নয়। আপনার forward()কলটি সরিয়ে ফেলতে হবে। এন্ডুয়েসারটি বর্তমানে খোলা পৃষ্ঠায় থাকবে। আপনি যদি ফাইল ডাউনলোডের পরে পৃষ্ঠাটি পরিবর্তন করতে চান তবে আপনার অবশ্যই ফাইল ডাউনলোডের যুক্তিটি লক্ষ্য পৃষ্ঠার পৃষ্ঠা লোডে স্থানান্তর করতে হবে।


তবুও আরেকটি সম্ভাব্য কারণ হ'ল forward(), sendRedirect()বা sendError()পদ্ধতিগুলি জাভা কোডের মাধ্যমে পুরানো ফ্যাশন পদ্ধতিতে একটি জেএসপি ফাইলে এম্বেড করা হয়েছে <% scriptlets %>, এটি একটি অভ্যাস যা ২০০১ সাল থেকে আনুষ্ঠানিকভাবে নিরুৎসাহিত হয়েছিল । উদাহরণ স্বরূপ:

<!DOCTYPE html>
<html lang="en">
    <head>
        ... 
    </head>
    <body>
        ...

        <% sendRedirect(); %>
        
        ...
    </body>
</html>

এখানে সমস্যাটি হ'ল জেএসপি অভ্যন্তরীণভাবে out.write("<!DOCTYPE html> ... etc ...")এটির সাথে সাথেই টেমপ্লেট পাঠ্য (অর্থাৎ এইচটিএমএল কোড) লিখে দেয় । এটি পূর্ববর্তী বিভাগে বর্ণিত হিসাবে একইভাবে মূলত একই সমস্যা।

সমাধানটি সুস্পষ্ট, কেবল একটি জেএসপি ফাইলে জাভা কোডটি লিখবেন না। এটি একটি সাধারণ জাভা শ্রেণীর যেমন সার্ভলেট বা ফিল্টার হিসাবে দায়িত্ব। সার্ভলেটগুলি কীভাবে সঠিকভাবে ব্যবহার করতে হয় তা শিখতে আমাদের সার্লেটস উইকি পৃষ্ঠাটিও দেখুন ।


আরো দেখুন:


অসম্পর্কিত আপনার কংক্রিট সমস্যা, আপনার JDBC- কোড সম্পদ লিক করছে। এটিও ঠিক করুন। ইঙ্গিতগুলির জন্য, আরও দেখুন কীভাবে সংযোগ, বিবৃতি এবং ফলাফলসেটটি জেডিবিসিতে বন্ধ করা উচিত?


4
বিরতি দিয়ে মানে break;? এর অর্থ হ'ল কোডটি কোনও কোনও forবা whileলুপের ভিতরে ছিল যেখানে লুপ forward()চলাকালীন বার বার ডাকা হত (যা এইভাবে ভুল, লুপের পরে একবার আপনাকে অবশ্যই ফোন করা উচিত - অথবা লুপটি পরিত্রাণের জন্য সম্ভবত এটি প্রয়োজন হয়নি) ।
বালুসসি

@ বালুসসি এই সম্পর্কিত সমস্যা সম্পর্কে আপনার কি ধারণা আছে? stackoverflow.com/questions/18658021/...
confile

@ কনফিলে: আমি গ্রিল করি না, তবে কল স্ট্যাকের ভিত্তিতে এটি এখনও forward()কল করছে যখন এটি করা উচিত নয়। জেএসএফ, যার সাথে আমি পরিচিত, এটিও যদি আপনি স্পষ্টভাবে কল না করেন তবে তা করে FacesContext#responseComplete()। এই সম্পর্কিত প্রশ্ন সহায়ক হতে পারে (যা আমি কীওয়ার্ড ব্যবহার করে "grails প্রতিক্রিয়া রেন্ডার প্রতিরোধ" খুঁজে): stackoverflow.com/questions/5708654/...
BalusC

@ বালুস সি গ্রিলস মূলত জাভা, তবে সমস্যাটি সার্লেটগুলির সাথে সম্পর্কিত। আমি কি করতে পারি আপনার কি অন্য কোনও ধারণা আছে? প্রতিটি রেন্ডারের পরে আমি একটি রিটার্ন রাখি, আপনার পরামর্শ অনুসারে পুনঃনির্দেশ এবং এগিয়ে।
বিভক্ত

@ কনফিলে: আমি জানি আমি ইতিমধ্যে কারণটির উত্তর দিয়েছি: গ্রেইস এখনও forward()কল করছে যখন এটি করা উচিত নয়। সমাধান কার্যকরীভাবে সুস্পষ্ট: এটি না করতে বলুন। এটির কোনও ধারণা ছিল না যে আপনি গ্রিলসকে যে কাজটি করার কথা ছিল তা আপনি প্রোগ্রামের ভিত্তিতে গ্রহণ করেছেন: প্রতিক্রিয়াটি পরিচালনা করছেন। টেকনিক্যালি, গ্রিলসকে কীভাবে বলতে হয় তা আমার কোনও ধারণা নেই। তবে আমি জানি যে আরও অনেক এমভিসি ফ্রেমওয়ার্কগুলি এটি সমর্থন করে (নিজে থেকে প্রতিক্রিয়াটি পরিচালনা না করার জন্য নির্দেশ দেওয়া হচ্ছে), যেমন জেএসএফ, স্প্রিং এমভিসি, উইকেট ইত্যাদি I'd
বালুসসি

19

এমনকি কোনও রিটার্নের বিবৃতি যুক্ত করাও এই ব্যতিক্রমটি নিয়ে আসে, যার জন্য এই কোডটিই কেবল তার সমাধান:

if(!response.isCommitted())
// Place another redirection

6

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

সম্পাদনা করুন : সমস্যাটি সনাক্তকরণে আরও কিছু সহায়তা…

এই সমস্যাটি নির্ণয়ের প্রথম পদক্ষেপটি ব্যতিক্রমটি ঠিক কোথায় ছুঁড়েছে তা নির্ধারণ করা। আমরা ধরে নিচ্ছি যে এটি লাইন দিয়ে নিক্ষেপ করা হচ্ছে

getServletConfig().getServletContext()
                  .getRequestDispatcher("/GroupCopiedUpdt.jsp")
                  .forward(request, response);

তবে আপনি দেখতে পাবেন যে এটি কোডের পরে নিক্ষেপ করা হচ্ছে, যেখানে আপনি এগিয়ে যাওয়ার চেষ্টা করার পরে আউটপুট স্ট্রিমে আউটপুট দেওয়ার চেষ্টা করছেন। যদি এটি উপরের লাইনটি থেকে আসে তবে এর অর্থ হ'ল এই লাইনের আগে কোথাও আপনার রয়েছে:

  1. আউটপুট স্ট্রিমে আউটপুট ডেটা, বা
  2. আগেই অন্য একটি পুনর্নির্দেশ কাজ করেছে।

শুভকামনা!


2

এটি হ'ল কারণ আপনার সার্লেটটি একটি অনুরোধ অবজেক্টটি অ্যাক্সেস করার চেষ্টা করছে যা আর নেই .. এটি অন্য জাভা পদ্ধতির মতোই মেথড ব্লক বা প্রথম রিটার্ন স্টেটমেন্টের শেষ অবধি অবিরত থাকে।

এই সমস্যাটি সমাধানের সর্বোত্তম উপায়টি আপনার যুক্তি অনুসারে কেবল পৃষ্ঠাটি সেট করুন (যেখানে আপনি অনুরোধটি ফরোয়ার্ড করার জন্য মনে করেন) গতিশীল। এটাই:

protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
 returnPage="page1.jsp";
}
if(condition2){
   returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}

এবং শেষ লাইনে একবার একবার ফরওয়ার্ড করুন ...

আপনি প্রতিটি ফরওয়ার্ডের পরে রিটার্ন স্টেটমেন্ট ব্যবহার করে এই সমস্যাটিও ঠিক করতে পারেন (অথবা) ...


2

আমি মুছেছি

        super.service(req, res);

তারপরে এটি আমার পক্ষে ভাল কাজ করেছে


2

ধাক্কা ...

আমি ঠিক একই ত্রুটি ছিল। আমি লক্ষ্য করেছি যে আমি পদ্ধতিটি super.doPost(request, response);ওভাররাইড করার doPost()পাশাপাশি সুপারক্লাস নির্মাণকারীকে স্পষ্টতই অনুরোধ করছি

    public ScheduleServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

যত তাড়াতাড়ি আমি বিবৃতিটি super.doPost(request, response);ভিতর থেকে মন্তব্য করার সাথে সাথে doPost()এটি পুরোপুরি কার্যকর হয়েছিল ...

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //super.doPost(request, response);
        // More code here...

}

বলা বাহুল্য, আমার super()সেরা অভ্যাসগুলি পুনরায় পড়তে হবে : পি


1

আপনি ফরোয়ার্ড ফরোয়ার্ড বা পুনঃনির্দেশের সময় ফিরতি বিবৃতি যুক্ত করতে হবে।

উদাহরণ:

যদি ফরওয়ার্ড,

    request.getRequestDispatcher("/abs.jsp").forward(request, response);
    return;

যদি পুনঃনির্দেশিত হয়,

    response.sendRedirect(roundTripURI);
    return;

0

ফরোয়ার্ড ফরোয়ার্ড পদ্ধতির পরে আপনি কেবল এটি করতে পারেন:

return null;

এটি বর্তমান সুযোগটি ভেঙে দেবে।

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