为什么`th:text`在其他页面显示正常,但在`main.html`模板中却不显示?

huangapple go评论76阅读模式
英文:

Why th:text doesn't want to display in the main.html template while it displays in other pages?

问题

下面是你提供的代码部分的翻译:

main.html (/templates/layouts/main)

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

<head>
    <!-- Required meta tags -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
    <script src="https://kit.fontawesome.com/2dafcd6f62.js" crossorigin="anonymous"></script>

    <!-- Bootstrap CSS // Let's connect the CSS to the grid system -->
    <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css">

    <!-- CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="css/style.css" th:href="@{css/style.css}">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css"
        th:href="@{css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css}">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css"
        th:href="@{css/bootstrap-4.3.1-dist/css/bootstrap.min.css}">
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
    <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Using Spring Security Thymeleaf</title>
</head>

<body>

    <div class="jumbotron text-center container-color">
        <h1 class="home-title font-text-style">Text</h1>
        <p>Text, text, text...</p>
    </div>
    <div layout:fragment="content">
        the login content should get here
    </div>
    <footer class="text-center footer bg-dark">
        <div class="font-style">
            <div>
                Today is <span th:text="${#dates.format(dateTime, 'yyyy-MM-dd')}">Today is</span></div>
            <br>Your IP address is <span class="yourIp" th:text="${yourip}">IP as: 127.0.0.1</span>

        </div>
    </footer>
</body>

</html>

login.html (/templates/auth/login)

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
    lang="en" layout:decorate="~{layouts/main}">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css">
    <!--We are choosing these two to let the browser to load faster-->
    <link rel="stylesheet" type="text/css" href="css/logincss.css">
    <!--this is the last one so that we can override previous boostrap styles if we want-->
    <head>

        <body class="signin-body">


            <div class="container signin-container" layout:fragment="content">
                <div class="row">
                    <div class="col"></div>
                    <div class="col-sm-12 col-md-8">
                        <div class="card signin-card">
                            <div class="card-block">
                                <!-- <img src="images/logindetails.png" width="50%" height="50%" class="img-fluid signin-img"> -->
                                <form name="login" th:action="@{/login}" method="post" class="signin-form">
                                    <div class="form-group">
                                        <h2 class="form-signin-heading">Please sign in</h2>
                                        <div th:if="${param.error}" class="alert alert-danger">Wrong username and
                                            password</div>
                                        <div th:if="${param.logout}" class="alert alert-success">You successfully
                                            logged out</div>
                                        <label for="username" class="sr-only">Username</label>
                                        <input type="text" id="username" name="username" class="form-control"
                                            placeholder="Username" required="true">
                                        <label for="password" class="sr-only">Password</label>
                                        <div class="form-group">
                                            <input type="password" id="password" name="password" class="form-control"
                                                placeholder="Password" required="true">
                                        </div>
                                    </div>
                                    <button class="btn btn-lg btn-primary btn-block signin-btn" type="submit">Login</button>
                                    <div class="custom-control custom-checkbox">
                                        <input type="checkbox" class="custom-control-input" id="customCheck1">
                                        <a class="new-account" href="/registration">Create New Account</a>
                                    </div>
                                </form>

                            </div>
                        </div>
                    </div>
                </div>
                <div class="col"></div>
            </div>
        </div>

        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
            integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
            crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
        <script src="css/bootstrap-4.3.1-dist/js/bootstrap.min.js"></script>
    </body>

</html>

ApiController.java 的一部分

@Controller
public class ApiController {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private EmailService emailService;
    private UserService userService;
    private FormUserService formUserService;

    @Autowired
    public void setForm

<details>
<summary>英文:</summary>

I&#39;m practicing Spring Security+Thymeleaf and I have a template with header and footer, **main.html** and a **login page** where the login content is. I successfully made the login content &quot;wrapped&quot; into the template but the only thing that doesn&#39;t want to work is the `th:text=&quot;${#dates.format(dateTime, &#39;yyyy-MM-dd&#39;)}&quot;` and the `th:text=&quot;${yourip}`&quot; in the footer of the main.html template. These are working in the other pages after I set them in the controller class. I made sure in the Config class that /templates/layouts/main is ignored (`.antMatchers(staticResources).permitAll()`) but it still doesn&#39;t want to work. I don&#39;t know how should I define the template page in the controller class since the template is just a template unlike the login page. 

**UPDATE:** I just tried to put the footer with the indicated th:text context variables in the login view and doesn&#39;t work either, but it works when I put them in the registration view for example. 

**main.html** (/templates/layouts/main)

