কেবল জাভা এসই এপিআই ব্যবহার করে জাভাতে সাধারণ এইচটিটিপি সার্ভার


333

এইচটিটিপি অনুরোধগুলিকে ম্যানুয়ালি পার্স করতে এবং HTTP প্রতিক্রিয়াগুলিকে ম্যানুয়ালি ফর্ম্যাট করতে কোড না লিখে জাভাতে খুব বেসিক এইচটিটিপি সার্ভার (কেবলমাত্র জিইটি / পোষ্টকে সমর্থন করে) তৈরি করার কোনও উপায় আছে? জাভা এসই এপিআই এইচটিপিটিএল সংযোগে এইচটিটিপি ক্লায়েন্টের কার্যকারিতা সুন্দরভাবে সংযুক্ত করে, তবে কি এইচটিটিপি সার্ভারের কার্যকারিতাটির জন্য কোনও অ্যানালগ রয়েছে?

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

ম্যানুয়াল এইচটিটিপি হেরফেরের উদাহরণ হিসাবে যা আমি এড়াতে চাইছি:

http://java.sun.com/developer/technicalArticles/Networking/Webserver/WebServercode.html


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

3
আমি জানি যে এটি এসও এর চেতনায় নেই, তবে আমি আপনাকে জাভা EE API এর জন্য আলাদাভাবে পুনর্বিবেচনা করার জন্য অনুরোধ করব। উত্তরগুলির মধ্যে যেমন উল্লেখ করা হয়েছে, জেটির মতো কিছু খুব সরাসরি-বাস্তবায়ন বাস্তবায়ন রয়েছে যা সার্ভলেট এপিআইয়ের সুযোগ গ্রহণের পরেও আপনাকে আপনার স্ট্যান্ড-একল অ্যাপ্লিকেশনটিতে একটি ওয়েব সার্ভার এম্বেড করার অনুমতি দেয়। আপনি যদি কোনও কারণে জাভা ইই এপিআই ব্যবহার করতে না পারেন তবে দয়া করে আমার মন্তব্যটিকে উপেক্ষা করুন :-)
ক্রিস থম্পসন

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

1
কোনও সিদ্ধান্ত নেওয়ার আগে এইচটিপি সার্ভারের এই তালিকাটি দিয়ে যাওয়া মূল্যবান হতে পারে। java-source.net/open-source/web-servers
হুমকি

উত্তর:


469

জাভা এসই 6 এর পর থেকে, সান ওরাকল জেআরই-তে একটি বিল্টিন এইচটিটিপি সার্ভার রয়েছে । com.sun.net.httpserverপ্যাকেজ সারসংক্ষেপ জড়িত শ্রেণীর রূপরেখা এবং উদাহরণ রয়েছে।

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

package com.stackoverflow.q3732109;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class Test {

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/test", new MyHandler());
        server.setExecutor(null); // creates a default executor
        server.start();
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "This is the response";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }

}

লক্ষণীয় হওয়া উচিত যে response.length()তাদের উদাহরণের অংশটি খারাপ, এটি হওয়া উচিত ছিল response.getBytes().length। তারপরেও, getBytes()পদ্ধতিটি অবশ্যই অবশ্যই চরসেটটি নির্দিষ্ট করতে হবে যা আপনি তারপরে প্রতিক্রিয়া শিরোনামে উল্লেখ করেছেন। হায় আফসোস, গোড়াপত্তনকারীদের গোমরাহ করা সত্ত্বেও, এটি সর্বোপরি একটি প্রাথমিক কিক অফের উদাহরণ।

এটি সম্পাদন করুন এবং HTTP: // লোকালহোস্ট: 8000 / পরীক্ষায় যান এবং আপনি নিম্নলিখিত প্রতিক্রিয়া দেখতে পাবেন:

এই প্রতিক্রিয়া


com.sun.*ক্লাসগুলি ব্যবহার করার ক্ষেত্রে , এটি লক্ষ্য করুন যে এটি কিছু বিকাশকারীদের যা মনে করেন তার বিপরীতে, পরিচিত FAQ দ্বারা একেবারেই নিষিদ্ধ নয় কেন বিকাশকারীরা 'সূর্য' প্যাকেজগুলি কল করে এমন প্রোগ্রামগুলি লিখবেন না কেন । ওএফএইএল sun.*প্যাকেজটিকে নয় (যেমন sun.misc.BASE64Encoder) ওরাকল জেআরই দ্বারা অভ্যন্তরীণ ব্যবহারের জন্য (যেমন আপনার অ্যাপ্লিকেশনটিকে কোনও অন্য জেআরইতে চালিত করার সময় মেরে ফেলবে), com.sun.*প্যাকেজটিকে নয় concerns সান / ওরাকল এছাড়াও জাভা এসই এপিআই এর উপরে নিজের মতো করে অন্যান্য অ্যাপ্লিকেশন যেমন অ্যাপাচি ইত্যাদির মতো সফ্টওয়্যার বিকাশ করে। com.sun.*ক্লাস ব্যবহার কেবল নিরুৎসাহিত করা হয় (তবে নিষিদ্ধ নয়) যখন এটি কোনও নির্দিষ্ট জাভা এপিআই, যেমন গ্লাসফিশ (জাভা ইই ইমপ্লিট), মোজাররা (জেএসএফ ইমপ্লিট), জার্সি (জ্যাকস-আরএস ইমপ্লিট) ইত্যাদির বাস্তবায়নের বিষয়ে উদ্বেগ প্রকাশ করে concerns


