Ultrakompakter HTTP Server
ulrich
2024-12-01 47e67b0aa12758fcbe6eb68f95a35ceb66c268e7
src/de/uhilger/neon/Handler.java
@@ -22,6 +22,7 @@
import de.uhilger.neon.Action.Type;
import de.uhilger.neon.entity.ActionDescriptor;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
@@ -30,6 +31,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Objekte der Klasse Handler nehmen Objekte entgegen die die Annotationen NeonActor enthalten.
@@ -91,7 +94,17 @@
    //Logger.getLogger(Handler.class.getName())
    //        .log(Level.INFO, "{0} {1} {2}", new Object[]{methodType, route, className});
    dispatcher.get(methodType).put(ad.route, ad);
    //dispatcher.get(methodType).put(ad.route, ad);
    Object adMapObj = dispatcher.get(methodType);
    if(adMapObj instanceof HashMap hashMap) {
      @SuppressWarnings("unchecked")
      HashMap<String, ActionDescriptor> map = hashMap;
      map.put(ad.route, ad);
      Logger.getLogger(Handler.class.getName()).log(Level.FINER, "ActionDescriptor route {0} className {1}", new Object[]{route, className});
    } else {
      Logger.getLogger(Handler.class.getName()).finer("ActionDescriptorMap nicht gefunden");
    }
  }
  /**
@@ -135,8 +148,9 @@
                    .getHttpContext()
                    .getPath()
                    .length());            
    Type requestMethod = Type.valueOf(exchange.getRequestMethod());
    String requestMethodStr = exchange.getRequestMethod();
    Logger.getLogger(Handler.class.getName()).log(Level.FINER, "method {0} route {1}", new Object[]{requestMethodStr, route});
    Type requestMethod = Type.valueOf(requestMethodStr);
    /*
      Es wird erst geprueft, ob zu einer bestimmten Route 
      ein Actor registriert wurde. Wenn kein Actor mit dieser 
@@ -147,32 +161,42 @@
    Object md = dispatcher.get(requestMethod);
    if (md instanceof Map) {
      int pos = route.lastIndexOf("/");
      Logger.getLogger(Handler.class.getName()).log(Level.FINER, "pos {0}", pos);
      Object o = ((Map) md).get(route);
      if (!(o instanceof ActionDescriptor)) {
        while (!found && (pos > -1)) {
          String routeRest = route.substring(0, pos);
          Logger.getLogger(Handler.class.getName()).log(Level.FINER, "pos {0} routeRest {1}", new Object[]{pos, routeRest});
          o = ((Map) md).get(routeRest);
          if (o instanceof ActionDescriptor) {
            found = true;
            handleRequest(exchange, o, routeRest, route.substring(routeRest.length()));
            handleRequest(exchange, o, routeRest, route.substring(routeRest.length()), requestMethod);
          }
          pos = routeRest.lastIndexOf("/");
        }
      } else {
        found = true;
        handleRequest(exchange, o, route, route);
        handleRequest(exchange, o, route, route, requestMethod);
      }
      if (!found) {
        Logger.getLogger(Handler.class.getName()).log(Level.FINER, "{0} not found ", route);
        o = dispatcher.get(requestMethod).get("/");
        if (o instanceof ActionDescriptor) {
          handleRequest(exchange, o, route, route);
          handleRequest(exchange, o, route, route, requestMethod);
        } else {
          // kein ActionDescriptor für '/'
          Logger.getLogger(Handler.class.getName()).log(Level.FINER, "Kein Actiondescriptor fuer '/'");
        }
      }
    } else {
      // keine Actions fuer HTTP Methode
      Logger.getLogger(Handler.class.getName()).log(Level.FINER, "Kein Actions fuer HTTP-Methode {0}", requestMethodStr);
    }
  }
  private void handleRequest(HttpExchange exchange, Object o, String route, String subroute) throws IOException {
  private void handleRequest(HttpExchange exchange, Object o, String route, String subroute, Type requestMethod) throws IOException {
    Logger.getLogger(Handler.class.getName()).log(Level.FINER, "Handle Request route {0} subroute {1}", new Object[]{route, subroute});
    ActionDescriptor ad = (ActionDescriptor) o;
    String actorClassName = ad.className;
    try {
@@ -181,13 +205,22 @@
      for (Method method : methods) {
        Action action = method.getAnnotation(Action.class);
        if (action != null) {
          if (action.route().equals("/") || action.route().startsWith(route)) {
          if ((action.route().equals("/") || action.route().startsWith(route)) && action.type().equals(requestMethod)) {
            Object[] actionArgs = getActionArgs(exchange, method, ad, subroute);
            Object actorObj = actorClass.getDeclaredConstructor().newInstance();
            addDataProvider(exchange, actorObj);
            Object antwort = method.invoke(actorObj, actionArgs);
            if (!action.handlesResponse()) {
              respond(exchange, antwort);
            @SuppressWarnings("unchecked")
            Object conObj = actorClass.getDeclaredConstructor();
            if(conObj instanceof Constructor) {
              Constructor con = (Constructor) conObj;
              Object actorObj;
              actorObj = con.newInstance();
              addDataProvider(exchange, actorObj);
              Object antwort = method.invoke(actorObj, actionArgs);
              if (!action.handlesResponse()) {
                respond(exchange, antwort);
              }
            } else {
              // kein Konstruktor
              Logger.getLogger(Handler.class.getName()).info("Kein Konstruktor gefunden");
            }
          }
        }
@@ -196,6 +229,7 @@
            InstantiationException | IllegalAccessException | IllegalArgumentException | 
            InvocationTargetException ex) {
      // Klasse nicht gefunden. Muss das geloggt oder sonstwie behandel werden?
      Logger.getLogger(Handler.class.getName()).finer("Kein passende Actor-Klasse gefunden");
    }
    //}
  }