    &lt;!doctype html&gt;
    &lt;html xmlns:th=&quot;http://www.thymeleaf.org&quot; xmlns:layout=&quot;http://www.ultraq.net.nz/thymeleaf/layout&quot; xmlns:sec=&quot;http://www.thymeleaf.org/extras/spring-security&quot;&gt;
    
    &lt;head&gt;
        &lt;!-- Required meta tags --&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
        &lt;!-- &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js&quot;&gt;&lt;/script&gt; --&gt;
        &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
        &lt;script src=&quot;https://kit.fontawesome.com/2dafcd6f62.js&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
    
        &lt;!-- Bootstrap CSS // Let&#39;s connect the CSS to the grid system --&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot;&gt;
    
        &lt;!--CSS--&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/style.css&quot; th:href=&quot;@{css/style.css}&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css&quot; th:href=&quot;@{css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css}&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot; th:href=&quot;@{css/bootstrap-4.3.1-dist/css/bootstrap.min.css}&quot;&gt;
        &lt;link href=&quot;https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN&quot; crossorigin=&quot;anonymous&quot;&gt;
        &lt;title layout:title-pattern=&quot;$LAYOUT_TITLE - $CONTENT_TITLE&quot;&gt;Using Spring Security Thymeleaf&lt;/title&gt;
    &lt;/head&gt;
    
    &lt;body&gt;
    
