HTTPServletResponse.getOutputStream () /। GetWriter () এ কি কেউ কল করা () কল করতে হবে?


96

জাভা সার্লেলেটগুলিতে, কেউ response.getOutputStream()বা এর মাধ্যমে প্রতিক্রিয়ার বডিটি অ্যাক্সেস করতে পারে response.getWriter()। এটি লিখিত হওয়ার পরে কেউ কি .close()এই কল OutputStreamকরতে হবে?

একদিকে, সর্বদা বন্ধ রাখার জন্য ব্লুচিয়ানদের উপদেশ রয়েছে OutputStream। অন্যদিকে, আমি মনে করি না যে এই ক্ষেত্রে কোনও অন্তর্নিহিত সংস্থান আছে যা বন্ধ করা দরকার। অবিচ্ছিন্ন সংযোগ এবং এর মতো জিনিসের মঞ্জুরি দেওয়ার জন্য, সকেটগুলির খোলার / সমাপনি এইচটিটিপি স্তরে পরিচালিত হয়।


এখানে কোনও অন্তর্নিহিত সংস্থান বন্ধ আছে কিনা তা অনুমান করার জন্য আপনাকে আমন্ত্রণ করা হয়নি। যদি বাস্তবায়নকারী এটি মনে করে বা বরং এটি জানে তবে তিনি close()এমন একটি সরবরাহ করবেন যা কিছুই করে না। কি আপনি কি করা উচিত ঘনিষ্ঠ যে closeable সম্পদ।
লার্নের মারকুইস

4
এমনকি যদি আপনার কোডটি এটি না খোলেন? আমি এরকম মনে করি না ...
স্টিভেন হুইগ

উত্তর:


93

সাধারণত আপনার স্ট্রিমটি বন্ধ করা উচিত নয়। সার্লেট অনুরোধ লাইফ-চক্রের অংশ হিসাবে সার্লেটটি চলমান শেষ হওয়ার পরে সার্লেট পাত্রে স্বয়ংক্রিয়ভাবে স্ট্রিমটি বন্ধ হয়ে যাবে।

উদাহরণস্বরূপ, আপনি যদি স্ট্রিমটি বন্ধ করে থাকেন তবে আপনি যদি কোনও ফিল্টার প্রয়োগ করেন তবে এটি উপলব্ধ হবে না ।

সমস্ত কিছু বলার পরেও, আপনি যদি এটি বন্ধ করেন তবে যতক্ষণ আপনি আবার এটি ব্যবহার করার চেষ্টা করবেন না ততক্ষণ খারাপ কিছুই ঘটবে না।

সম্পাদনা: অন্য ফিল্টার লিঙ্ক

EDIT2: অ্যাড্রিয়ান.টারাউ ঠিক আছে যে আপনি সার্লেলেটটি কাজটি করার পরে প্রতিক্রিয়া পরিবর্তন করতে চান আপনার এইচটিপিএস সার্লেটরেসপোনসরেপার প্রসারিত একটি মোড়ক তৈরি করা উচিত এবং আউটপুট বাফার হবে। এটি আউটপুটটিকে সরাসরি ক্লায়েন্টের কাছে যেতে না দেয় তবে সার্লেটটি স্ট্রিমটি বন্ধ করে দিলে সুরক্ষিত করতে দেয়, এই উদ্ধৃতি (জোর খনি):

একটি ফিল্টার যা প্রতিক্রিয়া সংশোধন করে তা ক্লায়েন্টকে ফেরত দেওয়ার আগে সাধারণত প্রতিক্রিয়াটি ক্যাপচার করতে হয়। এটি করার উপায় হ'ল সার্লেটটি যা উত্তরের স্ট্রিম প্রতিক্রিয়া জেনারেট করে। স্ট্যান্ড-ইন স্ট্রিমটি পরিপূরকটি মূল প্রতিক্রিয়ার স্ট্রিমটি বন্ধ করার থেকে বাধা দেয় যখন এটি সম্পূর্ণ হয় এবং ফিল্টারটিকে সার্লেটের প্রতিক্রিয়া পরিবর্তন করতে দেয়।

নিবন্ধ

যে কোনও আনুষ্ঠানিক সূর্যের নিবন্ধটি থেকে অনুমান করা যায় যে OutputStreamকোনও সার্লেট থেকে বন্ধ করা এমন একটি বিষয় যা একটি সাধারণ ঘটনা, তবে এটি বাধ্যতামূলক নয়।


