programing

Java SE API만 사용하는 Java의 단순한 HTTP 서버

bestcode 2022. 12. 7. 22:30
반응형

Java SE API만 사용하는 Java의 단순한 HTTP 서버

Java에서 HTTP 요청을 수동으로 해석하고 HTTP 응답을 수동으로 포맷하는 코드를 작성하지 않고 Java SE API만을 사용하여 매우 기본적인 HTTP 서버(GET/POST만 지원)를 작성하는 방법이 있습니까?는 Java SE API의 HTTP 클라이언트 을 적절하게 합니다.HttpURLConnectionHTTP?

말씀드리면, 가 가지고 있는 는 많은 것 .ServerSocket예를 들어 온라인상에서 본 적이 있는 것은, 고객이 독자적인 요구 해석/응답 포맷과 에러 처리를 실시하는 것입니다.이것은 지루하고, 에러가 발생하기 쉬우며, 포괄적이지 않을 가능성이 높기 때문에, 그러한 이유로 회피하려고 하고 있습니다.

Java SE 6 이후, 에는 HTTP 서버가 내장되어 있습니다. 태양 Oracle JREJava 9 모듈명은 입니다.패키지 개요에는 관련 클래스의 개요와 예가 포함되어 있습니다.

다음은 그들의 문서에서 복사한 킥오프 예시입니다.Java 6+에서 copy'n paste'n't 실행하기만 하면 됩니다.
말아 은 복사제 것이 소스에서 한 는 안 ).이것은 카피 페이스트이며, 제 것이 아닙니다.또한 인용문은 원래 소스에서 변경되지 않는 한 편집해서는 안 됩니다.)

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().lengthgetBytes()메서드는 명시적으로 charset을 지정해야 합니다.이 charset은 응답 헤더에서 지정합니다.아아, 비록 시작자를 잘못 인도하긴 했지만, 그것은 결국 기본적인 킥오프 사례일 뿐이다.

실행 후 http://localhost:8000/test로 이동하면 다음 응답이 나타납니다.

이것은 응답입니다.


「」의 사용에 com.sun.*classes, 이것은 일부 개발자의 생각과는 달리 왜 개발자가 '태양' 패키지를 호출하는 프로그램을 작성해서는 안 되는지에 대한 잘 알려진 FAQ에 의해 절대 금지되지 않는다는 점에 유의하시기 바랍니다.이 FAQ는sun.*: 「」:sun.misc.BASE64Encoder JRE가 아닌 에 의한 시 응용 됨),com.sun.*다른 로 Java 합니다.Sun/Oracle Apache Apache 른른른 se se 、 Java SE API 를반를를 。 이 인 것은HttpServer는 모든 "JDK"와 ".sun.* . 용용을 사용해서.com.sun.*클래스는 GlassFish(Java EE include), Mojarra(JSF include), Jersey(JAX-RS include) 등의 특정 Java API 구현과 관련된 경우에만 권장됩니다.

NanoHttpd 확인

NanoHTTPD는 다른 응용 프로그램에 내장하도록 설계된 경량 HTTP 서버로 Modified BSD 라이선스로 출시되었습니다.

Github에서 개발 중이며 빌드 및 유닛 테스트에 Apache Maven을 사용하고 있습니다."

com.sun.net.http server 솔루션은 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)

EDIT: 이것은 실제로 작동합니다!위 코드는 그루비인가 뭔가로 보입니다.테스트한 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. 신서버: 최소한의 처리, 컨텍스트 또는 세션 처리로 서버업 스태틱 콘텐츠 제공.
  2. 스몰 서버: 겉으로 보기에 에는 httpD와 같은 많은 서버 특성이 있으며 설치 공간은 최대한 작습니다.

