wake-up-neo.com

Spring Boot mit Umleitung mit einzelner Seite angle2

Ich habe eine einzige eckige App mit Federstiefel. Es sieht wie folgt aus

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

Beim Spring-Start wird standardmäßig der Ordner webapp verwendet und die index.html-Datei bereitgestellt. 

Was ich suche, ist 

1) Für jede lokale REST -Anforderung not, die mit/api beginnt, wird sie überschrieben und zur Standard-Webapp/index.html umgeleitet. Ich habe vor, den Federsteuerungen etwas/api zu servieren.

2) Gibt es eine Möglichkeit, alle Controller Mit einem API vorzustellen, so dass ich nicht jedes Mal ein API schreiben muss. 

z.B. 

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

oder 

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

Edit .. Weitere Hinweise, um oben besser zu erklären

Ich suche nach jeder API-Anfrage Z. 1) http: // localhost: 8080/api/home api mit api beibehalten und auflösen, Controller korrigieren und json zurückgeben. 

Wenn jedoch jemand eine URL wie http: /// localhost/some-url oder http: /// localhost/some-other/123/url eingibt, wird die index.html-Seite bereitgestellt und beibehalten die URL.

 enter image description here

Alternative Möglichkeiten - Versuchen Sie, #ErrorViewResolverSpringboot/Angular2 - Wie werden HTML5-URLs behandelt?

8
Robbo_UK

Für jede lokale REST - Anforderung, die nicht mit/api beginnt, wird sie überschrieben und auf die standardmäßige webapp/index.html umgeleitet. Ich habe vor, den Federsteuerungen etwas/api zu servieren.

Update 15/05/2017

Lassen Sie mich Ihre Frage für andere Leser umformulieren. (Korrigieren Sie mich, wenn Sie falsch verstanden werden)

Hintergrund
Verwenden von Spring Boot und statische Ressourcen aus Klassenpfad

Voraussetzung
Alle 404non api -Anfragen sollten zu index.html umgeleitet werden.

NON API - bedeutet Anfragen, bei denen die URL nicht mit /api beginnt.
API - 404 sollte 404 wie üblich werfen.

Beispielantwort
/api/something - wirft 404
/index.html - wird Server index.html
/something - wird zu index.html weitergeleitet 

Meine Lösung

Lassen Sie die Spring-MVC-Ausnahmen werfen, wenn für die angegebene Ressource kein Handler verfügbar ist.

Folgendes zu application.properties hinzufügen

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

Fügen Sie eine ControllerAdvice wie folgt hinzu

@ControllerAdvice
public class RedirectOnResourceNotFoundException {

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public Object handleStaticResourceNotFound(final NoHandlerFoundException ex, HttpServletRequest req, RedirectAttributes redirectAttributes) {
        if (req.getRequestURI().startsWith("/api"))
            return this.getApiResourceNotFoundBody(ex, req);
        else {
            redirectAttributes.addFlashAttribute("errorMessage", "My Custom error message");
            return "redirect:/index.html";
        }
    }

    private ResponseEntity<String> getApiResourceNotFoundBody(NoHandlerFoundException ex, HttpServletRequest req) {
        return new ResponseEntity<>("Not Found !!", HttpStatus.NOT_FOUND);
    }
}

Sie können die Fehlermeldung nach Ihren Wünschen anpassen.

Gibt es eine Möglichkeit, alle Controller mit einer API vorzustellen, so dass ich sie nicht jedes Mal schreiben muss.

Dazu können Sie eine BaseController erstellen und den RequestMapping-Pfad auf /api setzen.

Beispiel

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/api")
public abstract class BaseController {}

Und erweitern Sie diese BaseController und stellen Sie sicher, dass nicht die untergeordnete Klasse mit @RequestMapping kommentiert.

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstTestController extends BaseController {
    @RequestMapping(path = "/something")
    public String sayHello() {
        return "Hello World !!";
    }

}

Vorherige Antwort

Sie können eine Filter erstellen, die zu /index.html weiterleitet, wenn der Anforderungspfad nicht mitWith /api startet.

// CODE REMOVED. Check Edit History If you want.
14
ansh

Versuchen Sie es stattdessen

@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

Wenn Sie es leid sind zu versuchen, dieses Problem zu lösen, indem Sie so vielen widersprüchlichen Lösungen folgen - schauen Sie hier !!

