केवल जावा एसई एपीआई का उपयोग करके जावा में सरल HTTP सर्वर


333

क्या मैन्युअल रूप से HTTP अनुरोधों को पार्स करने और HTTP प्रतिसादों को मैन्युअल रूप से लिखने के लिए कोड लिखे बिना जावा में बहुत मूल HTTP सर्वर (केवल GET / POST का समर्थन) बनाने का एक तरीका है? Java SE API HttpURLConnection में HTTP क्लाइंट कार्यक्षमता को अच्छी तरह से समझाया गया है, लेकिन क्या HTTP सर्वर कार्यक्षमता के लिए एक एनालॉग है?

बस स्पष्ट होने के लिए, मेरे पास बहुत सारे सर्वरसलेट उदाहरणों के साथ समस्या जो मैंने ऑनलाइन देखी है, वह यह है कि वे अपने स्वयं के अनुरोध को पार्सिंग / प्रतिक्रिया स्वरूपण और त्रुटि से निपटने के लिए करते हैं, जो थकाऊ, त्रुटि-प्रवण है, और व्यापक होने की संभावना नहीं है, और मैं उन कारणों से बचने की कोशिश कर रहा हूं।

मैं से बचने के लिए कोशिश कर रहा हूँ कि मैनुअल HTTP हेरफेर के एक उदाहरण के रूप में:

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


3
उम्म… छोटा जवाब है नहीं। यदि आप कुछ ऐसा चाहते हैं जो पोस्ट को हैंडल करता है और HTTP हेडर को मैन्युअल रूप से लिखने के बिना अनुरोध प्राप्त करता है तो आप सर्वलेट्स का उपयोग कर सकते हैं। लेकिन यह जावा ee है। यदि आप ऐसा कुछ उपयोग नहीं करना चाहते हैं तो सॉकेट्स और मैनुअल पार्सिंग केवल एक अन्य विकल्प है जो मुझे पता है।
मैट फिलिप्स

3
मुझे पता है कि यह एसओ की भावना में नहीं है, लेकिन मैं आपसे आग्रह करूंगा कि आप जावा ईई एपीआई के लिए अविश्वास पर पुनर्विचार करें। जैसा कि कुछ जवाबों में उल्लेख किया गया है, जेट्टी जैसे कुछ बहुत सीधे-सीधे कार्यान्वयन हैं जो आपको सर्वलेट एप का लाभ लेते हुए अपने स्टैंड-अलोन एप्लिकेशन में एक वेब सर्वर को एम्बेड करने की अनुमति देते हैं। अगर आप मेरी टिप्पणी की अवहेलना करने के बजाय किसी कारण से जावा ईई एपीआई का उपयोग नहीं कर सकते हैं तो कृपया :-)
क्रिस थॉम्पसन

1
"सर्वलेट्स" वास्तव में "जावा ईई" नहीं हैं। वे प्लगइन्स लिखने का एक तरीका है जो संदेश गतिविधि (इन दिनों, आमतौर पर HTTP अनुरोधों) के जवाब में आसपास के अनुप्रयोग द्वारा बुलाया जा सकता है। "सिर्फ जावा एसई एपीआई का उपयोग करके" एक सर्वलेट होस्टिंग वातावरण प्रदान करना ठीक वैसा ही है जैसा जेट्टी और टॉमकैट करते हैं। बेशक आप अवांछित जटिलता को बाहर फेंकना चाहते हैं, लेकिन फिर आपको GET / POST की अनुमत विशेषताओं और कॉन्फ़िगरेशन के सबसेट पर निर्णय लेने की आवश्यकता हो सकती है। विशेष सुरक्षा / एम्बेडेड समस्याओं को छोड़कर, यह अक्सर इसके लायक नहीं है।
डेविड टोनहोफर

1
यह निर्णय लेने से पहले http सर्वर की इस सूची से गुजरने लायक हो सकता है। java-source.net/open-source/web-servers
ThreaT

जवाबों:


469

जावा एसई 6 के बाद से, सन ओरेकल जेआरई में एक अंतर्निहित HTTP सर्वर है । com.sun.net.httpserverपैकेज सारांश शामिल कक्षाओं की रूपरेखा और उदाहरण हैं।