Jetty, Apache Http Components, Netty 등의 HTTP 라이브러리는 원시 HTTP 처리 기능에 가깝다고 생각할 수 있습니다.라벨 표시는 매우 주관적이며, 소규모 사이트를 위해 주문하신 물품의 종류에 따라 달라집니다.나는 질문의 정신, 특히...에 관한 발언에서 이 구별을 한다.

  • "...HTTP 요청을 수동으로 해석하고 HTTP 응답을 수동으로 포맷하는 코드를 쓰지 않습니다.."

이러한 원시 도구를 사용하면 다른 답변에서 설명한 대로 이 작업을 수행할 수 있습니다.경량, 임베디드 또는 미니 서버를 만드는 기성품 스타일에는 적합하지 않습니다.미니 서버는 풀기능 웹 서버(예를 들어 Tomcat )와 유사한 기능을 제공합니다.종소리나 휘파람, 저볼륨, 뛰어난 퍼포먼스가 99% 항상 필요합니다.씬 서버는 raw보다 조금 더 원래의 표현에 가까운 것 같습니다.아마 서브셋 기능은 한정되어 있기 때문에 90%는 외관이 훌륭합니다.생에 대한 저의 아이디어는 추가 설계와 코딩 없이 75%에서 89%까지 저를 멋지게 보이게 하는 것입니다.WAR 파일의 레벨에 도달했을 경우는, Bonsi 서버의 「스몰」이 되어 버립니다.이러한 「스몰」은, 큰 서버의 모든 것이 작은 것처럼 보입니다.

신서버 옵션

미니 서버 옵션:

  • Java 스파크...필터, 템플릿 등 많은 도우미 구성으로 좋은 일이 가능합니다.
  • MadVoc...분재를 목표로 하고 있으며, 그럴 수도 있다;-)

그 외에 인증, 검증, 국제화, FreeMaker 등의 템플릿 툴을 사용한 페이지 출력도 고려하고 있습니다.그렇지 않으면 HTML 편집과 파라미터화를 관리하면 HTTP를 사용하는 작업이 norts-n-cross처럼 보일 수 있습니다.당연히 이 모든 것은 얼마나 유연해야 하는지에 달려있다.메뉴 방식의 FAX라면 매우 간단합니다.상호작용이 많을수록 프레임워크는 '조금씩' 해야 합니다.좋은 질문이야, 행운을 빌어!

「Jetty」 서버 「Jetty」를 봐 주세요.모든 요구에 대응할 수 있는 뛰어난 오픈 소스 소프트웨어.

독자적인 롤링을 고집하는 경우는, 「http Message」클래스를 참조해 주세요.

옛날에 저는 비슷한 것을 찾고 있었습니다.경량이지만 기능성이 뛰어난HTTP 서버를 쉽게 삽입하여 커스터마이즈할 수 있었습니다.다음 두 가지 유형의 잠재적인 솔루션을 찾았습니다.

  • 가볍고 심플한 풀 서버(경량이라는 극단적인 정의를 위해)
  • HTTP 서버라고는 할 수 없지만, 리모트에서도 RFC에 준거하고 있지 않고, 일반적으로 필요한 기본적인 기능을 서포트하고 있지 않은 Server Socket의 예에 충실합니다.

그래서 JLHTTP - Java Lightweight HTTP Server를 쓰기로 했습니다.

어느 프로젝트에나 단일 소스 파일(좀 길더라도) 또는 종속성이 없는 최대 50,000개의 jar(최대 35,000개의 제거됨)로 포함할 수 있습니다.RFC에 준거하기 위해 노력하고 있으며, 부풀어 오르는 것을 최소한으로 억제하면서 광범위한 문서와 많은 유용한 기능이 포함되어 있습니다.