        &lt;div class=&quot;jumbotron text-center container-color&quot;&gt;
            &lt;h1 class=&quot;home-title font-text-style&quot;&gt;Text&lt;/h1&gt;
            &lt;p&gt;Text, text, text...&lt;/p&gt;
        &lt;/div&gt;
        &lt;div layout:fragment=&quot;content&quot;&gt;
            the login content should get here
        &lt;/div&gt;
        &lt;footer class=&quot;text-center footer bg-dark&quot;&gt;
            &lt;div class=&quot;font-style&quot;&gt;
                &lt;div&gt;
                    Today is &lt;span th:text=&quot;${#dates.format(dateTime, &#39;yyyy-MM-dd&#39;)}&quot;&gt;Today is&lt;/span&gt;&lt;/div&gt;
                &lt;br&gt;Your IP address is &lt;span class=&quot;yourIp&quot; th:text=&quot;${yourip}&quot;&gt;IP as: 127.0.0.1&lt;/span&gt;
    
            &lt;/div&gt;
        &lt;/footer&gt;
    &lt;/body&gt;
    
    &lt;/html&gt;

**login.html** (/templates/auth/login)

    &lt;!doctype html&gt;
    &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
    	xmlns:th=&quot;http://www.thymeleaf.org&quot;
    	xmlns:sec=&quot;http://www.thymeleaf.org/thymeleaf-extras-springsecurity3&quot;
    	xmlns:layout=&quot;http://www.ultraq.net.nz/thymeleaf/layout&quot;
    	
    	lang=&quot;en&quot; layout:decorate=&quot;~{layouts/main}&quot;&gt;
    
    &lt;head&gt;
        &lt;!-- Required meta tags --&gt;
        &lt;meta charset=&quot;utf-8&quot;&gt;
        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;
    
        &lt;!-- Bootstrap CSS --&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot;&gt;
        &lt;!--We are choosing these two to let the browser to load faster--&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/logincss.css&quot;&gt;
        &lt;!--this is the last one so that we can override previous boostrap styles if we want--&gt;
        
        
    
        &lt;head&gt;
    
        &lt;body class=&quot;signin-body&quot;&gt;
        
        
            &lt;div class=&quot;container signin-container&quot; layout:fragment=&quot;content&quot;&gt;
                &lt;div class=&quot;row&quot;&gt;
                    &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
                    &lt;div class=&quot;col-sm-12 col-md-8&quot;&gt;
                        &lt;div class=&quot;card signin-card&quot;&gt;
                            &lt;div class=&quot;card-block&quot;&gt;
                             &lt;!-- &lt;img src=&quot;images/logindetails.png&quot; width=&quot;50%&quot; height=&quot;50%&quot; class=&quot;img-fluid signin-img&quot;&gt; --&gt;
                                &lt;form name=&quot;login&quot; th:action=&quot;@{/login}&quot; method=&quot;post&quot; class=&quot;signin-form&quot;&gt;
                                	&lt;div class=&quot;form-group&quot;&gt;
                                    &lt;h2 class=&quot;form-signin-heading&quot;&gt;Please sign in&lt;/h2&gt;
                                    	&lt;div th:if=&quot;${param.error}&quot; class=&quot;alert alert-danger&quot;&gt;Wrong username and password&lt;/div&gt;
                                    	&lt;div th:if=&quot;${param.logout}&quot; class=&quot;alert alert-success&quot;&gt;You successfully logged out&lt;/div&gt;
                                    	&lt;label for=&quot;username&quot; class=&quot;sr-only&quot;&gt;Username&lt;/label&gt;
                                    	&lt;input type=&quot;text&quot; id=&quot;username&quot; name=&quot;username&quot; class=&quot;form-control&quot; placeholder=&quot;Username&quot; required=&quot;true&quot;&gt;
                                    	&lt;label for=&quot;password&quot; class=&quot;sr-only&quot;&gt;Password&lt;/label&gt;
                                    &lt;div class=&quot;form-group&quot;&gt;
                                    &lt;input type=&quot;password&quot; id=&quot;password&quot; name=&quot;password&quot; class=&quot;form-control&quot; placeholder=&quot;Password&quot; required=&quot;true&quot;&gt;
                                    &lt;/div&gt;	
                                        &lt;/div&gt;                               
                                    &lt;button class=&quot;btn btn-lg btn-primary btn-block signin-btn&quot; type=&quot;submit&quot;&gt;Login&lt;/button&gt;
                                    &lt;div class=&quot;custom-control custom-checkbox&quot;&gt;
                                &lt;input type=&quot;checkbox&quot; class=&quot;custom-control-input&quot; id=&quot;customCheck1&quot;&gt;
                                 &lt;!-- &lt;label class=&quot;custom-control-label&quot; for=&quot;customCheck1&quot;&gt;Remember me &lt;a href=&quot;#&quot;&gt; Need help?&lt;/a&gt;&lt;/label&gt; --&gt;
                                 &lt;a class= &quot;new-account&quot; href=&quot;/registration&quot;&gt;Create New Account&lt;/a&gt;
                                &lt;/div&gt;
                            &lt;/form&gt;
                            
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    
            &lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.slim.min.js&quot; integrity=&quot;sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
            &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot;&gt;&lt;/script&gt;
            &lt;script src=&quot;css/bootstrap-4.3.1-dist/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
        &lt;/body&gt;
    
    &lt;/html&gt;

**snippet of the ApiController.java**

    @Controller
    public class ApiController {
    	private final Logger log = LoggerFactory.getLogger(this.getClass());
    	private EmailService emailService;
    	private UserService userService;
    	private FormUserService formUserService;
    	
    	@Autowired
    	public void setFormUserService(FormUserService formUserService) {
    		this.formUserService = formUserService;
    	}
    
    	@Autowired
    	public void setEmailService(EmailService emailService) {
    		this.emailService = emailService;
    	}
    	
    	@Autowired
    	public void setUserService(UserService userService) {
    		this.userService = userService;
    	}
    
    	@RequestMapping(&quot;/&quot;)
	public String home(Model  model) {
		
		model.addAttribute(&quot;serverTime&quot;, new Date());
		model.addAttribute(&quot;itskills&quot;, &quot;IT skills&quot;);
		model.addAttribute(&quot;references&quot;, &quot;References&quot;);
		model.addAttribute(&quot;qualifications&quot;, &quot;Qualifications&quot;);
		model.addAttribute(&quot;myproject&quot;, &quot;My Project&quot;);
		model.addAttribute(&quot;it&quot;, &quot;IT&quot;);
		model.addAttribute(&quot;vaadin&quot;, &quot;VAADIN&quot;);
		model.addAttribute(&quot;java&quot;, &quot;JAVA&quot;);
		model.addAttribute(&quot;exam&quot;, &quot;EXAM&quot;);
		model.addAttribute(&quot;yourip&quot;, userService.userIpAddress());
		return &quot;index&quot;;
	}
    	@PostMapping(&quot;/login&quot;)
    	public String login(Model  model) {
    		
    		model.addAttribute(&quot;dateTime&quot;, new Date());
    		model.addAttribute(&quot;yourIp&quot;, userService.userIpAddress());
    		return &quot;auth/login&quot;;
    	}
    	}

**snippet of the config class**

    @EnableGlobalMethodSecurity(securedEnabled=true)
    @EnableWebSecurity
    @Configuration
    public class SecurityConf extends WebSecurityConfigurerAdapter {
    	
    	String[] staticResources  =  {
    	        &quot;/css/**&quot;,
    	        &quot;/layouts/main&quot;
    	        
    	    };
    	
    	@Bean
    	public UserDetailsService userDetailsService() {
    		return super.userDetailsService();	
    	}
    	
    	
    	private UserDetailsService userService;
    	
    	@Autowired
    	public void setUserService(UserDetailsService userService) {
    		this.userService = userService;
    	}
    	@Autowired
    	public void configureAuth(AuthenticationManagerBuilder auth) {
    		
    		try {
    			auth
    			.inMemoryAuthentication()
    				.withUser(&quot;user&quot;)
    				.password(&quot;user&quot;)
    				.roles(&quot;USER&quot;);
    		} catch (Exception e) {
    			 System.out.println(&quot; &quot; + e.getMessage());
    		}
    	}
    	
    	@Override
        public void configure(WebSecurity web) {
            web
                .ignoring()
                .antMatchers(staticResources);
       
    	        
    	}
    	@Override
    	public void configure(HttpSecurity httpSec) {
    		
    	
    		try {
    			httpSec.authorizeRequests()
    				
    				.antMatchers(staticResources).permitAll()
    				.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
    				.antMatchers(&quot;/admin/**&quot;).hasRole(&quot;ADMIN&quot;)
    				.antMatchers(&quot;/registration&quot;).permitAll()
    				.antMatchers(&quot;/reg&quot;).permitAll()
    				.antMatchers(&quot;/log&quot;).permitAll()
    				.antMatchers(&quot;/main&quot;).permitAll()
    				.antMatchers(&quot;/addUser&quot;).permitAll()
    				.anyRequest().authenticated()
    			.and()
    				.formLogin()
    				.loginPage(&quot;/login&quot;).permitAll()
    				.and().rememberMe().tokenValiditySeconds(60*60*7).key(&quot;message&quot;)
    				.and()
    		.logout()
    			.logoutSuccessUrl(&quot;/login?logout&quot;)
    			.permitAll();
    		} catch (Exception ex) {
    			System.out.println(&quot; &quot; + ex.getMessage());
    		}	
    }

</details>


# 答案1
**得分**: 0

只有在我将`WebConf`类中的`HIGHEST_PRECEDENCE`更改为`LOWEST_PRECEDENCE`它才对我起作用

```java
@Configuration
public class WebConf implements WebMvcConfigurer {
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("auth/login");
        registry.setOrder(Ordered.LOWEST_PRECEDENCE);
    }
    
}

显然,这并不是最佳实践,是否有其他更好的解决方案?

英文:

It only works for me when I change HIGHEST_PRECEDENCE for LOWEST_PRECEDENCE in the WebConf class:

@Configuration
public class WebConf implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController(&quot;/login&quot;).setViewName(&quot;auth/login&quot;);
registry.setOrder(Ordered.LOWEST_PRECEDENCE);
}
}

This is obviously not the best practice, is there any other better solution?

huangapple
  • 本文由 发表于 2020年4月11日 00:06:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/61144115.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定