19
@ ওয়ালধেঞ্জ: যেমন @ সফটওয়্যার আপনি বিভ্রান্ত sun.*করছেন com.sun.*। উদাহরণস্বরূপ, আপনি কি sun.*এপিআইয়ের কোনও ডকুমেন্টেশন দেখতে পাচ্ছেন ? এখানে দেখুন: java.sun.com/products/jdk/faq/faq-sun-packages.html এটি সম্পর্কে কি কিছু জানায় com.sun.*? এটি কেবল com.sun.*তাদের নিজস্ব পাবলিক সফ্টওয়্যার জন্য ব্যবহার করা হয়েছে যা জাভা এপিআই-র অংশ নয়। তারা অন্যান্য সংস্থাগুলির মতো জাভা এপিআই-র শীর্ষে সফ্টওয়্যারও বিকাশ করে।
বালাসসি

4
আমি মনে করি এটি ইন্টিগ্রেশন পরীক্ষার ক্ষেত্রে ব্যবহার করার জন্য এটি খুব সুন্দর একটি HTTP সার্ভার। ইঙ্গিত জন্য ধন্যবাদ!
আন্দ্রেয় পিটারসন

13
আপনি অন্ধকার ব্যবহার করে এবং মত কোনো ত্রুটির সম্মুখীন হয়েছেন থাকেন "অ্যাক্সেস সীমাবদ্ধতা: টাইপ HttpExchange প্রয়োজনীয় গ্রন্থাগার উপর বিধিনিষেধ অ্যাক্সেসযোগ্য কারণে না ...", stackoverflow.com/a/10642163 বলে যে অ্যাক্সেস পরীক্ষা নিষ্ক্রিয় করতে কিভাবে।
সামুলি পাহাওজা

13
এফডাব্লুআইডাব্লু এটি ওপেনজেডিকে উপস্থিত রয়েছে।
জেসন সি

6
এখানে বর্ণিত ক্লাসগুলিকে @jdk.Exportedওপেনজেডিকে উত্স কোডে ট্যাগ করা হয়েছে যার অর্থ এপিআই জনসাধারণ হিসাবে বিবেচিত হয় এবং এটি জাভা 9 এ উপলব্ধ হবে (কিছু অন্যান্য com.sun.*প্যাকেজ প্রজেক্ট জিগসের কারণে অনুপলব্ধ হবে)।
জুলে

42

পরীক্ষা করে দেখুন NanoHttpd

"ন্যানোএইচটিটিপিডি একটি হালকা ওজনের এইচটিটিপি সার্ভার, যা অন্য অ্যাপ্লিকেশনগুলিতে এম্বেড করার জন্য ডিজাইন করা হয়েছে, পরিবর্তিত বিএসডি লাইসেন্সের অধীনে প্রকাশিত হয়েছে।

এটি গিথুবে তৈরি করা হচ্ছে এবং বিল্ডস এবং ইউনিট পরীক্ষার জন্য অ্যাপাচি ম্যাভেন ব্যবহার করে "


4
একটি সাবধানতা: সম্ভবত যে ন্যানোএইচটিটিপিডি গাছ বয়ে যাওয়া আক্রমণগুলির বিরুদ্ধে সুরক্ষা রাখে না - আপনার এটি পরীক্ষা করা উচিত এটি কোনও জনসাধারণের ঠিকানায় পরিবেশিত হবে কিনা। এর মাধ্যমে আমার আক্রমণগুলি বোঝায় যেখানে অনুরোধ GET /../../blahblah http/1.1জারি করা হয় এবং সার্ভারটি ওয়েবসাইটের মূলের উপরে এবং সিস্টেম ফাইলের জমির উপরে চলে যায়, এমন ফাইলগুলি পরিবেশন করে যা কোনও পাসওয়ার্ড ফাইলের মতো সিস্টেমে আপস করতে বা দূরবর্তীভাবে আক্রমণ করতে ব্যবহৃত হতে পারে।
লরেন্স ডল

