Java SE APIのみを使用したJavaのシンプルなHTTPサーバー


333

Java SE APIだけを使用して、Javaで非常に基本的なHTTPサーバー(GET / POSTのみをサポート)を作成する方法はありますか。手動でHTTP要求を解析し、HTTP応答を手動でフォーマットするコードを書く必要はありませんか?Java SE APIは、HTTPクライアント機能をHttpURLConnectionにうまくカプセル化しますが、HTTPサーバー機能の類似物はありますか?

明確にするために、私がオンラインで見た多くのServerSocketの例で私が抱えている問題は、それらが独自の要求の解析/応答のフォーマットとエラー処理を行うことです。そして私はそれらの理由でそれを避けようとしています。

私が避けようとしている手動のHTTP操作の例として:

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


3
うーん...短い答えはノーです。手動でhttpヘッダーを記述せずにpostおよびgetリクエストを処理するものが必要な場合は、サーブレットを使用できます。しかし、それはjava eeです。そのようなものを使用したくない場合は、ソケットと手動解析が唯一知っている他のオプションです。
マットフィリップス

3
これはSOの趣旨ではないことはわかっていますが、Java EE APIへの嫌悪感を再考するようにお願いします。回答のいくつかで述べたように、サーブレットAPIを利用しながらスタンドアロンアプリケーションにWebサーバーを埋め込むことができるJettyなどの非常に単純な実装があります。なんらかの理由で絶対にJava EE APIを使用できない場合は、私のコメントを無視してください:-)
Chris Thompson

1
「サーブレット」は実際には「Java EE」ではありません。これらは、メッセージアクティビティ(最近のHTTPリクエスト)に応じて、周囲のアプリケーションから呼び出すことができるプラグインを記述するための方法にすぎません。「Java SE APIのみを使用して」サーブレットホスティング環境を提供することは、まさにJettyとTomcatが行うことです。もちろん、不要な複雑さ捨てたいと思うかもしれませんが、許可された属性とGET / POSTの構成のサブセットを決定する必要があるかもしれません。ただし、特別なセキュリティや組み込みの問題を除いて、多くの場合、それだけの価値はありません。
David Tonhofer 2013年

1
決定を下す前に、このhttpサーバーのリストを検討する価値があるかもしれません。java-source.net/open-source/web-servers
ThreaT

回答:


469

Java SE 6以降、Sun Oracle JREにはHTTPサーバーが組み込まれています。com.sun.net.httpserverパッケージの概要は、関係のクラスの概要と例が含まれています。

ここに彼らのドキュメントからコピーペーストしたキックオフの例があります(それを編集しようとするすべての人に、それはコードの醜い部分なので、しないでください、これは私のものではなくコピーペーストです。さらに、変更されていない限り、引用を編集しないでください)元のソースで)。Java 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:// localhost:8000 / testに移動すると、次の応答が表示されます。

これが反応です


com.sun.*クラスの使用に関しては、一部の開発者の考えに反して、よく知られているFAQで禁止されていない理由に注意してください。開発者が「sun」パッケージを呼び出すプログラムを作成してはならない理由です。このFAQは、sun.*パッケージでsun.misc.BASE64Encoderはなく、Oracle JREによる内部使用のためのパッケージ(など)に関係します(したがって、別のJREで実行するとアプリケーションが強制終了されます)com.sun.*。Sun / Oracleは、Apacheなどの他のすべての企業と同様に、Java SE APIの上にソフトウェアを開発するだけです。com.sun.*クラスの使用は、GlassFish(Java EE 実装)、Mojarra(JSF 実装)、ジャージー(JAX-RS 実装)などの特定のJava APIの実装に関する場合にのみ推奨されます(禁止されていません)。


19
@Waldheinz:@Softwareと混同sun.*しているようにcom.sun.*。たとえば、sun.*APIのドキュメントはありますか?ここを見てください:java.sun.com/products/jdk/faq/faq-sun-packages.htmlそれは何かについて教えてくれcom.sun.*ますか?com.sun.*ただのJava APIの一部ではない、独自の公衆ソフトウェアのために使用されています。また、他のすべての企業と同様に、Java APIをベースにソフトウェアを開発します。
BalusC、2011年