यहाँ एक किकऑफ़ उदाहरण है copypasted (सभी लोगों, यह संपादित करने की कोशिश कर फिर भी, क्योंकि यह कोड का एक बदसूरत टुकड़ा है करने के लिए, कृपया मत उनके डॉक्स से, यह एक कॉपी पेस्ट है मेरा, इसके अलावा आप संपादित कोटेशन जब तक कि वे बदल गए हैं कभी नहीं करना चाहिए नहीं मूल स्रोत में)। आप इसे Java 6+ पर बस''n'paste'n'run पर कॉपी कर सकते हैं।

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: // localhost: 8000 / test पर जाएं और आप निम्नलिखित प्रतिक्रिया देखेंगे:

यह प्रतिक्रिया है


com.sun.*कक्षाओं का उपयोग करने के रूप में , ध्यान दें कि यह कुछ डेवलपर्स के विपरीत है, बिल्कुल अच्छी तरह से ज्ञात FAQ द्वारा मना नहीं किया जाता है क्यों डेवलपर्स को प्रोग्राम नहीं लिखना चाहिए जो कि 'सूरज' पैकेज कहते हैं । यह पूछे जाने वाले प्रश्न ओरेकल जेआरई द्वारा आंतरिक उपयोग के लिए sun.*पैकेज (जैसे कि sun.misc.BASE64Encoder) की चिंता करता है (जो इस प्रकार आपके आवेदन को मार देगा जब आप इसे एक अलग JRE पर चलाते हैं), com.sun.*पैकेज नहीं । सन / ओरेकल भी जावा एसई एपीआई के शीर्ष पर सॉफ्टवेयर विकसित करता है जैसे कि हर दूसरी कंपनी जैसे अपाचे और इसी तरह। com.sun.*कक्षाओं का उपयोग करना केवल हतोत्साहित (लेकिन निषिद्ध नहीं) है जब यह एक निश्चित जावा एपीआई के कार्यान्वयन की चिंता करता है, जैसे ग्लासफिश (जावा ईई निहित), मोआजरा (जेएसएफ प्रत्यारोपण), जर्सी (जेएक्स-आरएस प्रत्यारोपण), आदि।


19
@Waldheinz: @Software की तरह आप के sun.*साथ भ्रमित कर रहे हैं com.sun.*। उदाहरण के लिए, क्या आपको sun.*एपीआई का कोई दस्तावेज दिखाई देता है? यहाँ देखें: java.sun.com/products/jdk/faq/faq-sun-packages.html क्या यह इसके बारे में कुछ बताता है com.sun.*? का com.sun.*उपयोग केवल अपने स्वयं के सार्वजनिक सॉफ़्टवेयर के लिए किया जाता है जो जावा एपीआई का हिस्सा नहीं है। वे हर दूसरी कंपनी की तरह जावा एपीआई के शीर्ष पर भी सॉफ्टवेयर विकसित करते हैं।
बालुसक

4
मुझे लगता है कि यह एकीकरण परीक्षण मामलों में उपयोग करने के लिए एक बहुत अच्छा http सर्वर है। संकेत के लिए धन्यवाद!
एंड्रियास पीटरसन 13

13
यदि आप एक्लिप्स का उपयोग कर रहे हैं और "एक्सेस प्रतिबंध:" आवश्यक लाइब्रेरी पर प्रतिबंध के कारण HttpExchange टाइप नहीं हो पा रहा है, तो एक त्रुटि मिलती है ... ", stackoverflow.com/a/10642163 बताता है कि उस एक्सेस चेक को कैसे निष्क्रिय करना है।
समुली पहाजा

13
FWIW यह OpenJDK में भी मौजूद है।
जेसन सी

6
यहां संदर्भित कक्षाएं @jdk.ExportedOpenJDK स्रोत कोड में टैग की गई हैं, जिसका अर्थ है कि एपीआई को सार्वजनिक माना जाता है और जावा 9 पर उपलब्ध होगा ( com.sun.*प्रोजेक्ट आरा के कारण कुछ अन्य पैकेज अनुपलब्ध हो जाएंगे)।
जूल्स

42

की जाँच करें NanoHttpd

"NanoHTTPD एक लाइट-वेट HTTP सर्वर है जिसे अन्य अनुप्रयोगों में एम्बेड करने के लिए डिज़ाइन किया गया है, जो एक संशोधित BSD लाइसेंस के तहत जारी किया गया है।

इसे गितुब में विकसित किया जा रहा है और बिल्ड और यूनिट परीक्षण के लिए अपाचे मावेन का उपयोग करता है "


