简体   繁体   中英

How to make my actor work in my routes Akka HTTP in java?

I'm a beginner in Akka HTTP and I don't know very well how to use an actor on routes which use an actor in the routes since the examples in the Akka Http are all very particular. I want to make a user enter a number which is 5 integer and 1 letter. If it is respecting this, it will show the number, if it is not, the system actor will send a message.

I used a lot of different manners to make it function but I have also a problem with the actor and a problem with the if (numCP.contains("[0-9]{7}[AZ]{1}")) which is never respected even if I change it to 1 integer and I write 1 integer.

Here is my code excuse me for the lot of comment:

public class HttpServerActorCP extends AllDirectives {
    public static ActorSystem<Printer.PrintMe> system = ActorSystem.create(Behaviors.empty(), "routes");
    //public static ActorRef<Printer.PrintMe> ref = system;;

    public boolean isnumCP(String numCP) {
        // if (numCP.contains("[0-9]{7}+[a-zA-Z]{1}") && numCP.length() == 8) {
        if (numCP.contains("[0-9A-Z]+") && numCP.length() == 8) {
            return true;
        }
        return false;
    }

    final Function<Entry, String> appel = entry -> entry.getKey() + " = '" + entry.getValue() + "'";
    
    

    /*
     * private CompletionStage<Optional<String>> getJob(Long jobId) { return
     * AskPattern.ask( Nouv, replyTo -> String, Duration.ofSeconds(3),
     * system.scheduler()); }
     */

    

    public static void main(String[] args) throws Exception {

        final Http http = Http.get(system);

        HttpServerActorCP app = new HttpServerActorCP();

        final CompletionStage<ServerBinding> binding = http.newServerAt("localhost", 8080).bind(app.createRoute());

        System.out.println("Server online at http://localhost:8080/\nPress RETURN to stop...");
        System.in.read();

        binding.thenCompose(ServerBinding::unbind).thenAccept(unbound -> system.terminate());
    }

    @SuppressWarnings("unlikely-arg-type")
    private Route createRoute() {
        /*final Route route1 = extractRequestContext(ctx -> {​​
              ctx.getLog().debug("Using access to additional context available, like the logger.");
        final HttpRequest request = ctx.getRequest();
        
        return complete("Request method is " + request.method().name() +" and content-type is " + request.entity().getContentType());
              }​ ​
                );// tests:
*/
            
        /*
         * final Route route2 = mapRequest(req -> req.withMethod(HttpMethods.POST), ()
         * -> extractRequest(req -> complete("The request method was " +
         * req.method().name())));
         */
            
        return concat(
        /*
         * path(segment("cem").slash("file").slash(integerSegment()), numCP ->
         * anyOf(Directives::get, Directives::put, () -> extractMethod(methode -> //
         * complete("Requête reçu de la part de "+ numCP + " avec la méthode "
         * +methode))),
         */
//          pathPrefix("cem", () ->
//          concat(
                // put(() ->
                // path("file", () -> {//{if (file.isPresent){ return
                /*
                 * mapRequest(req -> req.withMethod(HttpMethods.POST), () -> extractRequest(req
                 * -> complete("The request method was " + req.method().name()
                 * //+requestEntityPresent(req) ))),
                 */
                parameterList(numCP -> {
                    // if (numCP.isnumCP == true) {
                    // if (numCP.contains("[0-9]{7}+[a-zA-Z]{1}") //&& ((CharSequence)
                    // numCP).length() == 8
                    if (numCP.contains("[0-9]{7}[A-Z]{1}")
                    // if (isnumCP(numCP) == true
                    ) {
                    // parameterRequiredValue(StringUnmarshallers.BOOLEAN, true, "action", () ->

                    // parameter("path", path ->
                    final String pString = numCP.stream().map(arg0 -> {
                        try {
                            return appel.apply(arg0);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        return null;
                    }).collect(Collectors.joining(", "));

                    // return complete("Le numCP est " +numCP+ " il a les droits d'accès à "// +path
                    return complete("Les parametres sont " + pString);
                    //ref.tell(new Printer.PrintMe("");
                    }
                 else { return system.tell(new Printer.PrintMe("Entrez un bon numero de CP"));//("Entrez un bon numéro CP")
                 
                 }; 
                     
                    
                })

Here is my Printer class for the message since I couldn't make my actors work only with Strings:

public class Printer {
      public static class PrintMe {
        public final String message;

        public PrintMe(String message) {
          this.message = message;
        }
      }

      public static Behavior<PrintMe> create() {
        return Behaviors.setup(
            context ->
                Behaviors.receive(PrintMe.class)
                    .onMessage(
                        PrintMe.class,
                        printMe -> {
                          context.getLog().info(printMe.message);
                          return Behaviors.same();
                        })
                    .build());
      }
    }

The error I have in the line when I use tell is "Cannot return a void result". So could you help me to know what is the problem with that using of the actor and why the if contains doesn't work (I always have the message "entrez un on numero de cp")?

The String.contains function doesn't work with regexes, just use simple string comparison. To use regexes you have to use the java.util.regex.Pattern like:

// import java.util.regex.Pattern;
Pattern p = Pattern.compile("[0-9]{7}+[a-zA-Z]");
String badInput = "123456a";
String goodInput = "1234567b";
System.out.println(badInput + " " + p.matcher(badInput).matches());
System.out.println(goodInput + " " + p.matcher(goodInput).matches());

As for the returning Void error. actorSystem.tell used a fire and forget way of sending the message to the actor. You have to use ask to expect an answer. It will return a Future though

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM