用spring boot找不到html页面

时间:2016-03-02 14:33:03

标签: java html spring spring-mvc spring-boot

我在前端使用弹簧靴和角形。有时我想直接从服务重定向。我们只使用.html,.css和脚本文件(没有.jsp)。

这是return "static/pages/savepassword.html";我尝试重定向到savepassword的方式

所以第一个问题如何在这种情况下正确重定向?

接下来,Spring没有找到我的html文件。我有这个结构

enter image description here

我读到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重定向到自定义登录的问题。 enter image description here

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直接调用我的脚本。

2 个答案:

答案 0 :(得分:3)

在我看来,最好将* .HTML文件放在资源文件夹中,包含所有静态CSS FONTS等,如下图所示。在webapp中,您只能拥有一个WEB-INF文件夹。

我正在使用这种结构,我没有遇到任何类css或htmls的问题,我在java中没有使用扩展(&#34; static / pages / login.html&#34;和你一样) 。如果我想访问html,我会像&#34; user / someHtml&#34;如果它在ex。

的文件夹用户中

我知道这个答案并不是你正在寻找的答案,但它可能会对你有所帮助。

enter image description here

编辑:现在为:

   @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放入静态文件夹中,请使用以下资源:

enter image description here

您可以像这样访问它们:

<link rel="stylesheet" th:href="@{/css/bootstrap-datetimepicker.min.css}" />

希望这有帮助!

答案 1 :(得分:3)

好的,现在我完全明白了。我试着尽可能具体。

我的最终结构

structure

<强> 1。静态资源

Spring有一些默认配置,您可以在不配置静态资源的情况下放置静态资源。您需要在 src / main / resources

中创建这些文件夹
  • / META-INF / resources /
  • 资源(是的,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如何提供文件。我希望它有助于某人:)