4
これは、統合テストケースで使用する非常に素晴らしいhttpサーバーだと思います。ヒントをありがとう!
Andreas Petersson 2012

13
Eclipseを使用していて、「アクセス制限:必要なライブラリの制限のためにタイプHttpExchangeにアクセスできません...」などのエラーが発生した場合、stackoverflow.com / a / 10642163はそのアクセスチェックを無効にする方法を示しています。
Samuli Pahaoja 2013

13
FWIWこれはOpenJDKにも存在します。
Jason C

6
ここで参照されているクラス@jdk.Exportedは、OpenJDKソースコードでタグ付けされています。つまり、APIはパブリックと見なされ、Java 9で使用できるようになります(他の一部のcom.sun.*パッケージはProject Jigsawにより使用できなくなります)。
ジュール

42

NanoHttpdをチェックする

「NanoHTTPDは、Modified BSDライセンスの下でリリースされた、他のアプリケーションに埋め込むために設計された軽量のHTTPサーバーです。

Githubで開発されており、ビルドとユニットテストにApache Mavenを使用しています。」


4
注意点:NanoHTTPDにはツリーウォーキング攻撃に対する保護機能がない可能性があります。パブリックアドレスでサービスを提供する場合は、これを確認する必要があります。これは、リクエストGET /../../blahblah http/1.1が発行され、サーバーがWebサイトのルートの上を歩き、システムファイルランドに入る攻撃を意味します。
ローレンスドル

7
それは修正されたようです。現在のバージョンでは、403 if(uri.startsWith( "..")|| uri.endsWith( "..")|| uri.indexOf( "../")> = 0)が生成されます。
Lena Schimmel、2012年

5
これがこの質問への回答であることがわかりません。
kimathie 2017

28

com.sun.net.httpserverのソリューションは、JREの間で移植ではありません。最小限の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)

編集:これは実際に機能します!上記のコードは、Groovyか何かに似ています。ここに私がテストしたJavaへの翻訳があります:

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 2014

1
<code> class Server implements Provider <DataSource> {</ code> ...を実行してから、DataSourceの<code> getContentType()</ code>メソッド内でContent-Typeを指定できると思います。さらに、WebServiceContext:<code> @Resource WebServiceContext ctx; </ code>を挿入して、他のヘッダーを設定し、リクエストパラメータを読み取ることもできます。残念ながら、WebServiceContextを介してコンテンツタイプを設定することはできません。
gruenewa 2014

4
com.sun.net.HttpServerがJRE間で移植できない理由を説明していただけますか?
javabeangrinder 2014年

3
いいえ、そうは思いません。これは、IBMのJava実装では機能しません。そして、それが現在機能していても、内部APIは変更できます。公式APIを使用しないのはなぜですか?
gruenewa 2014年

1
このリンク:docs.oracle.com/javase/9​​/docs/api/java.xml.ws-summary.htmlは、java.xml.wsモジュールがJava 9以降非推奨であることを示しています
Erel Segal-Halevi

23

これは絶え間ない革新があり、特に小型(より小型の)デバイスの組み込みサーバーについて話す場合は常に軽量サーバーが必要な領域であるため、この質問が好きです。答えは2つの大きなグループに分類されると思います。

  1. シンサーバー:最小限の処理、コンテキスト、またはセッション処理によるサーバーアップ静的コンテンツ。
  2. 小型サーバー:表面的には、aはhttpDに似た多くのサーバー品質を備えており、フットプリントはできるだけ小さくなっています。

JettyApache Http ComponentsNettyなどのHTTPライブラリは、生のHTTP処理機能に似ていると考えるかもしれません。ラベル付けは非常に主観的であり、小規模サイトに提供するよう求められてきたものの種類によって異なります。私はこの質問の精神、特に...

  • "... HTTPリクエストを手動で解析し、HTTPレスポンスを手動でフォーマットするコードを書かずに..."

これらの生のツールを使用すると、(他の回答で説明されているように)それを行うことができます。彼らは本当に、ライト、組み込み、またはミニサーバーを作るための既成のスタイルには向いていません。ミニサーバーは、フル機能のWebサーバー(Tomcatなど)と同様の機能を提供できるものです)。シンサーバーは元のフレーズに少し近いように見えますが、サブセット機能が制限されているため、90%の確率で見栄えがよくなります。私の生のアイデアは、余分なデザインやコーディングをしなくても、75%から89%の時間で見栄えがよくなると思います。WARファイルのレベルに達した場合は、大きなサーバーが行う処理がすべて小さいように見えるbonsiサーバーに「小さな」ものを残したと思います。

