我在前端使用弹簧靴和角形。有时我想直接从服务重定向。我们只使用.html,.css和脚本文件(没有.jsp)。
这是return "static/pages/savepassword.html";
我尝试重定向到savepassword的方式
所以第一个问题如何在这种情况下正确重定向?
接下来,Spring没有找到我的html文件。我有这个结构
我读到spring应该在" static"中找到所有静态文件。自动,但它没有。所以我尝试配置我的ViewControllerRegistry和RessourceControllerRegistry
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
// registry.addResourceHandler("/stylesheets/**").addResourceLocations("/stylesheets/");
// registry.addResourceHandler("/scripts/**").addResourceLocations("/scripts/");
// registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/savePassword").setViewName("static/pages/savePassword.html");
registry.addViewController("/login").setViewName("static/pages/login.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
当我打电话给" static / pages / login.html"直接,它的工作原理。当我想打电话给" / login"它说404。 第二个问题:我需要配置什么?不需要什么?
UPDATE-1:Spring Security
http
.authorizeRequests().antMatchers("/login", "/logout", "/user/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler())
.authenticationEntryPoint(new CustomAuthenticationEntryPoint())
.and()
.requiresChannel()
.anyRequest().requiresSecure()
.and()
.csrf()
.disable()
//.csrfTokenRepository(csrfTokenRepository())
.addFilterBefore(new MDCFilter(), ExceptionTranslationFilter.class)
// .addFilterBefore(new CorsFilter(),// ChannelProcessingFilter.class)
//.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.formLogin()
.successHandler(new CustomSuccessAuthenticationHandler())
.failureHandler(new CustomFailureHandler())
.loginPage("/login").permitAll();
UPDATE-2 我更新了我的结构,但仍然有从/ login重定向到自定义登录的问题。
UPDATE-3 我看了Bob Shields的第二条评论:https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot 我做了以下事情:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/savepassword").setViewName("savepassword.html");
registry.addViewController("/login").setViewName("login.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
我设置.html因为否则/ login会导致递归问题。使用此配置,我可以输入/ login并调用/templates/login.html(对于savepassword.html也是如此)。
现在,我想知道如何在html中包含我的css / js :
<link rel="stylesheet" type="text/css" href="..resources/stylesheets/bootstrap.min.css" />
<script src="..resources/scripts/angular.min.js"></script>
<script src="..resources/scripts/login.js"></script>
这不起作用......但我可以用/scripts/login.js直接调用我的脚本。
答案 0 :(得分:3)
在我看来,最好将* .HTML文件放在资源文件夹中,包含所有静态CSS FONTS等,如下图所示。在webapp中,您只能拥有一个WEB-INF文件夹。
我正在使用这种结构,我没有遇到任何类css或htmls的问题,我在java中没有使用扩展(&#34; static / pages / login.html&#34;和你一样) 。如果我想访问html,我会像&#34; user / someHtml&#34;如果它在ex。
的文件夹用户中我知道这个答案并不是你正在寻找的答案,但它可能会对你有所帮助。
编辑:现在为:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/savePassword").setViewName("static/pages/savePassword.html");
registry.addViewController("/login").setViewName("static/pages/login.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
假设你有一个控制器:
@Controller
@RequestMapping("/myController")
public class MyController{
...
@RequestMapping(value = "/login")
public String login(Model model) {
// Your code ....
return "login"; //<- this is your login.html if it is directly in resource/templates folder
}
@RequestMapping(value = "/savePassword")
public String savePassword(Model model) {
// Your code ....
return "savePassword"; //<- this is your savePassword.html if it is directly in resource/templates folder
}
.....
}
现在您的 addViewController 节目如下所示:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/savePassword").setViewName("forward:/myController/savePassword");
registry.addViewController("/login").setViewName("forward:/myController/login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
您在 addViewController 中看到,您正在尝试访问CONTROLLER而不是HTML,您将通过您从方法 addViewControllers 访问的CONTROLLER访问您的HTML。
<强>更新强>
如果您将CSS放入静态文件夹中,请使用以下资源:
您可以像这样访问它们:
<link rel="stylesheet" th:href="@{/css/bootstrap-datetimepicker.min.css}" />
希望这有帮助!
答案 1 :(得分:3)
好的,现在我完全明白了。我试着尽可能具体。
我的最终结构
<强> 1。静态资源
Spring有一些默认配置,您可以在不配置静态资源的情况下放置静态资源。您需要在 src / main / resources
中创建这些文件夹查看here in Spring Doku.例如,查看Bob Shields的第二条评论:
在创建了一堆“findme.txt”文件后,每个文件中都有不同的“源相关”路径字符串,我发现可以使用“http://host/findme.txt”获取以下位置:
的src /主/资源/公共/ findme.txt
的src /主/资源/静态/ findme.txt
src / main / resources / resources / findme.txt - (是的,资源^ 2!)
src / main / resources / findme.txt - 找不到!!
我将文件夹“scripts”和“stylesheets”放在静态文件夹中。当我想在html中包含这些文件夹中的文件时,源代码看起来像src="scripts/file.js"
,因为static
中的文件和文件夹直接找到host/scripts/file.js
我不需要ResourceHandlerRegistry!
<强> 2。查看控制器
我想将我的login.html发送到/ login,savepassword.html到/ savepassword,将我的index.html发送到/。这是我做的:
registry.addViewController("/savepassword").setViewName("savepassword.html");
registry.addViewController("/login").setViewName("login.html");
registry.addViewController("/").setViewName("loggedin/index.html");
我设置* .html因为否则我有一个问题,春天不知道/ login和登录(.html)之间的区别。 如您所见,我将index.html放在名为“loggedin”的不同文件夹中。此文件夹位于我的公共文件夹中(由Spring找到,请参阅1.)。为什么我这样做?看看3。
第3。 Spring Security
.authorizeRequests().antMatchers("/stylesheets/**", "/scripts/**","/login", "/user/**").permitAll()
...omitted further configuration...
.loginPage("/login").permitAll();
首先,我希望用户始终必须先登录才能访问任何其他网站。因此,所有登录页面的资源都必须可用。
这段代码使样式表和脚本中的每个文件都可以访问。记住样式表和脚本文件夹是静态的。由于自定义登录页面,我不得不设置“/ login”。
老实说,我认为.loginPage("/login").permitAll();
会授予访问权限,但事实并非如此。没有它Spring尝试访问“/ login”,但不能导致没有权限,然后自动重定向到login =&gt; ERR_TOO_MANDY_REDIRECTS。
“/ user / **”仅适用于每个用户都可以使用的一些服务。
正如您所看到的,我不会访问“loggedin”文件夹,因此每个访问者只有在登录时才能以“登录”方式输入文件;)
<强> 4。重定向强>
我刚用@RequestController标记了我的整个控制器,它实现了@ResponseBody。当我返回一个类似返回"redirect:/savepassword";
的字符串时,Spring会将其设置为ResponseBody,它将被解释为String / Json(?)。
我必须将控制器标记为@Controller并将@ResponseBody设置为必须返回json或sth的每个服务。我的重定向服务只用@RequestMapping和method = RequestMethod.GET标记。最后,我返回一个像return "redirect:/savepassword";
这样的字符串。这将使Spring重定向到/ savepassword,它实际上放在src/main/resources/public/savepassword.html
中。
最后,它的工作原理很难找到spring如何提供文件。我希望它有助于某人:)