我使用spring boot启动我的Web应用程序。它使用一个简单的主类来启动嵌入式tomcat服务器:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我想以他能够处理将被激活的angularjs html5mode的方式配置服务器
$locationProvider.html5Mode(true);
其他用户的相关帖子显示您需要重定向到根目录。 html5模式从url中删除hashbag。如果刷新页面,服务器找不到页面导致他不处理哈希。见:AngularJS - Why when changing url address $routeProvider doesn't seem to work and I get a 404 error
答案 0 :(得分:22)
我有同样的问题。据我所知,在html5模式下,angularjs不会解析哈希,但输入的网址或网址已添加through pushState。
问题在于PathResourceResolver映射目录而不是文件。因为它打算从目录提供所请求的文件,但不是为了重写URL。对于应用程序,这意味着,如果您刷新浏览器窗口或输入http://example.com/mystate之类的网址,则会查询" / mystate"从服务器。如果spring不知道url,他们会返回404.其中一个解决方案是将每个可能的状态映射到index.html,例如here(source,顺便看看webjars - 它是' s大!)。但在我的情况下,我可以安全地映射" / **"到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;
}
});
}
}
答案 1 :(得分:21)
使用此控制器将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:/";
}
}
在此解决方案中,ForwardController仅转发未在任何其他Controller
或RestController
中定义的路径。这意味着如果您已经拥有:
@RestController
public class OffersController {
@RequestMapping(value = "api/offers")
public Page<OfferDTO> getOffers(@RequestParam("page") int page) {
return offerService.findPaginated(page, 10);
}
}
两个控制器都能正常工作 - @RequestMapping(value = "api/offers")
之前检查@RequestMapping(value = "/**/{[path:[^\\.]*}")
答案 2 :(得分:10)
我找到了一个可以忍受它的解决方案。
@Controller
public class ViewController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/app/**")
public String app() {
return "index";
}
}
angularjs应用程序必须位于子域应用程序下。如果您不希望这样,您可以创建一个像app.subdomain.com这样的子域,它可以映射到您的子域应用程序。使用此构造,您不会与webjars,statis内容等发生冲突。
答案 3 :(得分:4)
对我之前的代码进行小幅调整。
// 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;
}
});
}
}
答案 4 :(得分:4)
您可以通过提供自定义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;
}
};
}
答案 5 :(得分:3)
我终于让我的Angular 5应用程序使用或不使用spring-boot-starter-tomcat
作为provided
(嵌入式)进行弹簧启动!
/**
* 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");
}
}
答案 6 :(得分:0)
我刚刚遇到类似的问题,我想配置资源,同时我想使用AngularJS Html5模式。
在我的情况下,我的静态文件是从/public
路由提供的,所以我在索引操作上使用了以下请求映射,一切正常。
@RequestMapping(value = {"", "/", "/{[path:(?!public).*}/**"}, method = GET)
public String indexAction() {
return "index";
}
答案 7 :(得分:0)
使用角度Html5Mode时遇到了同样的问题。 对我有用的解决方案是在web.xml中为404配置错误页面,在我的情况下为我的索引视图分配路径&#34; /&#34;。
<error-page>
<error-code>404</error-code>
<location>/</location>
</error-page>
同样,您可以尝试在spring boot中配置错误页面。作为参考,您可以查看此链接。
答案 8 :(得分:0)
1-首先你创建新的Controller然后复制并粘贴简单的代码
@Controller
public class viewController {
@RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect() {
// Forward to home page so that route is preserved.
return "forward:/";
}
}
3-从角度应用
中移除下面的项目2$locationProvider.hashPrefix('!');
$urlRouterProvider.otherwise("/");
2-角应用程序中,您必须将$locationProvider.html5Mode(true);
添加到应用程序路径
3-不要忘记在index.html文件中的任何http请求之前放置基本标记
<head>
<base href="/"> /* Or whatever your base path is */
//call every http request for style and other
...
</head>
这对我来说很好用