Eenvoudige HTTP-server in Java met alleen Java SE API

Is er een manier om een zeer eenvoudige HTTP-server (die alleen GET/POST ondersteunt) in Java te maken met alleen de Java SE API, zonder code te schrijven om HTTP-verzoeken handmatig te ontleden en HTTP-antwoorden handmatig te formatteren? De Java SE API vat de HTTP-clientfunctionaliteit mooi samen in HttpURLConnection, maar is er een analoog voor HTTP-serverfunctionaliteit?

Voor alle duidelijkheid, het probleem dat ik heb met veel ServerSocket-voorbeelden die ik online heb gezien, is dat ze hun eigen verzoekparsering/antwoordopmaak en foutafhandeling doen, wat vervelend is, fout -gevoelig, en waarschijnlijk niet volledig, en om die redenen probeer ik het te vermijden.


Antwoord 1, autoriteit 100%

Sinds Java SE 6 is er een ingebouwde HTTP-server in SunOracle JRE. De com.sun.net.httpserverpakketoverzichtgeeft een overzicht van de betrokken klassen en bevat voorbeelden.

Hier is een voorbeeld van een aftrap gekopieerduit hun documenten (voor alle mensen die het toch proberen te bewerken, want het is een lelijk stuk code, doe dat alsjeblieft niet, dit is kopiëren en plakken, niet de mijne, bovendien moet u citaten nooit bewerken, tenzij ze in de oorspronkelijke bron zijn gewijzigd). Je kunt het gewoon kopiëren en plakken op 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();
        }
    }
}

Opgemerkt moet worden dat het response.length()-gedeelte in hun voorbeeld slecht is, het had response.getBytes().lengthmoeten zijn. Zelfs dan moet de methode getBytes()expliciet de tekenset specificeren die u vervolgens opgeeft in de antwoordheader. Helaas, hoewel misleidend voor starters, is het toch maar een eenvoudig voorbeeld van een aftrap.

Voer het uit en ga naar http://localhost:8000/testen je ziet het volgende antwoord :

Dit is het antwoord


Wat betreft het gebruik van com.sun.*Classes, noteer dat dit is, in strijd met wat sommige ontwikkelaars denken, absoluut niet verboden door de bekende FAQ Waarom ontwikkelaars geen programma’s moeten schrijven die ‘Sun’-pakketten noemen. Die FAQ betreft de sun.*Pakket (zoals sun.misc.BASE64Encoder) voor intern gebruik door de Oracle JRE (die dus uw aanvraag zou doden wanneer u het opdoet Een andere JRE), niet de com.sun.*PAKKET. Sun / Oracle ontwikkelt ook gewoon software op de top van de Java SE API zelf zoals elk ander bedrijf zoals Apache enzovoort. Met com.sun.*Classes is alleen ontmoedigd (maar niet verboden) wanneer het een implementatie betreft van een bepaalde Java-API, zoals Glassfish (Java EE IM), Mojarra (JSF-implicatie), Jersey (JAX-RS IM), enz.


Antwoord 2, Autoriteit 9%

Uitchecken nanohttpd

nanohttpd is een lichtgewicht HTTP-server die is ontworpen voor het insluiten van andere toepassingen, vrijgegeven onder een gemodificeerde BSD-licentie.

Het wordt ontwikkeld in Github en maakt gebruik van Apache Maven voor Builds & AMP; Unit Testing “


Antwoord 3, Autoriteit 6%

Ik vind deze vraag leuk omdat dit een gebied is waar er continue innovatie is en er is altijd een behoefte aan een lichte server te hebben, vooral wanneer het gaat om embedded servers in kleine (ER) -apparaten. Ik denk dat antwoorden in twee brede groepen vallen.

  1. Dun-server : Server-up statische inhoud met minimale verwerking, context of sessie verwerking.
  2. Small-server : ogenschijnlijk a heeft veel httpd-achtige server-kwaliteiten met als kleine voetafdruk terwijl je weg kunt komen.

Hoewel ik HTTP-bibliotheken zou kunnen overwegen zoals: Jetty, Apache Http-componenten, Nettyen anderen om meer op ruwe HTTP-verwerkingsfaciliteiten te lijken. De etikettering is erg subjectief en hangt af van het soort dingen dat u voor kleine sites moet leveren. Ik maak dit onderscheid in de geest van de vraag, met name de opmerking over…

  • “…zonder code te schrijven om HTTP-verzoeken handmatig te ontleden en HTTP-antwoorden handmatig op te maken…”