シンサーバーオプション

ミニサーバーオプション:

  • Spark Java ...フィルター、テンプレートなどの多くのヘルパーコンストラクトを使用すると、良いことが可能になります。
  • MadVoc ...は盆栽になることを目指しており、そうなる可能性もある;-)

考慮すべき他のものの中で、私は認証、検証、国際化、FreeMakerや他のテンプレートツールのようなものを使用してページ出力をレンダリングすることを含みます。それ以外の場合、HTMLの編集とパラメーター化を管理すると、HTTPでの作業がnoughts-n-crossesのように見える可能性があります。当然、それはすべて、あなたがどれだけ柔軟になる必要があるかに依存します。メニュー方式のFAXマシンであれば、非常に簡単です。相互作用が多いほど、フレームワークを「より厚く」する必要があります。良い質問、頑張ってください!


21

"Jetty" WebサーバーJettyを見てください。すべての要件を満たしているように見える優れたオープンソースソフトウェア。

自分でローリングすることを主張する場合は、「httpMessage」クラスを確認してください。


jetty apiはサーブレットに依存すると思います。
評判の悪い

4
@Irreputable:いいえ、Jettyは高度にモジュール化されたWebサーバーであり、オプションのモジュールの1つとしてサーブレットコンテナーを持っています。
ローレンスドル

「サーバー機能の類似点です」-はい、「サーブレット」APIです。それは、クッキーなど、ヘッダを解析された後に、サーブレット・コンテナは、あなたのクラスを呼び出す
ジェームズ・アンダーソン

1
参考までに-JettyにはサーブレットAPIの独自の実装が付属しており、Java SEで問題なく動作します
James Anderson

4
Jettyが大きすぎ、実際の本番環境での使用が可能になる前に学習曲線が多すぎます。
ThreaT 2014年

18

昔々、私は似たようなものを探していました-軽量で完全に機能するHTTPサーバーで、簡単に組み込み、カスタマイズできました。私は2種類の潜在的な解決策を見つけました:

  • それほど軽量でも単純でもない完全なサーバー(軽量の極端な定義の場合)。
  • 完全にHTTPサーバーではないが、リモートでRFCに準拠しておらず、一般的に必要とされる基本機能をサポートしていない、非常に軽量なサーバーソケットの例。

だから... JLHTTP-Java Lightweight HTTP Serverを書くことにしました

単一の(かなり長い場合)ソースファイルとして、または依存関係のない〜50Kのjar(〜35Kを取り除いたもの)として任意のプロジェクトに埋め込むことができます。RFCに準拠するよう努めており、拡張機能を最小限に抑えながら、広範なドキュメントと多くの便利な機能を備えています。

機能には、仮想ホスト、ディスクからのファイルサービス、標準のmime.typesファイルによるMIMEタイプマッピング、ディレクトリインデックスの生成、ウェルカムファイル、すべてのHTTPメソッドのサポート、条件付きETagおよびIf- *ヘッダーのサポート、チャンク転送エンコーディング、gzip / deflateが含まれます。圧縮、基本的なHTTPS(JVMで提供)、部分的なコンテンツ(ダウンロードの継続)、ファイルアップロード用のmultipart / form-data処理、APIまたはアノテーションを介した複数のコンテキストハンドラー、パラメーター解析(クエリ文字列またはx-www-form-urlencoded)ボディなど)

私は他の人がそれが役に立つことを願っています:-)


主な方法は基本的な使用法の良い例であり、FAQは詳細の多くを説明しています。既存のドキュメントを改善するための提案がある場合は、直接私に連絡してください!
amichair



