Java SE API만 사용하는 Java의 단순한 HTTP 서버
Java에서 HTTP 요청을 수동으로 해석하고 HTTP 응답을 수동으로 포맷하는 코드를 작성하지 않고 Java SE API만을 사용하여 매우 기본적인 HTTP 서버(GET/POST만 지원)를 작성하는 방법이 있습니까?는 Java SE API의 HTTP 클라이언트 을 적절하게 합니다.HttpURLConnection
HTTP?
말씀드리면, 가 가지고 있는 는 많은 것 .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().length
getBytes()
메서드는 명시적으로 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);
}
}
저는 이 질문을 좋아합니다.왜냐하면 이 분야에서는 끊임없는 혁신이 이루어지고 있으며, 특히 소형 디바이스의 임베디드 서버에 대해 이야기할 때는 항상 라이트 서버가 필요하기 때문입니다.내 생각에 답은 크게 두 그룹으로 나뉜다.
- 신서버: 최소한의 처리, 컨텍스트 또는 세션 처리로 서버업 스태틱 콘텐츠 제공.
- 스몰 서버: 겉으로 보기에 에는 httpD와 같은 많은 서버 특성이 있으며 설치 공간은 최대한 작습니다.
Jetty, Apache Http Components, Netty 등의 HTTP 라이브러리는 원시 HTTP 처리 기능에 가깝다고 생각할 수 있습니다.라벨 표시는 매우 주관적이며, 소규모 사이트를 위해 주문하신 물품의 종류에 따라 달라집니다.나는 질문의 정신, 특히...에 관한 발언에서 이 구별을 한다.
- "...HTTP 요청을 수동으로 해석하고 HTTP 응답을 수동으로 포맷하는 코드를 쓰지 않습니다.."
이러한 원시 도구를 사용하면 다른 답변에서 설명한 대로 이 작업을 수행할 수 있습니다.경량, 임베디드 또는 미니 서버를 만드는 기성품 스타일에는 적합하지 않습니다.미니 서버는 풀기능 웹 서버(예를 들어 Tomcat 등)와 유사한 기능을 제공합니다.종소리나 휘파람, 저볼륨, 뛰어난 퍼포먼스가 99% 항상 필요합니다.씬 서버는 raw보다 조금 더 원래의 표현에 가까운 것 같습니다.아마 서브셋 기능은 한정되어 있기 때문에 90%는 외관이 훌륭합니다.생에 대한 저의 아이디어는 추가 설계와 코딩 없이 75%에서 89%까지 저를 멋지게 보이게 하는 것입니다.WAR 파일의 레벨에 도달했을 경우는, Bonsi 서버의 「스몰」이 되어 버립니다.이러한 「스몰」은, 큰 서버의 모든 것이 작은 것처럼 보입니다.
신서버 옵션
미니 서버 옵션:
그 외에 인증, 검증, 국제화, 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 애플리케이션 프레임워크도 참조할 수 있습니다.
- Netty: http://jboss.org/netty
- 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가 상대적으로 적어요.
심플한 체크아웃매우 심플한 임베디드 서버이며, 다양한 조작을 서포트하고 있습니다.특히 스레드화 모델이 마음에 들어요.
최고야!
아웃 ★★★★takes
https://github.com/yegor256/takes 를 참조해 주세요.
https://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md 를 사용해 보세요.
이 API는 소켓을 사용하여 HTTP 서버를 만듭니다.
- 브라우저에서 요청을 텍스트로 수신합니다.
- URL 정보, 메서드, 속성 등을 취득하기 위해 해석합니다.
- 정의된 URL 매핑을 사용하여 동적 응답을 만듭니다.
- 응답을 브라우저로 보냅니다.
'만들다'의.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.httpserver
Java 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
'programing' 카테고리의 다른 글
반복하는 동안 목록에서 항목을 제거하려면 어떻게 해야 합니까? (0) | 2022.12.07 |
---|---|
데이터베이스에 Enum을 저장하는 방법 (0) | 2022.12.07 |
macOS에서의 my.cnf 파일 위치 (0) | 2022.12.07 |
Google이 JSON 응답 앞에 (1)을 추가하는 이유는 무엇입니까? (0) | 2022.12.07 |
PHP에서 구성 파일 만들기 (0) | 2022.12.07 |