4
এটা সঠিক। একটি বিষয় লক্ষণীয় হ'ল কিছু ক্ষেত্রে আপনার প্রবাহটি প্রবাহিত করার প্রয়োজন হতে পারে এবং এটি পুরোপুরি অনুমোদিত।
টোলুজু

4
লেখককে বন্ধ করার আরও একটি পার্শ্ব প্রতিক্রিয়া রয়েছে। আপনি প্রতিক্রিয়া.সেট স্ট্যাটাসটি বন্ধ হয়ে যাওয়ার পরেও স্থিতি কোডটি সেট করতে সক্ষম হবেন না।
চে জাভারা

4
এই পরামর্শ অনুসরণ করুন। এটি আপনার প্রচুর ব্যথা বাঁচাবে। আপনি কেন এটি করছেন তা আপনি যদি না জানেন তবে আমি (()) ফ্লাশ করব না - আপনার পাত্রে হ্যান্ডেলটি বাফারিং করা উচিত।
Hal50000

76

তাদের সাধারণ নিয়মটি হ'ল: আপনি যদি স্ট্রিমটি খোলেন তবে আপনার এটি বন্ধ করা উচিত। আপনি না, আপনি করা উচিত নয়। কোডটি প্রতিসম হয় কিনা তা নিশ্চিত করুন।

এর ক্ষেত্রে HttpServletResponseএটি কিছুটা কম পরিষ্কার কাটা, যেহেতু কলিংটি getOutputStream()এমন একটি অপারেশন যা প্রবাহ খোলায় তা স্পষ্ট নয় । জাভাদোক কেবল বলেছেন যে এটি " Returns a ServletOutputStream"; একইভাবে জন্য getWriter()। যেভাবেই হোক, যা পরিষ্কার তা হল HttpServletResponseস্ট্রিম / লেখকের "মালিকানা" রয়েছে এবং এটি (বা ধারক) এটি আবার বন্ধ করার জন্য দায়ী।

সুতরাং আপনার প্রশ্নের উত্তর দেওয়ার জন্য - না, এই ক্ষেত্রে আপনার স্ট্রিমটি বন্ধ করা উচিত নয়। ধারকটিকে অবশ্যই এটি করতে হবে এবং আপনি যদি এটির আগে সেখানে প্রবেশ করেন তবে আপনার অ্যাপ্লিকেশনটিতে সূক্ষ্ম বাগগুলি প্রবর্তনের ঝুঁকি রয়েছে।


আমি এই উত্তরের সাথে একমত, আপনি সার্ভলেটরেস্পোনস.ফ্লুশ বাফার () দেখুনও
সাইবার-সন্ন্যাসী

14
"আপনি যদি স্ট্রিমটি খোলেন, তবে আপনার এটি বন্ধ করা উচিত
you

4
এটা তোলে বাক্য স্কুল বোর্ড পোস্ট মত আর "যদি আপনি এটি এটি খোলার, বন্ধ আপনি এটি চালু এটিকে চালু বন্ধ এটিকে আনলক পারেন, এটি লক আপ [...]।।।"
রিকার্ডো

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

"আপনি যদি স্ট্রিমটি খোলেন, তবে আপনার এটি বন্ধ করা উচিত If আপনি যদি না করেন তবে আপনার উচিত হবে না sure কোডটি প্রতিসম্মত কিনা তা নিশ্চিত করুন" " - তাহলে আপনি যদি অন্য স্ট্রিম তৈরি করেন যা এই স্ট্রিমটি জড়ো করে? বাহ্যিক স্ট্রিমের কাছাকাছি কল করা সাধারণত নেস্টেডটিকে বন্ধ করে দেবে বলে এই ক্ষেত্রে প্রতিসাম্যপূর্ণ থাকা শক্ত।
স্টিনিবোট

5

যদি কোনও সম্ভাবনা থাকে তবে ফিল্টারটিকে একটি 'অন্তর্ভুক্ত' রিসোর্সে কল করা যেতে পারে, আপনার অবশ্যই স্ট্রিমটি বন্ধ করা উচিত নয় । এটি সহ 'সংস্থান বন্ধ' ব্যতিক্রম সহ সংস্থানগুলি ব্যর্থ করে দেবে।


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

4