7
এটি স্থির বলে মনে হচ্ছে। বর্তমান সংস্করণ 403 উত্পন্ন করে যদি (uri.startsWith ("..") || uri.endsWith ("..") || uri.indexOf ("../")> = 0)।
লেনা শিম্মেল

5
আমি বুঝতে পারি না এটি কীভাবে এই প্রশ্নের উত্তর।
কিমাথি

28

Com.sun.net.httpserver সমাধান JREs জুড়ে পোর্টেবল নয়। ন্যূনতম এইচটিটিপি সার্ভার বুটস্ট্র্যাপ করার জন্য javax.xML.ws এ অফিসিয়াল ওয়েবসার্ভিস এপিআই ব্যবহার করা আরও ভাল ...

import java.io._
import javax.xml.ws._
import javax.xml.ws.http._
import javax.xml.transform._
import javax.xml.transform.stream._

@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD) 
class P extends Provider[Source] {
  def invoke(source: Source) = new StreamSource( new StringReader("<p>Hello There!</p>"));
}

val address = "http://127.0.0.1:8080/"
Endpoint.create(HTTPBinding.HTTP_BINDING, new P()).publish(address)

println("Service running at "+address)
println("Type [CTRL]+[C] to quit!")

Thread.sleep(Long.MaxValue)

সম্পাদনা: এটি আসলে কাজ করে! উপরের কোডটি গ্রোভির মতো বা অন্য কিছুর মতো দেখাচ্ছে। এখানে আমি জাভা অনুবাদ করেছি যা আমি পরীক্ষা করেছি:

import java.io.*;
import javax.xml.ws.*;
import javax.xml.ws.http.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

@WebServiceProvider
@ServiceMode(value = Service.Mode.PAYLOAD)
public class Server implements Provider<Source> {

    public Source invoke(Source request) {
        return  new StreamSource(new StringReader("<p>Hello There!</p>"));
    }

    public static void main(String[] args) throws InterruptedException {

        String address = "http://127.0.0.1:8080/";
        Endpoint.create(HTTPBinding.HTTP_BINDING, new Server()).publish(address);

        System.out.println("Service running at " + address);
        System.out.println("Type [CTRL]+[C] to quit!");

        Thread.sleep(Long.MAX_VALUE);
    }
}

1
পোর্টেবল হওয়ার জন্য +1। খুব খারাপ আপনি প্রতিক্রিয়া সামগ্রীর ধরণটি যেমন সেট করতে পারবেন না text/xml
আইজজা

