2014-07-19 30 views
15

Avvio la mia applicazione Web con avvio a molla. Si usa una classe principale semplice per avviare un server Tomcat incorporato:Avvio a molla con AngularJS html5Mode

@Configuration 
@EnableAutoConfiguration 
@ComponentScan 
public class Application { 

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

} 

voglio configurare il server in modo che possa gestire angularjs html5mode che verrà attivato con

$locationProvider.html5Mode(true); 

messaggi pertinenti da altri utenti mostrano che è necessario reindirizzare alla radice. la modalità html5 rimuove l'hashbag dall'URL. Se aggiorni la pagina il server non trova la pagina perché non gestisce l'hash. vedi: AngularJS - Why when changing url address $routeProvider doesn't seem to work and I get a 404 error

+0

Non penso che ci siano abbastanza informazioni per sapere cosa hai fatto e perché non ha funzionato. –

risposta

9

ho trovato una soluzione che posso vivere con esso.

@Controller 
public class ViewController { 

    @RequestMapping("/") 
    public String index() { 
     return "index"; 
    } 

    @RequestMapping("/app/**") 
    public String app() { 
     return "index"; 
    } 
} 

L'app angularjs deve essere sotto l'app sottodominio. Se non vuoi che tu possa creare un sottodominio come app.subdomain.com che si collega alla tua sottodominio. Con questo costrutto non hai conflitti con webjars, contenuto di statis e così via.

+0

Potresti elaborare come funziona? Per me restituisce solo la stringa "indice"! il mio index.html è sotto resources/static/app – sansari

+0

Lo scopo di html5mode è di evitare l'uso di un prefisso '#'. Lo stai sostituendo con un prefisso 'app', quindi qual è il valore. Meglio usare la strategia di routing basata sull'hash. – rcomblen

20

Ho avuto lo stesso problema. Per quanto ne so, in modalità html5, angularjs non risolve hash ma è stato inserito url o url aggiunto throughpushState.

Il problema era che PathResourceResolver mappava le directory ma non i file. Perché intendeva servire i file richiesti dalla directory ma non per riscrivere gli URL. Per app è medio, se si aggiorna la finestra del browser o si digita l'url come http://example.com/mystate, la query "/ mystate" viene eseguita dal server. Se primavera non conoscono l'url, restituiscono 404. Una delle soluzioni è mappare ogni stato possibile a index.html come here (source, btw guarda i webjars - è fantastico!). Ma nel mio caso posso tranquillamente mappa "/ **" per index.html e quindi la mia soluzione è quella di ignorare PathResourceResolver # getResource:

@Configuration 
@EnableConfigurationProperties({ ResourceProperties.class }) 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

    @Autowired 
    private ResourceProperties resourceProperties = new ResourceProperties(); 

    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     Integer cachePeriod = resourceProperties.getCachePeriod(); 

     registry.addResourceHandler("/static/**") 
       .addResourceLocations("classpath:/static/") 
       .setCachePeriod(cachePeriod); 

     registry.addResourceHandler("/**") 
       .addResourceLocations("classpath:/static/index.html") 
       .setCachePeriod(cachePeriod).resourceChain(true) 
       .addResolver(new PathResourceResolver() { 
        @Override 
        protected Resource getResource(String resourcePath, 
          Resource location) throws IOException { 
         return location.exists() && location.isReadable() ? location 
           : null; 
        } 
       }); 
    } 
} 
+0

Non riesco a farlo funzionare con altre risorse statiche incluse in index.html, ad esempio JS e risorse CSS. Ad esempio, ho un altro file css nella mia cartella statica e mi collego ad esso nella sezione head del mio file index.html. Quando guardo quel file in Chrome Dev Tools, il suo contenuto è index.html. – tlavarea

+1

Ho finito per mappare manualmente i percorsi angolari a un controller specifico che inoltra a index.html come da fonte collegata. Funziona bene ed è chiaro e facile da capire :) –

5

Una piccola regolazione di un codice precedente che funziona per me.

// Running with Spring Boot v1.3.0.RELEASE, Spring v4.2.3.RELEASE 
@Configuration 
@EnableConfigurationProperties({ ResourceProperties.class }) 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