আপনার স্ট্রিমটি বন্ধ করা উচিত, যেহেতু আপনি getOutputStream () কে আহ্বান করেন এবং কোডটি পরিষ্কার থাকে এবং প্যারামিটার হিসাবে স্ট্রিমটি আপনাকে দেওয়া হয় না, যখন আপনি সাধারণত এটি ব্যবহার করেন এবং এটি বন্ধ করার চেষ্টা করবেন না। সার্ভলেট এপিআই তে উল্লেখ করে না যে যদি আউটপুট স্ট্রিমটি বন্ধ করা যায় বা বন্ধ না করা যায়, এই ক্ষেত্রে আপনি নিরাপদে স্ট্রিমটি বন্ধ করতে পারেন, সেখানকার যে কোনও পাত্রে স্ট্রোলেটটি বন্ধ না করা থাকলে স্ট্রিমটি বন্ধ করার যত্ন নেওয়া হয়।

এখানে জেটির কাছাকাছি () পদ্ধতিটি রয়েছে, তারা স্ট্রিমটি বন্ধ না করলে বন্ধ করে দেয়।

public void close() throws IOException
    {
        if (_closed)
            return;

        if (!isIncluding() && !_generator.isCommitted())
            commitResponse(HttpGenerator.LAST);
        else
            flushResponse();

        super.close();
    }

ফিল্টারটির বিকাশকারী হিসাবে আপনি ধরেও নিবেন না যে আউটপুট স্ট্রিম বন্ধ নেই, সার্ভলেটের কাজ শেষ করার পরে আপনি যদি সামগ্রীটি পরিবর্তন করতে চান তবে আপনাকে সর্বদা অন্য একটি আউটপুট স্ট্রিম পাস করতে হবে।

সম্পাদনা: আমি সর্বদা স্রোতটি বন্ধ করে দিই এবং টমক্যাট / জেটি নিয়ে আমার কোনও সমস্যা হয়নি। পুরানো বা নতুন কোনও ধারক নিয়ে আপনার কোনও সমস্যা হওয়া উচিত বলে আমি মনে করি না।


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

4
হ্যাঁ, তবে সৌন্দর্য পরে আসে :) যাইহোক, যেহেতু এপিআই স্পষ্ট নয় আমি কোডটি বন্ধ রাখতে পছন্দ করব, কোডটি সামঞ্জস্যপূর্ণ দেখায়, একবার আপনি আউটপুট স্ট্রিমের জন্য অনুরোধ করলে আপনার এপিআই বন্ধ না করা উচিত যদি না "এটিকে বন্ধ না করেন"।
অ্যাড্রিয়ান.তারাউ

আমার নিজের কোডে আউটপুট স্ট্রিম বন্ধ করা একটি ভাল অনুশীলন বলে আমি মনে করি না। এটাই পাত্রে কাজ।
জিমহকিন্স

পান * স্ট্রিম তৈরি করে না, এটি প্রযোজক নয়। আপনি এটি বন্ধ করা উচিত নয়, ধারক এটি করা উচিত।
দমেজ

3

বন্ধ করার বিরুদ্ধে আরেকটি যুক্তি OutputStream। এই সার্লেটটি দেখুন। এটি একটি ব্যতিক্রম ছোঁড়ে। ব্যতিক্রমটি একটি ত্রুটি জেএসপি-তে ওয়েব.এক্সএমএল এ ম্যাপ করা হয়েছে:

package ser;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

@WebServlet(name = "Erroneous", urlPatterns = {"/Erroneous"})
public class Erroneous extends HttpServlet {

  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html;charset=UTF-8");
    PrintWriter out = resp.getWriter();
    try {
      throw new IOException("An error");
    } finally {
//      out.close();
    }
  }
}

ওয়েব.এক্সএমএল ফাইলটিতে রয়েছে:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <error-page>
        <exception-type>java.io.IOException</exception-type>
        <location>/error.jsp</location>
    </error-page>
</web-app>

এবং ত্রুটি.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Error Page</title>
    </head>
    <body>
        <h1><%= exception.getMessage()%></h1>
    </body>
</html>

আপনি /Erroneousব্রাউজারে লোড করার সময় আপনি "একটি ত্রুটি" প্রদর্শিত ত্রুটি পৃষ্ঠাটি দেখতে পাবেন। তবে আপনি যদি out.close()উপরের সার্লেলে লাইনটি অন-মন্তব্য করেন তবে পুনরায় অ্যাপ্লিকেশনটি পুনরায় লোড করুন /Erroneousএবং ব্রাউজারে আপনি কিছুই দেখতে পাবেন না। আসলে কী হচ্ছে সে সম্পর্কে আমার কোনও ধারণা নেই, তবে আমি অনুমান করি যে out.close()ত্রুটি পরিচালনা করা বাধা দেয়।

টমক্যাট 7.0.50, জাভা EE 6 নেটবিনস 7.4 ব্যবহার করে পরীক্ষিত।

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