4
एक सावधानी: यह संभावना है कि नैनो-टीटीपीडी को पेड़ से चलने वाले हमलों से सुरक्षा नहीं है - आपको यह जांचना चाहिए कि क्या यह एक सार्वजनिक पते पर सेवा दे रहा है। इसके द्वारा मैं उन हमलों का मतलब है जहां एक अनुरोध GET /../../blahblah http/1.1जारी किया जाता है और सर्वर वेबसाइट रूट और सिस्टम फ़ाइल भूमि के ऊपर चलता है, उन फ़ाइलों की सेवा करता है जो एक पासवर्ड फ़ाइल की तरह, सिस्टम से समझौता करने या दूर से हमला करने के लिए इस्तेमाल किया जा सकता है।
लॉरेंस डोल

7
यह तय लग रहा है। वर्तमान संस्करण एक 403 उत्पन्न करता है अगर (uri.startsWith ("..") || uri.endsWith ("..") || uri.indexOf ("../")> = 0)।
लीना शिम्मेल

5
मुझे समझ नहीं आता कि यह इस सवाल का जवाब कैसे है।
किमाथी

28

Com.sun.net.httpserver समाधान JREs भर में पोर्टेबल नहीं है। एक न्यूनतम HTTP सर्वर बूटस्ट्रैप करने के लिए javax.xml.ws में आधिकारिक webservices API का उपयोग करना बेहतर है ...

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
icza

1
मुझे लगता है कि आप कर सकते हैं <code> वर्ग सर्वर उपकरण प्रदाता प्रदाता <dataSource> {</ code> ... और फिर DataSource के <code> getContentType () </ code> विधि के भीतर सामग्री-प्रकार निर्दिष्ट करें। इसके अलावा आप WebServiceContext: <code> @Resource WebServiceContext ctx; </ code> को अन्य हेडर सेट करने और अनुरोध पैरामीटर पढ़ने के लिए भी इंजेक्ट कर सकते हैं। दुर्भाग्य से WebServiceContext के माध्यम से सामग्री-प्रकार सेट करना काम नहीं करता है।
ग्रुएन्यूवा

4
क्या आप समझा सकते हैं कि क्यों com.sun.net.HttpServer, JREs कृपया पोर्टेबल नहीं है?
javabeangrinder 15

3
नहीं, l ऐसा नहीं लगता। यह आईबीएम जावा कार्यान्वयन और शायद दूसरों पर भी काम नहीं करेगा। और यहां तक ​​कि अगर यह अब काम करता है, तो आंतरिक एपीआई को बदलने की अनुमति है। केवल आधिकारिक एपीआई का उपयोग क्यों न करें?
ग्रुएन्यूवा

1
यह लिंक: docs.oracle.com/javase/9/docs/api/java.xml.ws-summary.html का कहना है कि जावा 9 से java.xml.ws मॉड्यूल को हटा दिया गया है
Erel Segal-Halevi

23

मुझे यह सवाल पसंद है क्योंकि यह एक ऐसा क्षेत्र है जहां निरंतर नवाचार है और विशेष रूप से छोटे (एर) उपकरणों में एम्बेडेड सर्वर के बारे में बात करते समय हमेशा एक प्रकाश सर्वर की आवश्यकता होती है। मुझे लगता है कि उत्तर दो व्यापक समूहों में आते हैं।

  1. पतला-सर्वर : न्यूनतम प्रसंस्करण, संदर्भ या सत्र प्रसंस्करण के साथ सर्वर-अप स्थिर सामग्री।
  2. छोटा सर्वर : ओस्टेंसिक रूप से कई httpD- जैसे सर्वर गुण होते हैं जिनमें छोटे पदचिह्न होते हैं जैसे आप दूर हो सकते हैं।

जबकि मैं HTTP पुस्तकालयों पर विचार कर सकता हूं जैसे: जेट्टी , अपाचे एचटीटीपी अवयव , नेट्टी और अन्य एक कच्चे HTTP प्रसंस्करण सुविधाओं की तरह होना चाहिए। लेबलिंग बहुत व्यक्तिपरक है, और छोटी-साइटों के लिए वितरित करने के लिए आपके द्वारा कॉल की गई चीज़ के प्रकार पर निर्भर करता है। मैं इस सवाल की भावना में अंतर करता हूं, विशेष रूप से टिप्पणी के बारे में ...

  • "... मैन्युअल रूप से HTTP अनुरोधों को पार्स करने के लिए कोड लिखे बिना और HTTP प्रतिक्रियाओं को मैन्युअल रूप से प्रारूपित करें ..."

ये कच्चे उपकरण आपको ऐसा करने देते हैं (जैसा कि अन्य उत्तरों में वर्णित है)। वे वास्तव में खुद को लाइट, एंबेडेड या मिनी-सर्वर बनाने के लिए तैयार-सेट-गो शैली में उधार नहीं देते हैं। एक मिनी-सर्वर एक ऐसी चीज है, जो बिना फुल- सीटी और बिना सीटी, कम मात्रा, अच्छे प्रदर्शन के 99% समय में आपको फुल-फंक्शन वेब सर्वर (जैसे कहना, टॉमकैट ) के समान कार्यक्षमता दे सकती है । एक पतला-सा सर्वर मूल उपमा के करीब लगता है, जो कच्चे की तुलना में शायद थोड़ा अधिक है, एक सीमित उपसमुच्चय कार्यक्षमता के साथ, जो आपको 90% अच्छा दिखने के लिए पर्याप्त है। कच्चे का मेरा विचार मुझे 75% अच्छा लगेगा - अतिरिक्त डिजाइन और कोडिंग के बिना 89% समय। मुझे लगता है कि अगर / जब आप WAR फ़ाइलों के स्तर तक पहुँचते हैं, तो हमने बोन्सी सर्वर के लिए "छोटा" छोड़ दिया है जो ऐसा दिखता है जैसे कि एक बड़ा सर्वर छोटा करता है।

पतली सर्वर विकल्प

मिनी-सर्वर विकल्प:

  • स्पार्क जावा ... बहुत सारे हेल्पर निर्माण जैसे फिल्टर, टेम्प्लेट आदि के साथ अच्छी चीजें संभव हैं।
  • MadVoc ... बोन्साई होने का लक्ष्य है और ऐसा हो सकता है ;-)

