Springboot/Angular2 - 如何处理HTML5网址?

Fel*_* S. 40 spring spring-boot angular

我相信这是一个简单的问题,但我找不到答案或至少在搜索中使用正确的术语.

我正在Angular2和我们Springboot一起建立.默认情况下,Angular将使用localhost:8080\dashboard和等路径localhost:8080\dashboard\detail.

如果可能的话,我想避免使用路径作为哈希.正如Angular 文档所述:

路由器的provideRouter函数将LocationStrategy设置为PathLocationStrategy,使其成为默认策略.如果我们愿意,我们可以在引导过程中使用覆盖切换到HashLocationStrategy.

然后...

几乎所有Angular 2项目都应使用默认的HTML 5样式.它生成的URL更易于用户理解.它保留了以后进行服务器端渲染的选项.

问题在于,当我尝试访问时localhost:8080\dashboard,Spring会寻找一些控制器映射到这条路径,它不会有.

Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
No message available
Run Code Online (Sandbox Code Playgroud)

我认为最初是为了让我的所有服务都处于不足localhost:8080\api之下localhost:8080\app.但是,如何告诉Spring忽略对此app路径的请求?

Angular2或Boot有更好的解决方案吗?

And*_*ver 49

我有一个解决方案,你可以添加一个ViewController转发请求从Spring启动Angular.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ViewController {

@RequestMapping({ "/bikes", "/milages", "/gallery", "/tracks", "/tracks/{id:\\w+}", "/location", "/about", "/tests","/tests/new","/tests/**","/questions","/answers" })
   public String index() {
       return "forward:/index.html";
   }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我重定向了所有的angular2("/ bikes","/ milages","/ gallery","/ tracks","/ tracks/{id:\ w +}","/ location","/ about", "/ tests","/ tests/new","/ tests/**","/ questions","/ answers")到我的SPA你可以对你的预测做同样的事情,你也可以重定向你的404错误页面到索引页面作为进一步的步骤.请享用!

  • 这个答案有效。但是,我相信这是最好的答案:/sf/ask/2696166721/#46854105 谢谢@davidxxx (2认同)

dav*_*xxx 34

在我的Spring Boot应用程序(版本1和版本2)中,我的静态资源位于一个地方:

src/main/resources/static
Run Code Online (Sandbox Code Playgroud)

static 是Spring Boot识别的文件夹,用于加载静态资源.

然后想法是定制Spring MVC配置.
更简单的方法是使用Spring Java配置.

我实现WebMvcConfigurer 覆盖addResourceHandlers().我在添加一个 ResourceHandler到当前ResourceHandlerRegistry.
处理程序映射到每个请求,我指定classpath:/static/为资源位置值(如果需要,您当然可以添加其他值).
我添加一个自定义PathResourceResolver匿名类来覆盖getResource(String resourcePath, Resource location).
返回资源的规则如下:如果资源存在且可读(因此它是文件),我将返回它.否则,默认情况下我返回index.html页面.处理HTML 5网址的预期行为是什么.

Spring Boot 1.X应用程序:

扩展org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter就是这样.
该类是WebMvcConfigurer具有空方法的接口的适配器,允许子类仅覆盖它们感兴趣的方法.

这是完整的代码:

import java.io.IOException;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.resource.PathResourceResolver;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    registry.addResourceHandler("/**/*")
        .addResourceLocations("classpath:/static/")
        .resourceChain(true)
        .addResolver(new PathResourceResolver() {
            @Override
            protected Resource getResource(String resourcePath,
                Resource location) throws IOException {
                  Resource requestedResource = location.createRelative(resourcePath);
                  return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                : new ClassPathResource("/static/index.html");
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Spring Boot 2.X应用程序:

org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter已被弃用.
直接实现WebMvcConfigurer是现在的方式,因为它仍然是一个接口,但它现在有默认方法(由Java 8基线实现),并且可以直接实现而无需适配器.

这是完整的代码:

import java.io.IOException;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

      registry.addResourceHandler("/**/*")
        .addResourceLocations("classpath:/static/")
        .resourceChain(true)
        .addResolver(new PathResourceResolver() {
            @Override
            protected Resource getResource(String resourcePath,
                Resource location) throws IOException {
                Resource requestedResource = location.createRelative(resourcePath);
                return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                : new ClassPathResource("/static/index.html");
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Dmi*_*iuk 12

您可以通过提供自定义ErrorViewResolver将所有未找到的资源转发到主页面.您需要做的就是将其添加到@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;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)


Lor*_*ren 7

您可以使用以下内容转发未映射到Angular的所有内容:

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

来源:https://stackoverflow.com/a/44850886/3854385

我的用于angular的Spring Boot服务器也是一个网关服务器,API调用/api在角度页面前没有登录页面,你可以使用类似的东西.

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

/**
 * This sets up basic authentication for the microservice, it is here to prevent
 * massive screwups, many applications will require more secuity, some will require less
 */

@EnableOAuth2Sso
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .logout().logoutSuccessUrl("/").and()
                .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .anyRequest().permitAll().and()
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}
Run Code Online (Sandbox Code Playgroud)