@Autowired 
private ResourceProperties resourceProperties = new ResourceProperties(); 

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    Integer cachePeriod = resourceProperties.getCachePeriod(); 

    final String[] staticLocations = resourceProperties.getStaticLocations(); 
    final String[] indexLocations = new String[staticLocations.length]; 
    for (int i = 0; i < staticLocations.length; i++) { 
     indexLocations[i] = staticLocations[i] + "index.html"; 
    } 
    registry.addResourceHandler(
      "/**/*.css", 
      "/**/*.html", 
      "/**/*.js", 
      "/**/*.json", 
      "/**/*.bmp", 
      "/**/*.jpeg", 
      "/**/*.jpg", 
      "/**/*.png", 
      "/**/*.ttf", 
      "/**/*.eot", 
      "/**/*.svg", 
      "/**/*.woff", 
      "/**/*.woff2" 
      ) 
      .addResourceLocations(staticLocations) 
      .setCachePeriod(cachePeriod); 

    registry.addResourceHandler("/**") 
      .addResourceLocations(indexLocations) 
      .setCachePeriod(cachePeriod) 
      .resourceChain(true) 
      .addResolver(new PathResourceResolver() { 
       @Override 
       protected Resource getResource(String resourcePath, 
         Resource location) throws IOException { 
        return location.exists() && location.isReadable() ? location 
          : null; 
       } 
      }); 
} 

}

0

Ho appena incontrato il problema simile in cui ho voluto configurare le risorse e allo stesso tempo ho voluto utilizzare la modalità AngularJS supporto HTML5.

Nel mio caso i miei file statici sono stati serviti dal percorso /public quindi ho utilizzato il seguente mapping di richiesta sull'azione indice e tutto funziona correttamente.

@RequestMapping(value = {"", "/", "/{[path:(?!public).*}/**"}, method = GET) 
public String indexAction() { 
    return "index"; 
} 
3

È possibile inoltrare tutte le risorse non trovate alla pagina principale fornendo ErrorViewResolver personalizzato. Tutto quello che dovete fare è aggiungere questo alla classe @Configuration:

@Bean 
ErrorViewResolver supportPathBasedLocationStrategyWithoutHashes() { 
    return new ErrorViewResolver() { 
     @Override 
     public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { 
      return status == HttpStatus.NOT_FOUND 
        ? new ModelAndView("index.html", Collections.<String, Object>emptyMap(), HttpStatus.OK) 
        : null; 
     } 
    }; 
} 
0

Ho avuto lo stesso problema durante l'utilizzo Html5Mode angolare. La soluzione che ha funzionato per me era configurare la pagina di errore per 404 in web.xml assegnando il percorso alla mia vista Indice nel mio caso "/".

<error-page> 
    <error-code>404</error-code> 
    <location>/</location> 
</error-page> 

Analogamente, è possibile provare a configurare la pagina di errore in avvio di primavera. per riferimento, puoi controllare questo link.

Spring boot and custom 404 error page

+0

Funziona ma il codice di stato della risposta sarà 404, non è bello. Userò questo come bypass. Grazie –

8

Utilizzare questo controller per inoltrare l'URI index.html per preservare percorsi AngularJS. Fonte https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii

@Controller 
public class ForwardController { 

    @RequestMapping(value = "/**/{[path:[^\\.]*}") 
    public String redirect() { 
     // Forward to home page so that route is preserved. 
     return "forward:/"; 
    } 
} 
+0

Cosa dice quel Regex nel valore "dì"? –

+1

Abbina tutto senza un suffisso (quindi non una risorsa statica) – Eljaiek

+0

La cosa grandiosa di questa vs alcune altre opzioni è questa opzione conserva percorsi come '/ login' dal controller di sicurezza. – Loren

0

finalmente ho il mio angolare 5 applicazione lavorare con avvio a molla con o senza spring-boot-starter-tomcat come provided (embedded) o no!

/** 
* Needed for html5mode (PathLocationStrategy in Angular). Every path except api/* and resources (css, html, js, woff, etc..) 
* should be redirect to index.html and then should angular managed routes (which could be correct or non existing). 
*/ 
@RestController 
@RequestMapping 
public class ForwardController { 

    @GetMapping(value = "/**/{[path:[^\\.]*}") 
    public ModelAndView forward() { 
     return new ModelAndView("/index.html"); 
    } 
} 
Problemi correlati