1
আমি মনে করি আপনি <কোড> শ্রেণি সার্ভার সরবরাহকারী <ডেটাসোর্স> {</code> প্রয়োগ করতে পারেন ... এবং তারপরে ডাটাসোর্সের <code> getContentType () </code> পদ্ধতিতে সামগ্রী-প্রকারটি নির্দিষ্ট করুন। এছাড়াও আপনি অন্য ওয়েব শিরোনাম সেট করতে এবং অনুরোধের পরামিতিগুলি পড়তে ওয়েবসওয়ারসিঙ্কটেক্সট: <কোড> @ রিসোর্স ওয়েবসোর্সেস কনটেক্সট সিটিএক্স; </ কোড> ইনজেক্ট করতে পারেন। দুর্ভাগ্যক্রমে ওয়েবসওয়ারসিঙ্কটেক্সটের মাধ্যমে সামগ্রী-প্রকার সেট করা কাজ করে না।
gruenewa

4
আপনি কী ব্যাখ্যা করতে পারেন কেন com.sun.net.HttpServer JRE গুলি জুড়ে বহনযোগ্য নয়?
জাভাবেংরিন্দর

3
না, আমি মনে করি না। এটি আইবিএম জাভা বাস্তবায়ন এবং অন্যদের জন্যও কাজ করবে না। এমনকি যদি এটি এখন কাজ করে তবে অভ্যন্তরীণ এপিআইগুলিকে পরিবর্তনের অনুমতি দেওয়া হয়। কেন শুধু অফিসিয়াল এপিআই ব্যবহার করবেন না?
গ্রুইনেওয়া

1
এই লিঙ্কটি: docs.oracle.com/javase/9/docs/api/java.xML.ws-summary.html বলেছে যে জাভা.এক্সএমএল.উস মডিউলটি জাভা 9
-এর

23

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

  1. পাতলা-সার্ভার : সর্বনিম্ন প্রক্রিয়াকরণ, প্রসঙ্গ বা সেশন প্রসেসিং সহ সার্ভার-আপ স্ট্যাটিক সামগ্রী।
  2. ছোট-সার্ভার : সম্ভবত এগুলির একটিতে অনেকগুলি এইচডিডি-এর মতো সার্ভার গুণাবলীর সাথে রয়েছে যতটা ছোট পদক্ষেপ আপনি এড়াতে পারবেন।

যদিও আমি এইচটিটিপি লাইব্রেরিগুলি যেমন: জেটি , অ্যাপাচি এইচটিপিপি উপাদানগুলি , নেটটি এবং অন্যান্যকে আরও কাঁচা এইচটিটিপি প্রসেসিং সুবিধার মতো বিবেচনা করতে পারি consider লেবেলিংটি খুব সাবজেক্টিভ এবং ছোট-সাইটের জন্য আপনি যে ধরণের জিনিস কল-অন করেছেন তা নির্ভর করে। আমি প্রশ্নের স্পিরিটে এই পার্থক্য তৈরি করি, বিশেষত এ সম্পর্কে মন্তব্যটির জন্য ...

  • "... এইচটিটিপি অনুরোধগুলি ম্যানুয়ালি পার্স করার জন্য কোড না লিখে এবং HTTP প্রতিক্রিয়াগুলিকে ম্যানুয়ালি বিন্যাস করুন ..."

এই কাঁচা সরঞ্জামগুলি আপনাকে এটি করতে দেয় (অন্যান্য উত্তরে বর্ণিত হিসাবে)। তারা সত্যিই একটি হালকা, এমবেডেড বা মিনি-সার্ভার তৈরির জন্য প্রস্তুত-গোপন শৈলীতে leণ দেয় না। একটি মিনি-সার্ভার এমন একটি জিনিস যা আপনাকে ঘন্টা-হুইসেল, স্বল্প ভলিউম, ভাল পারফরম্যান্সের সময়কালের 99% সময় ব্যতীত কোনও ফুল-ফাংশন ওয়েব সার্ভারে (যেমন টমক্যাট বলুন ) অনুরূপ কার্যকারিতা দিতে পারে । একটি পাতলা-সার্ভার মূল ফ্রেসিংয়ের কাছাকাছি মনে হচ্ছে কাঁচা থেকে কিছুটা বেশি সীমিত সাবসেট কার্যকারিতা সহ, আপনাকে 90% সময়কে ভাল দেখায়। কাঁচা সম্পর্কে আমার ধারণাটি আমাকে 75% - 89% অতিরিক্ত ডিজাইন এবং কোডিং ছাড়াই দেখতে সুন্দর করে তুলবে। আমি মনে করি যদি / আপনি WAR ফাইলের স্তরে পৌঁছান, আমরা বনসী সার্ভারগুলির জন্য "ছোট" রেখেছি যা দেখতে দেখতে বড় সার্ভারটি আরও ছোট করে।

পাতলা-সার্ভার অপশন

মিনি-সার্ভার বিকল্পগুলি:

  • স্পার্ক জাভা ... ফিল্টার, টেম্পলেট ইত্যাদি ইত্যাদির সাহায্যে প্রচুর সহায়ক কাজ সম্ভব things
  • ম্যাডভোক ... বনসাই হওয়ার লক্ষ্য এবং এরকম ভাল হতে পারে ;-)

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


21

"জেটি" ওয়েব সার্ভার জেটি একবার দেখুন । ওপেন সোর্স সফ্টওয়্যারটির দুর্দান্ত এক টুকরা যা আপনার সমস্ত প্রয়োজনীয়তার সাথে মিলবে বলে মনে হচ্ছে।

আপনি যদি নিজের রোলিংয়ের জন্য জেদ করেন তবে "httpMessage" শ্রেণিটি একবার দেখুন।


আমি মনে করি জেটি এপি সার্লেটের উপর নির্ভর করে।
অপরিবর্তনীয়

4
@ ত্রুটিযুক্ত: না, জেটিটি একটি অত্যন্ত মডুলার ওয়েব সার্ভার, এটির একটি letচ্ছিক মডিউলগুলির মধ্যে একটি সার্লেট পাত্রে রয়েছে।
লরেন্স ডল

"এটি সার্ভার কার্যকারিতার জন্য একটি অ্যানালগ" - হ্যাঁ এটির "সার্লেট" API। সার্ভলেট ধারক আপনার ক্লাসটি শিরোনাম, কুকিজ ইত্যাদি পার্স করার পরে কল করে
জেমস অ্যান্ডারসন

1
কেবলমাত্র রেকর্ডের জন্য - জেটি সার্ভলেট এপিআই এর নিজস্ব প্রয়োগের সাথে আসে এবং জাভা এসই
জেমস অ্যান্ডারসনের সাথে

4
জেটি খুব বড় এবং প্রকৃত উত্পাদন ব্যবহারের সম্ভাবনা হওয়ার আগে তার শেখার পরিমাণ খুব বেশি।
হুমকি

