Spring Boot Some pit https://www.jianshu.com/p/3494c84b4be3
globalization:
1) Set Home:
Method 1: Add a request controller
@RequestMapping({"/","index.html"}) public String index(){ return "index.html"; }
Method 2: Set Configuration File: WebMvcConfigurer in the addViewControllers registry.addViewController ( "/ index.html") setViewName ( "login"); registry.addViewController ( "/") setViewName ( "login");..
package com.anitano.config; import com.anitano.component.MyLocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** *扩展SpringMVC的功能 */ @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { / * View mapping: When the browser sends anita will come * Success / registry.addViewController ( "/").setViewName("login"); registry.addViewController("/anita").setViewName("success"); } /** * 所以的WebMvcConfigurer组件都会起作用 * @return */ @Bean //记得加到容器里 public WebMvcConfigurer webMvcConfigurer(){ WebMvcConfigurer adapter= new WebMvcConfigurer() { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login.html").setViewName("login"); registry.addViewController("/index.html").setViewName("login"); registry.addViewController("/dashboard.html").setViewName("dashboard"); / * * Set interceptor / } @Override public void addInterceptors (InterceptorRegistry Registry) { } }; return Adapter; } / ** * modification area resolver * @return * / @Bean public LocaleResolver that LocaleResolver () { return new new MyLocaleResolver (); } }
2) modify the details: import namespace and set up Chinese page
<html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
Adding th: src = "@ {asserts / img / bootstrap-solid.svg}" When a project name change, the link will automatically add the project name.
<img class="mb-4" src="asserts/img/bootstrap-solid.svg" th:src="@{asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
2) Internationalization i18n
1, create a new folder i18n and several configuration files, IDEA will automatically recognize you have to do international. Note that to set the profile settings File Encoding UTF-8 encoding and setting inside asii manner,
2, open just one file, click on the Resource Bundle below, there is a + sign at the top, click + Add Property. After completion of the increase in property values.
3, designated international resource configuration file locations: In the project's configuration file inside to add: spring.messages.basename = i18n.login
4, the value of the page acquired in international: TH : text = "{#} login.tip"
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<!DOCTYPE html> <html lang="zh-cn" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="asserts/css/bootstrap.min.css" th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" action="dashboard.html" th:action="@{/user/login}" method="post"> <img class="mb-4" src="asserts/img/bootstrap-solid.svg" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1> <label class="sr-only" th:text="#{login.username}">Username</label> <input type="text" name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only" th:text="#{login.password}">Password</label> <input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"> [[#{login.remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm" th:href="@{index.html(language='zh-CN')}">中文</a> <a class="btn btn-sm" th:href="@{index.html(language='en-US')}">English</a> </form> </body> </html>
Here will be displayed in English according to the language of the browser. If there are to Chinese garbled because the encoding profile as I said before is not UTF-8
5) Modify SpringMVC profile, the default request header according to the international setting region information, click on the link to the international switch.
Add a class
package com.anitano.component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.LocaleResolver; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale; /** * 区域信息解析器 */ public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { String language = httpServletRequest.getParameter("language"); Locale locale=Locale.getDefault(); if(!StringUtils.isEmpty(language)){ String[] strings = language.split("_"); locale=new Locale(strings[0],strings[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } }
Modify their newly added SpringMVC profile categories:
/ ** * modification area resolver * @return * / @Bean public LocaleResolver that LocaleResolver () { return new new MyLocaleResolver (); }
Switch links in English
<a class="btn btn-sm" th:href="@{index.html(language='zh-CN')}">中文</a> <a class="btn btn-sm" th:href="@{index.html(language='en-US')}">English</a>
User login
During the development of the page template engine later modifications to take effect immediately: First prohibit template engine cache, Ctrl + F9: recompile
# Disable template engine cache spring.thymeleaf.cache = false
When a password error: error reading information from the information returned. Only there is only an error message is displayed
<p class="text-danger" th:text="${msg}" th:if="${ not #strings.isEmpty(msg)}"></p>
After successful login redirection:
registry.addViewController("/dashboard.html").setViewName("dashboard")
package com.anitano.config; import com.anitano.component.MyLocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** *扩展SpringMVC的功能 */ @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { /*视图映射 :当浏览器发送 anita 会来到success*/ registry.addViewController("/anita").setViewName("success"); registry.addViewController ( "/ of dashboard.html") setViewName ( "Dashboard");. } / ** * modification area resolver * @return * / @Bean public LocaleResolver that LocaleResolver () { return new new MyLocaleResolver (); } }
return "redirect:/dashboard.html";
@PostMapping(value = "user/login") public String login(@RequestParam("username")String username, @RequestParam("password")String password, Map<String,Object> map){ if(!StringUtils.isEmpty(username) && "123456".equals(password)){ //return "dashboard"; return "redirect:/dashboard.html"; } map.put("msg","用户名或密码错误"); return "index"; }
Set interceptor: Spring Boot 1.x version set interceptor static resources will not be intercepted, 2.x version of static resources but will be blocked, so to release
About static resources after setting interceptor intercepted: https://my.oschina.net/dengfuwei/blog/1795346
1) add a new method:
com.anitano.component Package; Import org.springframework.web.servlet.HandlerInterceptor; Import org.springframework.web.servlet.ModelAndView; Import the javax.servlet.http.HttpServletRequest; Import javax.servlet.http.HttpServletResponse; / ** * interceptor component: Log in to intercept, not allowed to enter the login page background and for staff CRUD * / public class LoginHandlerInterceptor the implements HandlerInterceptor { @Override public boolean preHandle (Request the HttpServletRequest, HttpServletResponse the Response, Object Handler) throws Exception { // The method of performing pre Object Request.getSession = User () the getAttribute ( "the LoginUser");. IF (User == null) { // not logged in, return to the login page request.setAttribute ( "MSG", "not logged Login"); request.getRequestDispatcher("/login.html").forward(request,response); return false; }else { //已登录, return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
2) In the profile configuration: Note Release / user / login to increase the front /
/*注册拦截器*/ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/","/index.html","/user/login","/login.html","/asserts/**"); /*拦截 所有请求, 放行 "/","/index.html","user/login" */ }
Full configuration file:
package com.anitano.config; import com.anitano.component.LoginHandlerInterceptor; import com.anitano.component.MyLocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** *扩展SpringMVC的功能 */ @Configuration MyMvcConfig the implements WebMvcConfigurer {class public @Override public void addViewControllers (ViewControllerRegistry Registry) { / * map view: When the browser sends anita will come * Success / registry.addViewController ( "/ anita") setViewName ( "Success");. } / ** * so that the assembly will act WebMvcConfigurer * @return * / @Bean added // remember container public WebMvcConfigurer webMvcConfigurer () { WebMvcConfigurer new new WebMvcConfigurer = Adapter () { @Override public void addViewControllers (ViewControllerRegistry Registry) { Registry . .addViewController ( "/ login.html") setViewName ( "login"); Registry . .addViewController ( "/ index.html") setViewName ( "login"); registry.addViewController("/").setViewName("login"); registry.addViewController("/main.html").setViewName("dashboard"); } /*注册拦截器*/ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/","/index.html","/user/login","/login.html","/asserts/**"); /*拦截 所有请求, 放行 "/","/index.html","user/login" */ } }; @Bean * / * @return * modification area resolver / ** return adapter; } public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } }
Public page extract
# Extracted public page of dashboard.html <NAV class = "Sticky Navbar Navbar-Dark Dark Flex-Top-BG-MD-P-0 nowrap" TH: the fragment = "topbar"> </ NAV> # page in list.html applications ---> this will only insert <nav> </ nav>, does not have the <div> </ div> insert <div th: replace = "dashboard :: topbar">
The so-called template name HTML :: Template :: ID selector selector or class selector ----> # selector name. Selector name
1, the common segments extracted <div TH: the fragment = "Copy"> © 2011 of The Good The Thymes the Virtual Grocery </ div> 2, into the public segment <div th: insert = "~ {footer :: copy}"> </ div > ~} {TemplateName selector ::: :: template name selectors ~ {templatename :: fragmentname}: template name :: fragment name 3, the effect of default: INSERT public div tag fragments If TH: insert the properties such as introduction, can not write ~ {}: the written line can add: [[{~}]]; [({~})];
Introducing three kinds of th attributes common segments:
th: insert: the common fragment of the entire insert element declaration to the introduced ----> example above, this would <div> <NAV> </ NAV> </ div> introduced into
th: replace: introducing declarations element with the common segments ------> this will only insert <nav> </ nav>, also not the <div> </ div> introduced into
th: include: a fragment is incorporated into the label comprising -----> only <div> </ div>, inside no <nav> </ nav>
Dynamic link highlighted:
1) Add a variable when extracting activeUri
th:fragment="navbar(activeUri)"
2) determination: the main value of this variable is added labeled highlighted
th:classappend="${activeUri}=='main'?' active ' :''"
3) Set the value of a variable is introduced
<! - introducing sidebar ->
< div TH : Replace = "Commons / bar :: Navbar (activeUri = 'main')"> </ div>
Display employee data:
Time Format: $ {# dates.format (emp.birth, 'yyyy / MM / dd HH: mm')}
<table class="table table-striped table-sm"> <thead> <tr> <th>#</th> <th>lastName</th> <th>email</th> <th>gender</th> <th>department</th> <th>birth</th> </tr> </thead> <tbody> <tr th:each="emp:${emps}"> <td th:text="${emp.id}"></td> <td th:text="${emp.lastName}"></td> <td th:text="${emp.email}"></td> <td th:text="${emp.gender}==0?'女':'男' "></td> <td th:text="${emp.department.departmentName}"></td> <td th:text="${ #dates.format(emp.birth,'yyyy/MM/dd HH:mm') }"></td> </tr> </tbody> </table>
Automated assembly, modification date format:
# Date format type spring.mvc.date-format = yyyy-MM- dd HH: mm
Path variables: link http: // localhost: 8080 / emp / 1001 want to get to 1001 as a value. Use @GetMapping ( "/ emp / {id }"), the parameters used in @PathVariable ( "id") Integer id
@GetMapping("/emp/{id}") public String toEditPage(@PathVariable("id") Integer id,Model model){ Employee employee = employeeDao.get(id); model.addAttribute("employee",employee); return "/emp/add"; }
Modify submission form: Add the following statement from the form inside: When time employee this value is present, put this label to the inside pages, and the submission is put.
<input type="hidden" value="put" th:if="${employee} !=null">
form Form Required: required = ""
a