Nach Stunden {nach Stunden, die versuchten, all den vereinzelten Ratschlägen von Dutzenden von Stapelüberläufen und Blogbeiträgen zu folgen, habe ich endlich die Mindestanwendung für PURE Spring Boot + Winkel 6 gefunden, um nach einer Aktualisierung immer zu index.html umzuleiten auf einer Nicht-Root-Seite, während Sie alle Ihre REST API-Endpunktpfade beibehalten. Kein @EnableWebMvc, kein @ControllerAdvice, keine Änderungen an application.properties, keine benutzerdefinierten ResourceHandlerRegistry-Modifikationen, nur Einfachheit:

Sehr wichtige Voraussetzung

Sie * must * include die Ausgabe von ng build in den resources/static-Ordner von Spring. Sie können dies über den maven-resources-plugin erreichen. Erfahren Sie hier: Kopieren von mehreren Ressourcenverzeichnissen in unabhängige Zielverzeichnisse mit 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;
    }
}

Argumentation

  • Durch das Einfügen der Ausgabe von ng-build in resources/static zur Build-Zeit können Spring View-Weiterleitungen ("forward:/index.html") erfolgreich ausgeführt werden. Es scheint, als könnte Spring nicht zu etwas außerhalb des Ressourcenordners umleiten. Wenn Sie also versuchen, auf Seiten im Stammverzeichnis der Site zuzugreifen, funktioniert dies nicht.
  • Mit der Standardfunktionalität (d. H. Keine Hinzufügung von @EnableWebMvc oder Änderungen an application.properties) wird die Index.html automatisch durch die Navigation zu / aufgerufen (falls diese im resources/static-Ordner enthalten war), so dass dort keine Änderungen vorgenommen werden müssen.
  • Mit der Standardfunktionalität (wie oben angegeben) wird jeder in einer Spring-Boot-App festgestellte Fehler an /error weitergeleitet, und ErrorController setzt dieses Verhalten außer Kraft - Sie ahnen es - und leitet an index.html weiter, wodurch Angular das Routing übernimmt.

Bemerkungen

Ok, fangen wir mit dem einfachen Teil Ihrer Frage an:

Gibt es eine Möglichkeit, allen Steuerungen eine API vorzustellen, damit ich sie nicht jedes Mal schreiben muss?

Die Antwort lautet ja, markieren Sie Ihren Controller einfach mit einer "globalen" @RequestMapping-Anmerkung, zum Beispiel:

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

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

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

Im obigen Beispiel können Sie die Hello-Methode mit dieser URL aufrufen: /api/hello

und die zweite Methode mit dieser URL: /api/hello2

So musste ich nicht jede Methode mit dem Präfix /api markieren.

Nun zum komplexeren Teil Ihrer Frage: 

Wie kann eine Umleitung erreicht werden, wenn die Anforderung nicht mit dem Präfix /api beginnt?

Sie können dies tun, indem Sie einen HTTP-Statuscode (302) von Redirect zurückgeben. Schließlich spricht "angleJs" REST von Natur aus. Daher können Sie keine Umleitung aus Java/Spring-Code erzwingen, wie Sie es verwenden. 

Dann geben Sie einfach eine HTTP-Nachricht mit dem Statuscode 302 zurück, und auf Ihrem angleJS führen Sie die eigentliche Weiterleitung durch.

Zum Beispiel:

Bei 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...");
});

Im Frühling:

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

natürlich müssen Sie es an Ihr Projekt anpassen.

0
Moshe Arad

Für die gesamte Anwendung können Sie in application.properties einen Kontextpfad hinzufügen

server.contextPath =/api

Es wird an jede angeforderte URL nach http: // localhost: 8080/api/home angehängt.

Für die Umleitung

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

Fügen Sie diese Menge Code in WebMVCConfig.Java ein

0
Anksss

Sie müssen nur versuchen, den index.html in src/main/resources/static/ zu setzen.

Siehe Beispiel:https://github.com/reflexdemon/shop/tree/master/src/main/resources/static

In meinem package.josn versuche ich es an diesen Ort zu kopieren.

Siehe 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

In der Bean @Configuration können Sie eine ServletRegistrationBean hinzufügen, um den Spring-Server nur für die/api/* -Anfrage zu erstellen. Im Controller müssen Sie sie nicht hinzufügen.

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