18

একসময় আমি অনুরূপ কিছু সন্ধান করছিলাম - একটি হালকা হলেও সম্পূর্ণরূপে কার্যক্ষম HTTP সার্ভার যা আমি সহজেই এম্বেড এবং কাস্টমাইজ করতে পারি। আমি দুটি ধরণের সম্ভাব্য সমাধান পেয়েছি:

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

তাই ... আমি জেএলএইচটিটিপি - জাভা লাইটওয়েট এইচটিটিপি সার্ভার লিখতে রইলাম

আপনি এটিকে যে কোনও প্রকল্পে একক (বরং দীর্ঘ) উত্স ফাইল হিসাবে বা কোনও নির্ভরতা ছাড়াই K 50K জার হিসাবে (~ 35K কেটে নেওয়া) এম্বেড করতে পারেন। এটি আরএফসি-কমপ্লায়েন্ট হওয়ার চেষ্টা করে এবং সর্বনিম্ন ব্লাট রাখার সময় বিস্তৃত ডকুমেন্টেশন এবং অনেক দরকারী বৈশিষ্ট্য অন্তর্ভুক্ত করে।

বৈশিষ্ট্যগুলির মধ্যে রয়েছে: ভার্চুয়াল হোস্ট, ডিস্ক থেকে ফাইল পরিবেশন করা, স্ট্যান্ডার্ড মাইম.টাইপস ফাইলের মাধ্যমে মাইম টাইপ ম্যাপিংস, ডিরেক্টরি সূচক প্রজন্ম, ফাইলগুলিকে স্বাগত জানানো, সমস্ত এইচটিটিপি পদ্ধতিগুলির জন্য সমর্থন, শর্তসাপেক্ষ ইটাগগুলি এবং যদি- * শিরোনাম সমর্থন, খণ্ডিত স্থানান্তর এনকোডিং, জিজিপ / ডিফল্ট সংক্ষেপণ, বেসিক এইচটিটিপিএস (জেভিএম দ্বারা সরবরাহিত হিসাবে), আংশিক সামগ্রী (ডাউনলোডের ধারাবাহিকতা), ফাইল আপলোডগুলির জন্য মাল্টিপার্ট / ফর্ম-ডেটা হ্যান্ডলিং, এপিআই বা টীকাগুলির মাধ্যমে একাধিক প্রসঙ্গ হ্যান্ডলার, প্যারামিটার পার্সিং (ক্যোরি স্ট্রিং বা এক্স-www-ফর্ম-urlencoded শরীর), ইত্যাদি

আমি আশা করি অন্যরা এটি দরকারী :-)


মূল পদ্ধতিটি মৌলিক ব্যবহারের একটি ভাল উদাহরণ এবং এফএকিউ অনেকগুলি বিবরণে যায়। আপনার কাছে বিদ্যমান ডক্সকে উন্নত করার জন্য পরামর্শ থাকলে, সরাসরি আমার সাথে যোগাযোগ করতে নির্দ্বিধায়!
amichair



8

একটি জাস্টি সার্ভারের জন্য জেডি কে এবং সার্ভলেট এপিআই সহ কয়েকটি কয়েকটি লাইনের কোডের মধ্যে বেসিক সমর্থন সরবরাহকারী এমন একটি সার্ভার তৈরি করা সম্ভব।

আমি ইউনিট টেস্টিং সার্লেটগুলির জন্য এটি খুব দরকারী বলে খুঁজে পেয়েছি, কারণ এটি অন্যান্য লাইটওয়েটের পাত্রে (আমরা জেটি উত্পাদনের জন্য ব্যবহার করি) এর চেয়ে খুব দ্রুত শুরু করে।

বেশিরভাগ অতি হালকা ওজনের httpservers সার্লেটগুলির জন্য সমর্থন সরবরাহ করে না, তবে আমাদের সেগুলি প্রয়োজন, তাই আমি ভেবেছিলাম আমি ভাগ করে নিই।

নীচের উদাহরণটি মৌলিক সার্লেট সহায়তা সরবরাহ করে, বা এখনও প্রয়োগ করা হয়নি এমন স্টাফগুলির জন্য ছোঁড়া এবং অসমর্থিত অপারেশন এক্সপশন। এটি বেসিক http সহায়তার জন্য com.sun.net.httpserver.HttpServer ব্যবহার করে।

import java.io.*;
import java.lang.reflect.*;
import java.net.InetSocketAddress;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

@SuppressWarnings("deprecation")
public class VerySimpleServletHttpServer {
    HttpServer server;
    private String contextPath;
    private HttpHandler httpHandler;