विचार करने के लिए अन्य बातों के अलावा, मैं पृष्ठ आउटपुट को रेंडर करने के लिए फ्रीमेकर या अन्य टेम्पलेट टूल जैसी किसी चीज़ का उपयोग करके प्रमाणीकरण, सत्यापन, अंतर्राष्ट्रीयकरण शामिल करूंगा । अन्यथा एचटीएमएल एडिटिंग और पैरामीटराइजेशन का प्रबंधन HTTP के साथ काम करने की संभावना है जैसे नॉटीज़-एन-क्रॉस। स्वाभाविक रूप से यह सब इस बात पर निर्भर करता है कि आपको कितना लचीला होना चाहिए। यदि यह एक मेनू-चालित FAX मशीन है तो यह बहुत सरल हो सकती है। जितना अधिक इंटरैक्शन, आपके ढांचे को ' मोटा ' होने की जरूरत है। अच्छा सवाल, शुभकामनाएँ!


21

"जेट्टी" वेब सर्वर जेट्टी पर एक नजर है । ओपन सोर्स सॉफ्टवेयर का शानदार टुकड़ा जो आपकी सभी आवश्यकताओं को पूरा करता प्रतीत होगा।

यदि आप अपना खुद का रोल करने पर जोर देते हैं, तो "httpMessage" क्लास पर एक नज़र डालें।


मुझे लगता है कि जेटी एपी सर्वलेट पर निर्भर करता है।
3

4
@ आकर्षक: नहीं, जेट्टी एक अत्यधिक मॉड्यूलर वेब सर्वर है, जिसमें वैकल्पिक मॉड्यूल में से एक के रूप में एक सर्वलेट कंटेनर है।
लॉरेंस Dol

"सर्वर कार्यक्षमता के लिए एक एनालॉग है" - हां इसका "सर्वलेट" एपीआई है। यह हेडर, कुकीज इत्यादि को पार्स करने के बाद सर्वलेट कंटेनर आपकी कक्षा को कॉल करता है
जेम्स एंडरसन

1
सिर्फ रिकॉर्ड के लिए - जेट्टी ने सर्वलेट एपीआई के अपने कार्यान्वयन के साथ आता है और जावा एसई के साथ ठीक काम करता है
जेम्स एंडरसन

4
जेट्टी बहुत बड़ी है और वास्तविक उत्पादन उपयोग की संभावना बनने से पहले बहुत अधिक सीखने की अवस्था है।
थ्रेट

18