Met deze onbewerkte tools kunt u dat doen (zoals beschreven in andere antwoorden). Ze lenen zich niet echt voor een kant-en-klare stijl van het maken van een lichte, embedded of miniserver. Een miniserver is iets dat je dezelfde functionaliteit kan geven als een volwaardige webserver (zoals bijvoorbeeld Tomcat) zonder toeters en bellen, laag volume, goede prestaties 99% van de tijd. Een thin-server lijkt dichter bij de oorspronkelijke frasering, net iets meer dan rauw, misschien met een beperkte subset-functionaliteit, genoeg om je er 90% van de tijd goed uit te laten zien. Mijn idee van raw zou zijn dat ik er 75% – 89% van de tijd goed uitzie zonder extra ontwerp en codering. Ik denk dat als/wanneer je het niveau van WAR-bestanden bereikt, we de “kleine” voor bonsi-servers hebben gelaten, dat lijkt op alles wat een grote server doet, kleiner.

Thin-server opties

Miniserveropties:

  • Spark Java… Goede dingen zijn mogelijk met veel hulpconstructies zoals filters, sjablonen , enz.
  • MadVoc… wil bonsai zijn en zou zo kunnen zijn 😉

Ik denk onder andere aan authenticatie, validatie, internationalisering, met iets als FreeMakerof een andere sjabloontool om pagina-uitvoer weer te geven. Anders zal het beheren van HTML-editing en parametrering het werken met HTTP er waarschijnlijk als nullen-n-kruisjes uit laten zien. Het hangt er natuurlijk allemaal vanaf hoe flexibel je moet zijn. Als het een menugestuurd faxapparaat is, kan het heel eenvoudig zijn. Hoe meer interacties, hoe ‘dikker‘ uw framework moet zijn. Goede vraag, succes!


Antwoord 4, autoriteit 5%

De com.sun.net.httpserver-oplossing is niet overdraagbaar tussen JRE’s. Het is beter om de officiële webservices-API in javax.xml.wste gebruiken om een minimale HTTP-server op te starten…

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: dit werkt echt! De bovenstaande code lijkt op Groovy of zoiets. Hier is een vertaling naar Java die ik heb getest:

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

Antwoord 5, autoriteit 5%

Bekijk de “Jetty” webserver Jetty. Schitterend stuk Open Source-software dat aan al uw eisen lijkt te voldoen.

Als je erop staat om je eigen te rollen, kijk dan eens naar de “httpMessage”-klasse.


Antwoord 6, autoriteit 4%

Er was eens naar iets soortgelijks op zoek – een lichtgewicht maar volledig functionele HTTP-server die ik gemakkelijk kon insluiten en aanpassen. Ik heb twee soorten mogelijke oplossingen gevonden:

  • Volledige servers die niet zo licht of eenvoudig zijn (voor een extreme definitie van lichtgewicht.)
  • Echt lichtgewicht servers die niet echt HTTP-servers zijn, maar verheerlijkte ServerSocket-voorbeelden die niet eens op afstand RFC-compatibel zijn en geen algemeen benodigde basisfunctionaliteit ondersteunen.

Dus… ik wilde JLHTTP – The Java Lightweight HTTP Serverschrijven.

Je kunt het in elk project insluiten als een enkel (hoewel vrij lang) bronbestand, of als een ~50K jar (~35K gestript) zonder afhankelijkheden. Het streeft ernaar om RFC-compatibel te zijn en bevat uitgebreide documentatie en veel handige functies, terwijl het opzwellen tot een minimum wordt beperkt.

Functies zijn onder meer: virtuele hosts, bestandsserving vanaf schijf, toewijzingen van mime-types via standaard mime.types-bestand, genereren van directory-indexen, welkomstbestanden, ondersteuning voor alle HTTP-methoden, voorwaardelijke ETags en If-*-headerondersteuning, gesegmenteerde overdrachtcodering, gzip/deflate-compressie, basis HTTPS (zoals geleverd door de JVM), gedeeltelijke inhoud (vervolg downloaden), multipart/form-data handling voor bestandsuploads, meerdere context-handlers via API of annotaties, parameterparsing (querystring of x-www- body-urlencoded), enz.