    public VerySimpleServletHttpServer(String contextPath, HttpServlet servlet) {
        this.contextPath = contextPath;
        httpHandler = new HttpHandlerWithServletSupport(servlet);
    }

    public void start(int port) throws IOException {
        InetSocketAddress inetSocketAddress = new InetSocketAddress(port);
        server = HttpServer.create(inetSocketAddress, 0);
        server.createContext(contextPath, httpHandler);
        server.setExecutor(null);
        server.start();
    }

    public void stop(int secondsDelay) {
        server.stop(secondsDelay);
    }

    public int getServerPort() {
        return server.getAddress().getPort();
    }

}

final class HttpHandlerWithServletSupport implements HttpHandler {

    private HttpServlet servlet;

    private final class RequestWrapper extends HttpServletRequestWrapper {
        private final HttpExchange ex;
        private final Map<String, String[]> postData;
        private final ServletInputStream is;
        private final Map<String, Object> attributes = new HashMap<>();

        private RequestWrapper(HttpServletRequest request, HttpExchange ex, Map<String, String[]> postData, ServletInputStream is) {
            super(request);
            this.ex = ex;
            this.postData = postData;
            this.is = is;
        }

        @Override
        public String getHeader(String name) {
            return ex.getRequestHeaders().getFirst(name);
        }

        @Override
        public Enumeration<String> getHeaders(String name) {
            return new Vector<String>(ex.getRequestHeaders().get(name)).elements();
        }

        @Override
        public Enumeration<String> getHeaderNames() {
            return new Vector<String>(ex.getRequestHeaders().keySet()).elements();
        }

        @Override
        public Object getAttribute(String name) {
            return attributes.get(name);
        }

        @Override
        public void setAttribute(String name, Object o) {
            this.attributes.put(name, o);
        }

        @Override
        public Enumeration<String> getAttributeNames() {
            return new Vector<String>(attributes.keySet()).elements();
        }

        @Override
        public String getMethod() {
            return ex.getRequestMethod();
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            return is;
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }

        @Override
        public String getPathInfo() {
            return ex.getRequestURI().getPath();
        }

        @Override
        public String getParameter(String name) {
            String[] arr = postData.get(name);
            return arr != null ? (arr.length > 1 ? Arrays.toString(arr) : arr[0]) : null;
        }

        @Override
        public Map<String, String[]> getParameterMap() {
            return postData;
        }

        @Override
        public Enumeration<String> getParameterNames() {
            return new Vector<String>(postData.keySet()).elements();
        }
    }

    private final class ResponseWrapper extends HttpServletResponseWrapper {
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        final ServletOutputStream servletOutputStream = new ServletOutputStream() {

            @Override
            public void write(int b) throws IOException {
                outputStream.write(b);
            }
        };

        private final HttpExchange ex;
        private final PrintWriter printWriter;
        private int status = HttpServletResponse.SC_OK;

        private ResponseWrapper(HttpServletResponse response, HttpExchange ex) {
            super(response);
            this.ex = ex;
            printWriter = new PrintWriter(servletOutputStream);
        }

        @Override
        public void setContentType(String type) {
            ex.getResponseHeaders().add("Content-Type", type);
        }

        @Override
        public void setHeader(String name, String value) {
            ex.getResponseHeaders().add(name, value);
        }

        @Override
        public javax.servlet.ServletOutputStream getOutputStream() throws IOException {
            return servletOutputStream;
        }

        @Override
        public void setContentLength(int len) {
            ex.getResponseHeaders().add("Content-Length", len + "");
        }

        @Override
        public void setStatus(int status) {
            this.status = status;
        }

        @Override
        public void sendError(int sc, String msg) throws IOException {
            this.status = sc;
            if (msg != null) {
                printWriter.write(msg);
            }
        }

        @Override
        public void sendError(int sc) throws IOException {
            sendError(sc, null);
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return printWriter;
        }

        public void complete() throws IOException {
            try {
                printWriter.flush();
                ex.sendResponseHeaders(status, outputStream.size());
                if (outputStream.size() > 0) {
                    ex.getResponseBody().write(outputStream.toByteArray());
                }
                ex.getResponseBody().flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                ex.close();
            }
        }
    }

    public HttpHandlerWithServletSupport(HttpServlet servlet) {
        this.servlet = servlet;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void handle(final HttpExchange ex) throws IOException {
        byte[] inBytes = getBytes(ex.getRequestBody());
        ex.getRequestBody().close();
        final ByteArrayInputStream newInput = new ByteArrayInputStream(inBytes);
        final ServletInputStream is = new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return newInput.read();
            }
        };

        Map<String, String[]> parsePostData = new HashMap<>();