एक बार मैं कुछ इसी तरह की तलाश में था - एक हल्का अभी तक पूरी तरह कार्यात्मक HTTP सर्वर जिसे मैं आसानी से एम्बेड और अनुकूलित कर सकता था। मुझे दो प्रकार के संभावित समाधान मिले:

  • पूर्ण सर्वर जो हल्के या सरल नहीं हैं (हल्के की चरम परिभाषा के लिए)।
  • वास्तव में हल्के सर्वर जो काफी HTTP सर्वर नहीं हैं, लेकिन सर्वर-सॉकेट उदाहरण हैं जो दूरस्थ रूप से RFC-अनुरूप भी नहीं हैं और आमतौर पर आवश्यक बुनियादी कार्यक्षमता का समर्थन नहीं करते हैं।

इसलिए ... मैंने JLHTTP - जावा लाइटवेट HTTP सर्वर लिखने के लिए निर्धारित किया है ।

आप इसे किसी भी परियोजना में एकल (यदि लंबे समय तक) स्रोत फ़ाइल के रूप में, या बिना निर्भरता के साथ ~ 50K जार (~ 35K छीन) के रूप में एम्बेड कर सकते हैं। यह RFC के अनुरूप होने का प्रयास करता है और इसमें व्यापक दस्तावेज और कई उपयोगी सुविधाएँ शामिल होती हैं, जबकि न्यूनतम तक ब्लोट रखते हैं।

सुविधाएँ शामिल हैं: वर्चुअल होस्ट, डिस्क से सेवारत फ़ाइल, मानक mime.types फ़ाइल के माध्यम से माइम टाइप मैपिंग, डायरेक्टरी इंडेक्स जेनरेशन, वेलकम फाइल्स, सभी HTTP मेथड के लिए सपोर्ट, सशर्त ETags और यदि- * हेडर सपोर्ट, चंक्ड ट्रांसफर एन्कोडिंग, गज़िप / डीफ़्लैट संपीड़न, मूल HTTPS (जेवीएम द्वारा प्रदान की गई), आंशिक सामग्री (डाउनलोड जारी रखना), फ़ाइल अपलोड के लिए मल्टीपार्ट / फॉर्म-डेटा हैंडलिंग, एपीआई या एनोटेशन, पैरामीटर पार्सिंग (क्वेरी स्ट्रिंग या x-www-form-urlencoded के माध्यम से कई संदर्भ हैंडलर) शरीर), आदि

मुझे आशा है कि अन्य इसे उपयोगी पाएंगे :-)


मुख्य विधि बुनियादी उपयोग का एक अच्छा उदाहरण है, और अक्सर पूछे जाने वाले प्रश्न विवरण में जाते हैं। यदि आपके पास मौजूदा डॉक्स को बेहतर बनाने के सुझाव हैं, तो बेझिझक मुझसे सीधे संपर्क करें!
अमीषा



8

एक httpserver बनाना संभव है जो कि J2EE सर्वलेट्स के लिए बस JDK के साथ मूल कोड प्रदान करता है और कोड की कुछ ही पंक्तियों में सर्वलेट एपीआई।

मैंने यूनिट टेस्टिंग सर्वलेट्स के लिए इसे बहुत उपयोगी पाया है, क्योंकि यह अन्य हल्के कंटेनरों की तुलना में बहुत तेज़ी से शुरू होता है (हम उत्पादन के लिए जेटी का उपयोग करते हैं)।

अधिकांश बहुत हल्के httpservers servlets के लिए सहायता प्रदान नहीं करते हैं, लेकिन हमें उनकी आवश्यकता है, इसलिए मैंने सोचा कि मैं साझा करूँगा।

नीचे दिया गया उदाहरण मूल सर्वलेट समर्थन, या फेंकता है और अभी तक लागू नहीं किए गए सामान के लिए UnsupportedOperationException। यह बुनियादी 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());
    }
}

यह ServletOutputStream और ServletInputStream
HomeIsWhereThePcIs

सर्वलेट एप का नया संस्करण, ऊपर 3.0 और नीचे फिट बैठता है। उदाहरण में आवश्यकतानुसार लापता मेथाडोस जोड़ें
f.carlsen

6