Ik hoop dat anderen het nuttig vinden 🙂


Antwoord 7, autoriteit 2%

Spark is de eenvoudigste, hier is een snelstartgids: http://sparkjava.com/


Antwoord 8, autoriteit 2%

Alle bovenstaande antwoorden details over Single main threaded Request Handler.

instelling:

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

Laat meerdere verzoeken toe via meerdere threads met behulp van de executeur-service.

Dus de eindcode ziet er ongeveer zo uit als hieronder:

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

Antwoord 9, Autoriteit 2%

Het is mogelijk om een ​​HTTPSERVER te maken die basisondersteuning biedt voor J2EE-sermen met alleen de JDK en de Servlet API in een enkele regels van de code.

Ik heb dit erg handig gevonden voor eenheidstestservlets, omdat het veel sneller begint dan andere lichtgewicht containers (we gebruiken steiger voor productie).

De meeste zeer lichte httpservers bieden geen ondersteuning voor servlets, maar we hebben ze nodig, dus ik dacht dat ik zou delen.

Het onderstaande voorbeeld biedt een basis serervlet-ondersteuning of gooit en niet-ondersteundeOperionException voor dingen die nog niet worden geïmplementeerd. Het maakt gebruik van de COM.SUN.net.httpserver.httpserver voor basishttp-ondersteuning.

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

Antwoord 10

U kunt ook eens een NIO-toepassingsframework bekijken, zoals:

  1. Netty: http://jboss.org/netty
  2. Apache Mina: http://mina.apache.org/of het subproject AsyncWeb: http://mina.apache.org/asyncweb/

Antwoord 11

Deze code is beter dan de onze, je hoeft maar 2 bibliotheken toe te voegen: javax.servelet.jaren org.mortbay.jetty.jar.

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

Serveren Klasse:

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

Antwoord 12

Ik kan het ten zeerste aanbevelen om Simplete bekijken, vooral als je geen Servlet-mogelijkheden nodig hebt, maar toegang tot de request/repons objecten. Als je REST nodig hebt, kun je Jersey er bovenop plaatsen, als je HTML of iets dergelijks moet uitvoeren, is er Freemarker. Ik vind het geweldig wat je met deze combinatie kunt doen, en er is relatief weinig API te leren.


Antwoord 13

afrekenen Eenvoudig. het is een vrij eenvoudige insluitbare server met ingebouwde ondersteuning voor een heel scala aan bewerkingen. Ik ben vooral dol op het inrijgmodel..

Geweldig!


Antwoord 14

Bekijk takes. Kijk op https://github.com/yegor256/takesvoor snelle info


Antwoord 15

Probeer dit https://github.com /devashish234073/Java-Socket-Http-Server/blob/master/README.md

Deze API heeft een HTTP-server gemaakt met sockets.

  1. Het krijgt een verzoek van de browser als tekst
  2. parseert het om URL-info, methode, kenmerken, enz.
  3. op te halen

  4. creëert dynamische respons met behulp van de gedefinieerde URL-mapping
  5. verzendt het antwoord op de browser.

Hier bijvoorbeeld hoe de constructeur in de Response.javaklasse een onbewerkte reactie in een HTTP-reactie converteert:

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

Antwoord 16

Hoe zit het met Apache Commons HTTPCORE project?

Vanaf de website: …
Httpcore-doelen

  • Implementatie van de meest fundamentele HTTP-transportaspecten
  • Balans tussen goede prestaties en de Clarity & AMP; expressiviteit van
    Api
  • kleine (voorspelbare) geheugenvoetafdruk
  • self-contained library (geen externe afhankelijkheden buiten JRE)

Antwoord 17

U kunt een vrij eenvoudige ingebedde steiger Java-server.

Embedded-steiger betekent dat de server (steiger) samen met de toepassing wordt verzonden in tegenstelling tot het inzetten van de toepassing op externe steigerserver.

Dus als u in niet-ingesloten aanpak bent ingebouwd, is uw webApp ingebouwd in het War-bestand dat wordt ingezet in een externe server (tomcat / Steiger / enz.), In ingesloten steiger Schrijf de WebApp en meneer de steigerserver in dezelfde codebasis.

Een voorbeeld voor ingesloten JAVA-server die u Git Clone en gebruik: https://github.com/stas-slu/embedded-jetty-java-server-Example

Other episodes