        try {
            parsePostData.putAll(HttpUtils.parseQueryString(ex.getRequestURI().getQuery()));

            // check if any postdata to parse
            parsePostData.putAll(HttpUtils.parsePostData(inBytes.length, is));
        } catch (IllegalArgumentException e) {
            // no postData - just reset inputstream
            newInput.reset();
        }
        final Map<String, String[]> postData = parsePostData;

        RequestWrapper req = new RequestWrapper(createUnimplementAdapter(HttpServletRequest.class), ex, postData, is);

        ResponseWrapper resp = new ResponseWrapper(createUnimplementAdapter(HttpServletResponse.class), ex);

        try {
            servlet.service(req, resp);
            resp.complete();
        } catch (ServletException e) {
            throw new IOException(e);
        }
    }

    private static byte[] getBytes(InputStream in) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        while (true) {
            int r = in.read(buffer);
            if (r == -1)
                break;
            out.write(buffer, 0, r);
        }
        return out.toByteArray();
    }

    @SuppressWarnings("unchecked")
    private static <T> T createUnimplementAdapter(Class<T> httpServletApi) {
        class UnimplementedHandler implements InvocationHandler {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                throw new UnsupportedOperationException("Not implemented: " + method + ", args=" + Arrays.toString(args));
            }
        }

        return (T) Proxy.newProxyInstance(UnimplementedHandler.class.getClassLoader(),
                new Class<?>[] { httpServletApi },
                new UnimplementedHandler());
    }
}

এটি সার্ভলেটআউটপুট স্ট্রিম এবং সার্লেটলেট ইনপুট স্ট্রিমের কিছু পদ্ধতি অনুপস্থিত
হোমআইএসইহেতুপিপিস

সার্ভলেট এপিআই এর নতুন সংস্করণ, উপরে 3.0 এবং নীচে ফিট করে। উদাহরণ হিসাবে প্রয়োজন হিসাবে কেবল অনুপস্থিত মেথডোস যুক্ত করুন
f.carlsen

6

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


+1 টি। আমি সরল পিছনে ধারণা পছন্দ করি। যাইহোক, এইচটিটিপিএস ব্যবহার করার চেষ্টা করার সময় সমস্যাগুলি আসে কারণ মাম্বা সরল থেকে "এম্বেডযোগ্য" বৈশিষ্ট্যটি হরণ করে।
হুমকি

6

এই কোড আমাদিগের চেয়ে ভাল, আপনি শুধুমাত্র 2 লিব যোগ করার জন্য প্রয়োজন হয় javax.servelet.jar এবং org.mortbay.jetty.jar

ক্লাস জেটি:

package jetty;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.mortbay.http.SocketListener;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHttpContext;

public class Jetty {

    public static void main(String[] args) {
        try {
            Server server = new Server();
            SocketListener listener = new SocketListener();      

            System.out.println("Max Thread :" + listener.getMaxThreads() + " Min Thread :" + listener.getMinThreads());

            listener.setHost("localhost");
            listener.setPort(8070);
            listener.setMinThreads(5);
            listener.setMaxThreads(250);
            server.addListener(listener);            

            ServletHttpContext context = (ServletHttpContext) server.getContext("/");
            context.addServlet("/MO", "jetty.HelloWorldServlet");

            server.start();
            server.join();

        /*//We will create our server running at http://localhost:8070
        Server server = new Server();
        server.addListener(":8070");

        //We will deploy our servlet to the server at the path '/'
        //it will be available at http://localhost:8070
        ServletHttpContext context = (ServletHttpContext) server.getContext("/");
        context.addServlet("/MO", "jetty.HelloWorldServlet");

        server.start();
        */

        } catch (Exception ex) {
            Logger.getLogger(Jetty.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
} 

পরিবেশন শ্রেণি:

package jetty;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException
    {
        String appid = httpServletRequest.getParameter("appid");
        String conta = httpServletRequest.getParameter("conta");

        System.out.println("Appid : "+appid);
        System.out.println("Conta : "+conta);

        httpServletResponse.setContentType("text/plain");
        PrintWriter out = httpServletResponse.getWriter();
        out.println("Hello World!");
        out.close();
    }
}

2
প্রশ্নটি খাঁটি জাভা এসই সমাধানের জন্য জিজ্ঞাসা করে। আপনি দেখতে পাবেন যে জেটি জাভা ইই এপিআই প্রয়োগ করে।
শ্রীধর

জেটি স্ট্যান্ডার্ড জাভা এসই ব্যবহার করে পুরোপুরি ভাল চালায় এবং তাই প্রয়োজনীয়তাগুলি ফিট করে। এটি জাভা EE API এর অংশগুলি প্রয়োগ করে, এটির প্রয়োজন নেই । পার্থক্য আছে.
ডেভিড টোনহোফার

1
এটি যোগ্যতা অর্জন করে না। "কেবল জাভা এসই এপিআই ব্যবহার করে"*.Servlet.jarএবং *.jetty.jarস্পষ্টতই জাভা এসই এর অংশ নয়।
আইজজা

আমার কি জেটি সেট আপ করা দরকার? বা আমি কেবল এই দুটি জারটি বাদ দিয়ে এই ফাইলটি চালাতে পারি?
পল প্রিবিশ


4

একক প্রধান থ্রেডযুক্ত অনুরোধ হ্যান্ডলার সম্পর্কে উপরের সমস্ত উত্তরসমূহ বিশদ।

বিন্যাস:

 server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());

এক্সিকিউটর পরিষেবা ব্যবহার করে একাধিক থ্রেডের মাধ্যমে একাধিক অনুরোধ পরিবেশন করার অনুমতি দেয়।

সুতরাং শেষ কোডটি নীচের মতো কিছু হবে:

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class App {
    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/test", new MyHandler());
        //Thread control is given to executor service.
        server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
        server.start();
    }
    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "This is the response";
            long threadId = Thread.currentThread().getId();
            System.out.println("I am thread " + threadId );
            response = response + "Thread Id = "+threadId;
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

3

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

অ্যামেজিং!



2

অ্যাপাচি কমন্স এইচটিপিপোর প্রকল্প সম্পর্কে কীভাবে ?

ওয়েব সাইট থেকে: ... এইচটিপিপোরের লক্ষ্যগুলি