기능: 가상 호스트, 디스크로부터의 파일 서비스, 표준 mime.types 파일을 통한 MIME 유형 매핑, 디렉토리 인덱스 생성, 초기 파일, 모든 HTTP 메서드 지원, 조건부 ETAG 및 If-* 헤더 지원, 청크 전송 부호화, gzip/deflate 압축, 기본 HTTPS(JVM에서 제공), 부분 콘텐츠 다운로드(계속)n), 파일 업로드를 위한 멀티파트/폼 데이터 처리, API 또는 주석을 통한 멀티콘텍스트 핸들러, 파라미터 해석(쿼리 문자열 또는 x-www-form-urlencoded 본문) 등.

다른 분들이 유용하게 써주셨으면 좋겠습니다:-)

Spark는 가장 심플합니다.다음은 퀵스타트 가이드입니다.http://sparkjava.com/

코드 몇 줄만으로 JDK와 서블릿 API만으로 J2EE 서블릿을 기본적으로 지원하는 httpserver를 만들 수 있습니다.

이것은 다른 경량 컨테이너보다 훨씬 더 빨리 시작되므로 장치 테스트에 매우 유용하다는 것을 알게 되었습니다(생산에는 제트를 사용합니다).

대부분의 초경량 http 서버는 서블릿을 지원하지 않지만 서블릿이 필요하기 때문에 공유하려고 합니다.

다음 예제에서는 기본 서블릿 지원 또는 슬로우 및 Unsupported Operation을 제공합니다.아직 구현되지 않은 항목에 대한 예외입니다.com.sun.net.http 서버를 사용합니다.기본 http 지원용 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());
    }
}

위의 답변은 모두 싱글메인 스레드 요구 핸들러에 대한 상세입니다.

설정:

 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();
        }
    }
}

또, 다음과 같은 NIO 애플리케이션 프레임워크도 참조할 수 있습니다.

  1. Netty: http://jboss.org/netty
  2. Apache Mina: http://mina.apache.org/ 또는 그 서브프로젝트 Async Web: http://mina.apache.org/asyncweb/

이 코드는 당사보다 우수합니다.javax.servelet.jar와 org.mortbay의 2lib만 추가하면 됩니다.jetty.jar.

클래스 Jetty:

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();
    }
}

특히 Servlet 기능이 필요하지 않고 단순히 요청/응답 개체에 액세스할 경우 Simple을 검토할 것을 강력히 권장합니다.REST가 필요한 경우 Jersey를 그 위에 올려놓거나 HTML 등을 출력해야 하는 경우 Freemarker가 있습니다.이 조합으로 할 수 있는 일이 너무 좋아서 배울 API가 상대적으로 적어요.

심플한 체크아웃매우 심플한 임베디드 서버이며, 다양한 조작을 서포트하고 있습니다.특히 스레드화 모델이 마음에 들어요.

최고야!

아웃 ★★★★takeshttps://github.com/yegor256/takes 를 참조해 주세요.

https://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md 를 사용해 보세요.

이 API는 소켓을 사용하여 HTTP 서버를 만듭니다.

  1. 브라우저에서 요청을 텍스트로 수신합니다.
  2. URL 정보, 메서드, 속성 등을 취득하기 위해 해석합니다.
  3. 정의된 URL 매핑을 사용하여 동적 응답을 만듭니다.
  4. 응답을 브라우저로 보냅니다.

'만들다'의.Response.java합니다.class raw raw http http 응 class 、 http 답 class 、 http 답 class class class class class

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;
}

Apache Commons HttpCore 프로젝트는 어떻습니까?

웹 사이트:...HttpCore 목표

  • 가장 기본적인 HTTP 전송 측면의 구현
  • 뛰어난 퍼포먼스와 API의 명확성과 표현성의 균형
  • 메모리 설치 공간이 작음(예측 가능)
  • 자기억제 라이브러리(JRE 이외의 외부 의존관계 없음)

꽤 간단한 임베디드 Jetty Java 서버를 작성할 수 있습니다.

Embedded Jetty는 외부 Jetty 서버에 애플리케이션을 전개하는 것이 아니라 서버(Jetty)가 애플리케이션과 함께 출하된 것을 의미합니다.

