java 无法找到带有 Spring Boot 的 html 页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35750114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:32:05  来源:igfitidea点击:

cannot find html pages with spring boot

javahtmlspringspring-mvcspring-boot

提问by AndreasGloeckner

I am using spring boot and angular in front end. Sometimes I want to redirect directly from a service. We are using only .html, .css and script files (no .jsp).

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

This is return "static/pages/savepassword.html";how I tried to redirect to savepassword

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

So 1st question how do I redirect properly in this case?

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

Next, Spring doesn't find my html files. I have this structure

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

enter image description here

在此处输入图片说明

I read that spring should find all static files in "static" automatically, but it doesn't. So I tried to configure my ViewControllerRegistry and RessourceControllerRegistry

我读到 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);
    }

When I call "static/pages/login.html" directly, it works. When i want to call "/login" it says 404. 2nd question: What do I need to configure and what not?

当我直接调用“static/pages/login.html”时,它可以工作。当我想调用“/login”时,它会显示 404。 第二个问题:我需要配置什么,不需要什么?

UPDATE-1: Spring Security

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-2I updated my structure, but still have problems with redirecting from /login to the custom login. enter image description here

UPDATE-2我更新了我的结构,但从 /login 重定向到自定义登录仍然有问题。 在此处输入图片说明

UPDATE-3I had a look at the 2nd comment by Bob Shields: https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-bootI did the following:

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);
    }

I set .html because otherwise /login would cause recursive problems. With this config, I can enter /login and /templates/login.html will be called (same for savepassword.html).

我设置 .html 因为否则 /login 会导致递归问题。使用此配置,我可以输入 /login 和 /templates/login.html 将被调用(savepassword.html 相同)。

Now, I would like to know how to include my css/js in html:

现在,我想知道如何将我的 css/js 包含在 html 中

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

This doesn't work...but I cann call my scripts directly with /scripts/login.js.

这不起作用...但我不能直接使用 /scripts/login.js 调用我的脚本。

采纳答案by AndreasGloeckner

Ok, now I totally got it. I try to be specific as possible.

好的,现在我完全明白了。我尽量做到具体。

My final structure

我的最终结构

structure

结构体

1. Static Ressources

1. 静态资源

Spring has some default configuration where you can put your static ressources without configure it. You need to create those folders in src/main/resources