8

ほんの数行のコードでJDKとサーブレットapiだけでJ2EEサーブレットの基本的なサポートを提供するhttpserverを作成することが可能です。

これは、他の軽量コンテナよりも起動が速いため、サーブレットの単体テストに非常に役立つことがわかりました(生産には突堤を使用します)。

ほとんどの非常に軽量なhttpserverはサーブレットをサポートしていませんが、必要なので、共有したいと思いました。

以下の例は、基本的なサーブレットのサポート、またはまだ実装されていないものに対するスローと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

上記のバージョンのサーブレットAPIは、3.0以下に適合します。必要に応じて、不足しているメソッドを例に追加するだけです
f.carlsen

6

特にサーブレット機能は必要なく、リクエスト/レスポンスオブジェクトにアクセスするだけの場合は、Simpleを調べることを強くお勧めします。RESTが必要な場合は、Jerseyをその上に置くことができます。HTMLなどを出力する必要がある場合は、Freemarkerがあります。私はあなたがこの組み合わせで何ができるかが本当に好きで、学ぶべき比較的少ないAPIがあります。


+1。Simpleの背後にあるアイデアが好きです。しかし、MambaはSimpleから「埋め込み可能」機能を取り除いているため、HTTPSを使用しようとすると問題が発生します。
ThreaT 2014年

6

このコードは私たちのコードよりも優れており、追加する必要があるのは2つのライブラリーjavax.servelet.jarorg.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
質問は、純粋なJava SEソリューションを求めています。jettyがJava EE APIを実装していることがわかります。
Sridhar 2012

Jettyは標準のJava SEを使用して完全に正常に動作するため、要件に適合します。これは、実装し、それはしない、のJava EE APIの部品を必要とすることを。違いがあります。
David Tonhofer 2013年

1
これは適格ではありません。"ただのJava SEのAPIを使用して"*.Servlet.jarそして*.jetty.jar、明らかにJavaのSEの一部ではありません。
icza 2014

桟橋を設置する必要がありますか?または、これらの2つのjarファイルを除外してこのファイルを実行できますか?
Paul Preibisch

5

次のようなNIOアプリケーションフレームワークもご覧ください。

  1. 正味: http //jboss.org/netty
  2. Apache Mina:http : //mina.apache.org/またはそのサブプロジェクトAsyncWeb:http ://mina.apache.org/asyncweb/

4

上記のすべては、単一のメインスレッド化されたリクエストハンドラに関する詳細に答えます。

設定:

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

executorサービスを使用して、複数のスレッドを介して複数のリクエストを処理できます。

したがって、終了コードは次のようになります。

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

Apache Commons HttpCoreプロジェクトはどうですか?

Webサイトから:... HttpCore Goals

  • 最も基本的なHTTPトランスポートの側面の実装
  • 優れたパフォーマンスとAPIの明確さと表現力のバランス
  • 小さい(予測可能な)メモリフットプリント
  • 自己完結型ライブラリ(JRE以外の外部依存関係なし)

それはおそらく低すぎるレベルです。チャンクやエンコーディングなどのすべての概念を自分で処理したくない場合を除き、サーブレットAPIレベルでコードを呼び出すソリューションを少なくとも目指す必要があります。でも楽しいかもしれません。
David Tonhofer 2013年

2

これを試してくださいhttps://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md

このAPIは、ソケットを使用して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

かなりシンプルな組み込みJetty Javaサーバーを作成できます。

組み込みJettyは、アプリケーションを外部Jettyサーバーにデプロイするのではなく、サーバー(Jetty)がアプリケーションと一緒に出荷されることを意味します。

したがって、組み込みでないアプローチで、外部サーバー(Tomcat / Jettyなど)にデプロイされたWARファイルに組み込まれたWebアプリケーションを組み込みJettyで使用する場合は、Webアプリケーションを記述して、同じコードベースでjettyサーバーをインスタンス化します。

git cloneして使用できる組み込みJetty Javaサーバーの例:https : //github.com/stas-slu/embedded-jetty-java-server-example

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.