मैं सरलता से देखने की दृढ़ता से अनुशंसा कर सकता हूं , खासकर यदि आपको सर्वलेट क्षमताओं की आवश्यकता नहीं है, लेकिन बस अनुरोध / रिपॉइंट ऑब्जेक्ट्स तक पहुंच है। यदि आपको REST की आवश्यकता है, तो आप इसके ऊपर जर्सी रख सकते हैं, यदि आपको HTML या इसी तरह का कोई और उत्पादन करने की आवश्यकता है, तो वह है। मुझे वास्तव में बहुत पसंद है कि आप इस संयोजन के साथ क्या कर सकते हैं, और सीखने के लिए अपेक्षाकृत कम एपीआई है।


+1। मुझे सिंपल के पीछे के आइडिया पसंद हैं। हालाँकि, समस्या तब आती है जब HTTPS का उपयोग करने का प्रयास किया जाता है क्योंकि Mamba सरल से "एम्बेड करने योग्य" सुविधा को हटा देता है।
थ्रोट

6

यह कोड हमारे से बेहतर है, आपको केवल 2 लिबास जोड़ने की जरूरत है: javax.ervelet.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
सवाल एक शुद्ध जावा एसई समाधान के लिए पूछता है। आप पाएंगे कि जेट्टी जावा ईई एपीआई को लागू करता है।
श्रीधर

जेट्टी मानक जावा एसई का उपयोग करके पूरी तरह से अच्छी तरह से चलती है और इसलिए आवश्यकताओं को पूरा करती है। यह जावा ईई एपीआई के कुछ हिस्सों को लागू करता है, इसे इसकी आवश्यकता नहीं है। इसमे अंतर है।
डेविड टोनहोफर

1
यह योग्यता नहीं है। "सिर्फ जावा एसई एपीआई का उपयोग कर"*.Servlet.jarऔर *.jetty.jarस्पष्ट रूप से जावा एसई का हिस्सा नहीं हैं।
icza

क्या मुझे जेटी स्थापित करने की आवश्यकता है? या मैं सिर्फ उन दो जार को हटा सकता हूं और इस फाइल को चला सकता हूं?
पॉल प्रीबिस्क


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

अपाचे कॉमन्स HttpCore प्रोजेक्ट के बारे में कैसे ?

वेब साइट से: ... HttpCore लक्ष्य

  • सबसे बुनियादी HTTP परिवहन पहलुओं का कार्यान्वयन
  • अच्छे प्रदर्शन और एपीआई की स्पष्टता और स्पष्टता के बीच संतुलन
  • स्मॉल (प्रेडिक्टेबल) मेमोरी फुटप्रिंट
  • सेल्फ लाइब्रेरी (जेआरई से परे कोई बाहरी निर्भरता नहीं)

वह शायद बहुत निचले स्तर का है। कम से कम एक समाधान के लिए लक्ष्य बनाना चाहिए जो सर्वलेट एपीआई स्तर पर आपके कोड को कॉल करता है, जब तक कि कोई भी सभी अवधारणाओं जैसे कि चैंकिंग, एन्कोडिंग आदि से खुद को निपटाना नहीं चाहता है। यह हालांकि मजेदार हो सकता है।
डेविड टोनहोफर

2

यह प्रयास करें https://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md

इस एपीआई में सॉकेट्स का उपयोग करके एक HTTP सर्वर बनाया गया है।

  1. इसे ब्राउज़र से पाठ के रूप में अनुरोध मिलता है
  2. URL जानकारी, विधि, विशेषताएँ, आदि प्राप्त करने के लिए इसे पार्स करता है।
  3. परिभाषित URL मानचित्रण का उपयोग करके गतिशील प्रतिक्रिया बनाता है
  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

आप एक बहुत ही सरल एम्बेडेड जेट्टी जावा सर्वर लिख सकते हैं ।

एंबेडेड जेट्टी का मतलब है कि सर्वर (जेट्टी) ने बाहरी जेट्टी सर्वर पर एप्लिकेशन को तैनात करने के विरोध में आवेदन के साथ भेज दिया।

इसलिए यदि गैर-एम्बेडेड दृष्टिकोण में आपका वेब WAR फ़ाइल में बनाया गया है जो कि कुछ बाहरी सर्वर ( Tomcat / Jetty / etc) में तैनात है , तो एम्बेडेड Jetty में, आप webapp लिखते हैं और उसी कोड बेस में जेट्टी सर्वर को इंस्टेंट करते हैं।

एम्बेडेड जेट्टी जावा सर्वर के लिए एक उदाहरण आप क्लोन और उपयोग कर सकते हैं: https://github.com/stas-slu/embedded-jetty-java-server-example

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.