找不到带有spring boot的html页面
Posted
技术标签:
【中文标题】找不到带有spring boot的html页面【英文标题】:cannot find html pages with spring boot 【发布时间】:2016-06-15 11:26:29 【问题描述】:我在前端使用弹簧靴和角度。有时我想直接从服务重定向。我们只使用 .html、.css 和脚本文件(没有 .jsp)。
这是return "static/pages/savepassword.html";
我尝试重定向到保存密码的方式
那么第一个问题在这种情况下如何正确重定向?
接下来,Spring 找不到我的 html 文件。我有这个结构
我读到 spring 应该自动在“静态”中找到所有静态文件,但它没有。所以我尝试配置我的 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 安全性
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 调用我的脚本。
【问题讨论】:
你可以试试 /login.html 吗? 不,因为默认的 Spring Security 页面出现了。通常,我们的自定义 login.html (static/pages/login.html) 应该会显示出来。我更新了我的答案,所以你可以看到 spring 安全配置。我认为ViewControllerRegistry
将登录解析为 static/pages/login,html 并会使用此登录页面
我可能需要将静态文件夹放在 src/main/ressource 中而不是放在 webapp 中吗?
您可以尝试将一页直接放在 webapp 文件夹下并使用 /login.html 引用它吗?
我停用了spring security,但是直接将html文件放在“资源”中时无法访问。
【参考方案1】:
在我看来,最好将您的 *.HTML 文件与所有静态 CSS 字体等放在资源文件夹中,如下图所示。在 webapp 中,您只能拥有一个 WEB-INF 文件夹。
我正在使用这种结构,我可以毫无问题地找到任何类 css 或 htmls,并且我没有在 java 的末尾使用扩展名(“static/pages/login.html”就像你的那样)。如果我想访问 html,如果它在文件夹用户中,我会像“user/someHtml”一样。
我知道这个答案并不完全是您正在寻找的答案,但它可能会以某种方式帮助您。
编辑:现在是:
@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),但是仍然有两个问题:如何重定向和设置 ViewController。 好吧,我想你扩展了 WebMvcConfigurerAdapter。所以对于前。这是当您尝试在浏览器中访问您的应用程序时的方式,例如localhost:8080,您将被重定向到“user/showSomething”@Override public void addViewControllers(ViewControllerRegistry registry)registry.addViewController("/").setViewName("forward :/user/showSomething" ); registry.setOrder(Ordered.HIGHEST_PRECEDENCE); super.addViewControllers(注册表); PS:你可能缺少像我前任那样的“前锋”。希望这会有所帮助。 它只是不起作用...无法访问任何 html...即使没有 Spring Security 并且没有 ViewControllerRegistry/ResourceHandlerRegistry 谢谢,我对你的做法有点不同。我现在通过包含 css 和 js 遇到问题...(请参阅更新 3) 你试过 Jhipster 吗?看看它,它可能就是你所需要的。【参考方案2】:好的,现在我完全明白了。我尽量做到具体。
我的最终结构
1.静态资源
Spring 有一些默认配置,您可以在其中放置静态资源而无需对其进行配置。您需要在 src/main/resources
中创建这些文件夹 /META-INF/resources/ resources(是的,src/main/resources 中的附加资源文件夹 静态 公开看看here in Spring Doku. 例如,查看 Bob Shields 的第二条评论:
在创建了一堆“findme.txt”文件后,每个文件里面都有不同的“source-relative”路径字符串,我发现可以用“http://host/findme.txt”获取以下位置是:
src/main/resources/public/findme.txt
src/main/resources/static/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 是因为我有一个问题,即 spring 不知道 /login 和 login(.html) 之间的区别。 如您所见,我将 index.html 放在名为“loggedin”的不同文件夹中。这个文件夹就在我的公共文件夹中(由 Spring 找到,参见 1.)。我为什么要这样做?看看3。
3.春季安全
.authorizeRequests().antMatchers("/stylesheets/**", "/scripts/**","/login", "/user/**").permitAll()
...omitted further configuration...
.loginPage("/login").permitAll();
首先,我希望用户始终必须先登录才能访问任何其他网站。所以登录页面的所有资源都必须可用。
这段代码使样式表和脚本中的每个文件都可以访问。记住样式表和脚本文件夹是静态的。由于自定义登录页面,我必须设置“/ login”。
老实说,我认为.loginPage("/login").permitAll();
会授予访问权限,但事实并非如此。没有它,Spring 会尝试访问“/login”,但不能导致没有权限,然后自动重定向到 login => ERR_TOO_MANDY_REDIRECTS。
“/user/**”只是我的一些服务,每个用户都可以使用。
如您所见,我不授予对“loggedin”文件夹的访问权限,因此每个访问者只有在登录时才能在“loggedin”中输入文件;)
4.重定向
我刚刚用@RequestController 标记了我的整个控制器,它实现了@ResponseBody。当我返回一个类似 return "redirect:/savepassword";
的字符串时,Spring 会将其设置为 ResponseBody 并将其解释为 String/Json(?)。
我必须将控制器标记为@Controller 并将@ResponseBody 设置为每个必须返回json 或某事的服务。我应该重定向的服务只用@RequestMapping 和method=RequestMethod.GET 标记。最后,我返回一个类似return "redirect:/savepassword";
的字符串,这将使Spring 重定向到/savepassword,实际上是放在src/main/resources/public/savepassword.html
中。
最后,它可以工作了,很难找到 spring 是如何为文件提供服务的。我希望它可以帮助别人:)
【讨论】:
以上是关于找不到带有spring boot的html页面的主要内容,如果未能解决你的问题,请参考以下文章
在带有 MongoDB 的 Spring Boot M7 中找不到 ReflectKotlinClass
带有 Spring Data 的 Spring Boot 应用程序找不到 com.mysema.query.types EntityPath
带有 MySQL 的 Spring Boot R2DBC - 异常:找不到表
带有 JOOQ 的 Spring Boot 收到一条消息“需要一个找不到的 'org.jooq.DSLContext' 类型的 bean”