web-dev-qa-db-fra.com

Botte à ressort avec redirection avec une seule page angular2

J'ai une application angulaire simple page avec démarrage à ressort. Il ressemble à ce qui suit

src
  main
  Java
    controller
       HomeController
       CustomerController
       OtherController
  webapp
    js/angular-files.js
    index.html

Le démarrage du printemps est correctement défini par défaut sur le dossier webapp et sert le fichier index.html. 

Ce que je cherche à faire est 

1) Pour chaque demande REST locale pas commençant par/api, écraser et rediriger vers la Webapp/index.html par défaut. Je prévois de servir n'importe quoi/api aux contrôleurs de printemps.

2) Existe-t-il un moyen de préfixer tous les contrôleurs Avec api afin que je n'ai pas à écrire api à chaque fois. 

par exemple. 

@RequestMapping("/api/home") can write shorthand in code  @RequestMapping("/home")

ou 

@RequestMapping("/api/other-controller/:id") can write shorthand  @RequestMapping("/other-controller/:id")

Edit .. Plus de notes pour expliquer ci-dessus mieux

Je cherche chaque demande d’API 1) http: // localhost: 8080/api/home keep api avec api et résolvez de corriger le contrôleur et renvoyez json. 

Cependant si quelqu'un entre url comme http: /// localhost/some-url ou http: /// localhost/some-other/123/url Ensuite, il servira la page index.html et la conservera l'URL.

 enter image description here

Autres moyens de le faire - essayez d'ajouter #ErrorViewResolverSpringboot/Angular2 - Comment gérer les URL HTML5?

8
Robbo_UK

Essayez ceci à la place

@SpringBootApplication
@RestController
class YourSpringBootApp { 

    // Match everything without a suffix (so not a static resource)
    @RequestMapping(value = "/**/{path:[^.]*}")       
    public String redirect() {
        // Forward to home page so that route is preserved.
        return "forward:/";
    }
}
10
Eduardo Eljaiek

Si vous êtes fatigué d'essayer de résoudre ce problème en suivant autant de solutions contradictoires, regardez ici !!

Après des heures upon heures essayant de suivre tous les conseils épars de dizaines de débordements de pile et d'articles de blog, j'ai finalement trouvé l'application minimale PURE Spring Boot + angular 6 permettant de toujours rediriger vers index.html après une actualisation d'un fichier. page non-root TOUT en conservant tous vos chemins de noeud final REST API. Pas de @EnableWebMvc, pas de @ControllerAdvice, pas de modifications apportées à application.properties, pas de modifications personnalisées ResourceHandlerRegistry, simplement de la simplicité:

Pré-requis très important

Vous * devez * inclure la sortie de ng build dans le dossier resources/static de Spring. Vous pouvez accomplir cela via le maven-resources-plugin. Apprenez ici: Copie de plusieurs répertoires de ressources dans des répertoires cibles indépendants avec maven

Code

@Controller
@SpringBootApplication
public class MyApp implements ErrorController {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "forward:/index.html";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

Raisonnement

  • L'inclusion de la sortie de ng-build dans resources/static au moment de la construction permet aux redirections de vue de printemps ("forward:/index.html") de réussir. Il semble que spring ne puisse rediriger vers rien en dehors du dossier de ressources. Par conséquent, si vous essayez d'accéder à des pages situées à la racine du site, cela ne fonctionnera pas.
  • Avec la fonctionnalité par défaut (c'est-à-dire aucun ajout de @EnableWebMvc ou modification de application.properties), naviguer vers / sert automatiquement l'index.html (si ce dernier a été inclus dans le dossier resources/static), il n'est donc pas nécessaire d'y apporter des modifications.
  • Avec la fonctionnalité par défaut (comme indiqué ci-dessus), toute erreur rencontrée dans une application de démarrage printanier achemine vers /error et implémente ErrorController annule ce comportement: vous l'avez deviné: routez vers index.html, ce qui permet à Angular de prendre en charge le routage.

Remarques

Ok, commençons par la partie simple de votre question:

Existe-t-il un moyen de préfixer tous les contrôleurs avec api afin que je n'ai pas à écrire api à chaque fois?

La réponse est oui, il suffit de marquer votre contrôleur avec une annotation "globale" @RequestMapping, par exemple:

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public String hello(){
      return "hello simple controller";
   }

   @RequestMapping("/hello2") 
   public String hello2(){
      return "hello2 simple controller";
   }
}

Dans l'exemple ci-dessus, vous pouvez appeler la méthode hello avec l'URL suivante: /api/hello

et la deuxième méthode avec cette URL: /api/hello2

C'est comme ça que je n'ai pas eu à marquer chaque méthode avec le préfixe /api.

Passons maintenant à la partie plus complexe de votre question: 

comment effectuer une redirection si la requête ne commence pas par le préfixe /api?

Vous pouvez le faire en renvoyant un code d’état HTTP (302) de redirection. Après tout, angularJs "parle" REST de manière native, vous ne pouvez donc pas forcer une redirection à partir du code Java/Spring comme vous le faites auparavant. 

Ensuite, il vous suffit de renvoyer un message HTTP avec le code d’état 302 et de procéder à la redirection sur votre angularJS.

Par exemple:

Sur AngularJS:

var headers = {'Content-Type':'application/json', 'Accept':'application/json'}

var config = {
    method:'GET'
    url:'http://localhost:8080/hello',
    headers:headers
};

http(config).then(
    function onSuccess(response){
        if(response.status == 302){
            console.log("Redirect");
            $location("/")
        }
}, function onError(response){
    console.log("An error occured while trying to open a new game room...");
});

Au printemps:

@RestController
@RequestMapping("/api")
public class ApiController{

   @RequestMapping("/hello") 
   public ResponseEntity<String> hello(){
      HttpHeaders header = new HttpHeaders();
      header.add("Content-Type", "application/json");
      return new ResponseEntity<String>("", header, HttpStatus.FOUND);
   }
}

bien sûr, vous devrez l’adapter à votre projet.

0
Moshe Arad

Pour toute l'application, vous pouvez ajouter un chemin de contexte dans application.properties

server.contextPath =/api

Il ajoutera "/ api" à chaque URL demandée après http: // localhost: 8080/api/home

Pour la redirection,

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addRedirectViewController("/", "/home");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    super.addViewControllers(registry);
}

Mettez ce groupe de code dans WebMVCConfig.Java

0
Anksss

Tout ce que vous devez essayer est de mettre le index.html à src/main/resources/static/

Voir Exemple:https://github.com/reflexdemon/shop/arborescence/master/src/main/resources/static

Dans mon package.josn, j'essaie de le copier à cet endroit.

Voir PackageJSON:https://github.com/reflexdemon/shop/blob/master/package.json#L14

0
reflexdemon
@Controller
public class RedirectController {
    /*
     * Redirects all routes to FrontEnd except: '/', '/index.html', '/api', '/api/**'
     */
    @RequestMapping(value = "{_:^(?!index\\.html|api).*$}")
    public String redirectApi() {
        return "forward:/";
    }
}
0
Anton

Dans le bean @Configuration, vous pouvez ajouter un ServletRegistrationBean pour créer le serveur de ressort pour la requête/api/* uniquement. Dans le contrôleur, vous n'avez pas besoin de l'ajouter.

@Bean
public ServletRegistrationBean dispatcherRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
            dispatcherServlet());
    registration.addUrlMappings("/api/*");
    registration.setLoadOnStartup(1);
    registration.setName("mvc-dispatcher");
    return registration;
}
0
Jane