使用AngularJS html5Mode进行Spring Boot

Rud*_*idt 17 html5 spring angularjs spring-boot

我用spring boot启动我的web应用程序.它使用一个简单的主类来启动嵌入式tomcat服务器:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

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

}
Run Code Online (Sandbox Code Playgroud)

我想以他能够处理将被激活的angularjs html5mode的方式配置服务器

$locationProvider.html5Mode(true);
Run Code Online (Sandbox Code Playgroud)

来自其他用户的相关帖子显示您需要重定向到根目录.html5模式从url中删除hashbag.如果刷新页面,服务器找不到页面导致他不处理哈希.请参阅:AngularJS - 为什么在更改URL地址时$ routeProvider似乎不起作用,我收到404错误

Edu*_*iek 23

使用此控制器将URI转发到index.html以保留AngularJS路由.来源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:/";
    }
} 
Run Code Online (Sandbox Code Playgroud)

在此解决方案ForwardController只转发路径,其未在任何其他定义Controller也没有RestController.这意味着如果你已经拥有:

@RestController
public class OffersController {

    @RequestMapping(value = "api/offers")
    public Page<OfferDTO> getOffers(@RequestParam("page") int page) {
        return offerService.findPaginated(page, 10);
    }
} 
Run Code Online (Sandbox Code Playgroud)

两个控制器都能正常工作 - @RequestMapping(value = "api/offers")之前已经过检查@RequestMapping(value = "/**/{[path:[^\\.]*}")

  • 为什么正则表达式有2个开口支撑而只有1个闭合支撑? (3认同)

Ant*_*nov 22

我有同样的问题.据我所知,在html5模式下,angularjs不解析哈希,但输入了通过 pushState添加的url或url .

问题是PathResourceResolver映射目录而不是文件.因为它打算从目录提供所请求的文件,但不是为了重写URL.对于app来说,这意味着,如果您刷新浏览器窗口或输入类似http://example.com/mystate的 URL ,则从服务器查询"/ mystate".如果spring不知道url,则返回404.其中一个解决方案是将每个可能的状态映射到index.html,就像这里一样(来源,顺便看一下webjars - 太棒了!).但在我的情况下,我可以安全地将"/**"映射到index.html,因此我的解决方案是覆盖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;
                    }
                });
    }
}
Run Code Online (Sandbox Code Playgroud)


Rud*_*idt 11

我找到了一个可以忍受它的解决方案.

@Controller
public class ViewController {

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

    @RequestMapping("/app/**")
    public String app() {
        return "index";
    }
}
Run Code Online (Sandbox Code Playgroud)

angularjs应用程序必须位于子域应用程序下.如果您不希望这样,您可以创建一个像app.subdomain.com这样的子域,它可以映射到您的子域应用程序.使用此构造,您不会与webjars,statis内容等发生冲突.