  • সর্বাধিক মৌলিক এইচটিটিপি পরিবহন দিকগুলির বাস্তবায়ন
  • ভাল পারফরম্যান্স এবং API এর স্পষ্টতা এবং অভিব্যক্তি মধ্যে ভারসাম্য
  • ছোট (অনুমানযোগ্য) মেমরি পদচিহ্ন
  • স্বযুক্ত গ্রন্থাগার (জেআরই এর বাইরে কোনও বাহ্যিক নির্ভরতা নেই)

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

2

এই https://github.com/devashish234073/ জাভা- সকেট- HTTP-Server/ blob/ master/ README.md ব্যবহার করে দেখুন

এই এপিআই সকেট ব্যবহার করে একটি এইচটিটিপি সার্ভার তৈরি করেছে।

  1. এটি পাঠ্য হিসাবে ব্রাউজারের একটি অনুরোধ পেয়েছে
  2. ইউআরএল তথ্য, পদ্ধতি, বৈশিষ্ট্য ইত্যাদি পুনরুদ্ধার করতে পার্স করে es
  3. ইউআরএল ম্যাপিং সংজ্ঞায়িত ব্যবহার করে গতিশীল প্রতিক্রিয়া তৈরি করে
  4. প্রতিক্রিয়াটি ব্রাউজারে প্রেরণ করে।

উদাহরণস্বরূপ এখানে Response.javaশ্রেণীর নির্মাতা কীভাবে কোনও কাঁচা প্রতিক্রিয়াটিকে একটি HTTP প্রতিক্রিয়াতে রূপান্তরিত করেন:

public Response(String resp){
    Date date = new Date();
    String start = "HTTP/1.1 200 OK\r\n";
    String header = "Date: "+date.toString()+"\r\n";
    header+= "Content-Type: text/html\r\n";
    header+= "Content-length: "+resp.length()+"\r\n";
    header+="\r\n";
    this.resp=start+header+resp;
}

1

আপনি জেটি জাভা সার্ভার এম্বেড করা একটি সহজ সাধারণ লিখতে পারেন ।

এম্বেড জেটির অর্থ বহিরাগত জেটি সার্ভারে অ্যাপ্লিকেশন মোতায়েনের বিরোধী হিসাবে অ্যাপ্লিকেশনটির সাথে সার্ভার (জেটি) একসাথে প্রেরণ করা হয়েছে।

সুতরাং যদি এম্বেডবিহীন পদ্ধতির মধ্যে আপনার ওয়েব অ্যাপসটি ওয়ার ফাইলটিতে অন্তর্নির্মিত হয় যা এম্বেড জেটিতে কিছু বাহ্যিক সার্ভারে ( টমক্যাট / জেটি / ইত্যাদি) মোতায়েন করা হয় , আপনি ওয়েব অ্যাপ লিখেছেন এবং একই কোড বেসে জেটি সার্ভারটি ইনস্ট্যান্ট করবেন।

এম্বেড জেটি জাভা সার্ভারের একটি উদাহরণ আপনি ক্লিটটি গিট করতে এবং ব্যবহার করতে পারেন: https://github.com/stas-slu/e এমবেডড- jetty-java- server-example

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