Spring Boot with AngularJS html5Mode

后端 未结 9 2247
长发绾君心
长发绾君心 2020-11-27 04:35

I start my web application with spring boot. It use a simple main class to start an embedded tomcat server:

@Configuration
@EnableAutoConfiguration
@Componen         


        
相关标签:
9条回答
  • 2020-11-27 04:37

    I had the same problem while using angular Html5Mode. The solution that worked for me was to configure error page for 404 in web.xml assigning the path to my Index view in my case "/".

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

    Similarly, you can try configuring error page in spring boot. for reference, you can check this link.

    Spring boot and custom 404 error page

    0 讨论(0)
  • 2020-11-27 04:40

    I just encountered the similar issue where I wanted to configure Resources and at the same time I wanted to use AngularJS Html5 mode enabled.

    In my case my static files were served from /public route so I used the following request mapping on my index action and it all works fine.

    @RequestMapping(value = {"", "/", "/{[path:(?!public).*}/**"}, method = GET)
    public String indexAction() {
        return "index";
    }
    
    0 讨论(0)
  • 2020-11-27 04:42

    I finally get my Angular 5 application working with spring boot with or without spring-boot-starter-tomcat as provided (embedded) or not!

    /**
     * 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");
        }
    }
    
    0 讨论(0)
  • 2020-11-27 04:44

    You can forward all not found resources to your main page by providing custom ErrorViewResolver. All you need to do is to add this to your @Configuration class:

    @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 讨论(0)
  • 2020-11-27 04:46

    I had same problem. As far as I know, in html5 mode, angularjs don't resolve hash but entered url or url added through pushState.

    The problem was that PathResourceResolver map directories but not files. Because it intended to serve requested files from directory but not to rewrite urls. For app it's mean, if you refresh your browser window or type url like http://example.com/mystate, it's query "/mystate" from the server. If spring don't know url, they return 404. One of the solutions is map every possible state to index.html like here (source, btw look at webjars - it's great!). But in my case I can safely map "/**" to index.html and therefore my solution is to override 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 讨论(0)
  • 2020-11-27 04:50

    A small adjustment to a previous code which works to 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 讨论(0)
提交回复
热议问题