Spring 有一些默认配置,您可以在其中放置静态资源而无需配置它。您需要在src/main/resources 中创建这些文件夹

  • /META-INF/resources/
  • resources (yes, an additional resources folder in src/main/resources
  • static
  • public
  • /元信息/资源/
  • 资源(是的,在 src/main/resources 中有一个额外的资源文件夹
  • 静止的
  • 上市

Have a look here in Spring Doku.For an example, check the 2nd comment by Bob Shields:

在 Spring Doku 中看看这里。例如,查看 Bob Shields 的第二条评论:

After creating a bunch of "findme.txt" files, each of which had different "source-relative" path string inside, I found that the following locations can be fetched with "http://host/findme.txt" are:

src/main/resources/public/findme.txt

src/main/resources/static/findme.txt

src/main/resources/resources/findme.txt - (yes, resources^2!)

src/main/resources/findme.txt - not found!!

在创建了一堆“findme.txt”文件后,每个文件都有不同的“源相对”路径字符串,我发现可以使用“ 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 - 未找到!!

I placed my folder "scripts" and "stylesheets" in the static folder. When I want to include files from these folders in html, the source looks like src="scripts/file.js"because the files and folders in staticare found directly rooted to host/scripts/file.js

我将文件夹“脚本”和“样式表”放在静态文件夹中。当我想将这些文件夹中的文件包含在 html 中时,源看起来像,src="scripts/file.js"因为找到的文件和文件夹static直接植根于host/scripts/file.js

No ResourceHandlerRegistry was necessary for me!

我不需要 ResourceHandlerRegistry!

2. View Controller

2. 视图控制器

I wanted to root my login.html to /login, savepassword.html to /savepassword and my index.html to /. Here is what I did:

我想将我的 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");

I set *.html because otherwise I had a problem that spring didn't know to differ between /login and the login(.html). As you can see I placed the index.html in a different folder called "loggedin". This folder is right in my public-folder (found by Spring, see 1.). Why do I do this? Have a look at 3.

我设置了 *.html,否则我遇到了一个问题,即 spring 不知道 /login 和 login(.html) 之间的区别。如您所见,我将 index.html 放置在名为“loggedin”的不同文件夹中。这个文件夹就在我的公共文件夹中(由 Spring 找到,参见 1.)。我为什么要这样做?看看3。

3. Spring Security

3. 春季安全

.authorizeRequests().antMatchers("/stylesheets/**", "/scripts/**","/login", "/user/**").permitAll()
...omitted further configuration...
.loginPage("/login").permitAll();

First, I want that a user always has to be logged in before he can visit any other sites. So all ressources for loginpage must be available.

首先,我希望用户在访问任何其他站点之前必须始终登录。所以登录页面的所有资源都必须可用。

This piece of code makes every file in stylesheets and scripts accessible. Remember stylesheets and scripts-folder are placed in static. I had to set "/login" because of the custom loginpage. Honestly I thought that the .loginPage("/login").permitAll();would grant access, but it doesn't. Without it Spring tries to access the "/login", but can't cause of no rights and then automatically redirects to login => ERR_TOO_MANDY_REDIRECTS. "/user/**" is just for some of my services that every user can use.

这段代码使样式表和脚本中的每个文件都可以访问。记住样式表和脚本文件夹是放在静态的。由于自定义登录页面,我不得不设置“/login”。老实说,我认为.loginPage("/login").permitAll();会授予访问权限,但事实并非如此。如果没有它,Spring 会尝试访问“/login”,但无法导致没有权限,然后自动重定向到登录 => ERR_TOO_MANDY_REDIRECTS。“/user/**” 仅适用于每个用户都可以使用的我的一些服务。

As you can see, I don't give access to "loggedin"-folder, so that every visitor can enter files in "loggedin" only if he is loggedin ;)

如您所见,我没有授予对“loggedin”文件夹的访问权限,因此每个访问者只有在登录时才能在“loggedin”中输入文件;)

4. Redirecting

4. 重定向

I just marked my whole controller with @RequestController, which implements @ResponseBody. When I return a String like return "redirect:/savepassword";, Spring will set this as ResponseBody and it will be interpreted as String/Json(?).

我只是用@RequestController 标记了我的整个控制器,它实现了@ResponseBody。当我返回类似 return 的 String 时"redirect:/savepassword";,Spring 会将其设置为 ResponseBody 并将其解释为 String/Json(?)。

I had to mark the controller as @Controller and set @ResponseBody to every service that must return json or sth. My service that shall redirect was only marked with @RequestMapping and method=RequestMethod.GET. Finally, I return a String like return "redirect:/savepassword";This will make Spring redirect to /savepassword, which actually is placed in src/main/resources/public/savepassword.html.

我必须将控制器标记为 @Controller 并将 @ResponseBody 设置为每个必须返回 json 或 sth 的服务。我应该重定向的服务只用@RequestMapping 和 method=RequestMethod.GET 标记。最后,我返回一个这样的字符串,return "redirect:/savepassword";这将使 Spring 重定向到 /savepassword,它实际上是放在src/main/resources/public/savepassword.html.

Finally, it works and it was hard enough to find how spring serves the files. I hope it helps someoneelse :)

最后,它起作用了,并且很难找到 spring 如何为文件提供服务。我希望它可以帮助别人:)

回答by Lazar Lazarov

In my opinion it is better to put your *.HTML files in your resources folder with all the static CSS FONTS and so on like in the picture below. In webapp you can have a WEB-INF folder only.

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

I am using this kind of structure and I have no problems finding any classes css or htmls and I do not use extensions at the end in java ("static/pages/login.html" like yours). If I want to access html I go like "user/someHtml" if it is in folder user for ex.

我正在使用这种结构,我在查找任何类 css 或 htmls 时没有任何问题,而且我没有在 Java 的末尾使用扩展(“static/pages/login.html”,就像你的一样)。如果我想访问 html,如果它在文件夹 user 中,我会像“user/someHtml”一样。

I know this answer is not precisely the one you are looking for but it may help you in someway.

我知道这个答案并不是您正在寻找的答案,但它可能会以某种方式帮助您。

enter image description here

在此处输入图片说明

EDIT: Now for the :

编辑:现在为:

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

Lets say you have a Controller:

假设您有一个控制器:

@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
} 
.....
}

Now your addViewControllershow look like this :

现在您的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);
}

You see in your addViewControlleryou are trying to access a CONTROLLER not a HTML you will access your HTML through the CONTROLLER you access from the method addViewControllers.

您在addViewController 中看到您正在尝试访问 CONTROLLER 而不是 HTML,您将通过从addViewControllers方法访问的 CONTROLLER 访问您的 HTML 。

UPDATE:

更新:

If you put your CSS into your static folder in resources like :

如果您将 CSS 放入静态文件夹中的资源,例如:

enter image description here

在此处输入图片说明

You can simply access them like this :

您可以像这样简单地访问它们:

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

Hope this helps!

希望这可以帮助!