따라서 WAR 파일에 내장된 웹 앱이 외부 서버(Tomcat / Jetty 등)에 배포된 경우 내장 Jetty에서 웹 앱을 작성하고 동일한 코드 기반에 Jetty 서버를 인스턴스화합니다.

클로닝하여 사용할 수 있는 임베디드 Jetty Java 서버의 예: https://github.com/stas-slu/embedded-jetty-java-server-example

★★★com.sun.net.httpserverJava 11 시시시 java API java java java 。 해서 이렇게 수 요.HttpServer 「」의 로서 사용 , 「」jdk.httpserver모듈.https://docs.oracle.com/en/java/javase/11/docs/api/jdk.httpserver/com/sun/net/httpserver/HttpServer.html 를 참조해 주세요.

이 클래스는 단순한 HTTP 서버를 구현합니다.HttpServer는 IP 주소와 포트 번호에 바인드되어 이 주소의 클라이언트로부터의 착신 TCP 접속을 수신합니다.하위 클래스 HttpsServer는 HTTPS 요청을 처리하는 서버를 구현합니다.

그래서 그 한계를 떠나서 더 이상 사용을 피할 이유가 없다.

서버 응용 프로그램에서 제어 인터페이스를 게시하기 위해 사용합니다.User-agent header에 합니다.text/plain 등의 에 접속합니다.curl또는 다른 브라우저에 대해 보다 우아한 HTML 방식을 사용할 수 있습니다.

침착하고 침착하게.

TCP 소켓레벨의 매우 기본적인 HTTP 서버의 예를 다음에 나타냅니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class NaiveHttpServer {

  public static void main(String[] args) throws IOException {
    String hostname = InetAddress.getLocalHost().getHostName();
    ServerSocket serverSocket = new ServerSocket(8089);
    while (true) {
      Socket clientSocket = serverSocket.accept();
      PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
      BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
      String s = in.readLine();
      System.out.println(s);
      while ("\r\n".equals(in.readLine())); 
      if ("GET /hostname HTTP/1.1".equals(s)) {
        out.println("HTTP/1.1 200 OK");
        out.println("Connection: close");
        out.println("Content-Type: text/plain");
        out.println("Content-Length:" + hostname.length());
        out.println();
        out.println(hostname);
      } else {
        out.println("HTTP/1.1 404 Not Found");
        out.println("Connection: close");
        out.println();    
      }
      out.flush();
    }
  }
}

이 예에서는, 컴퓨터의 호스트명에 대응하고 있습니다.

Java 18부터는 Java 표준 라이브러리를 사용하여 간단한 웹 서버를 만들 수 있습니다.

class Main {
    public static void main(String[] args) {
        var port = 8000;
        var rootDirectory = Path.of("C:/Users/Mahozad/Desktop/");
        var outputLevel = OutputLevel.VERBOSE;
        var server = SimpleFileServer.createFileServer(
                new InetSocketAddress(port),
                rootDirectory,
                outputLevel
        );
        server.start();
    }
}

기본적으로는 지정한 루트 디렉토리의 디렉토리 목록이 표시됩니다.대신 해당 디렉토리에 index.html 파일(및 CSS 파일이나 JS 파일 등 기타 자산)을 배치하여 표시할 수 있습니다.

예(위의 디렉토리 루트로 지정된 바탕화면에 다음 항목을 배치합니다).

index.syslog:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Java 18 Simple Web Server</title>
  <link rel="stylesheet" href="styles.css">
  <script src="scripts.js" defer></script>
</head>
<body>
  <h1>I'm <i>index.html</i> in the root directory.</h1>
</body>
</html>

styles.css:

h1 { color: blue; }

scripts.syslog:

let element = document.getElementsByTagName("h1")[0];
element.style.fontSize = "48px";

언급URL : https://stackoverflow.com/questions/3732109/simple-http-server-in-java-using-only-java-se-api

반응형