首先将模板文件导入resources/templates,配置MyMvcConfig
@Configurationpublic class MyMvcConfig implements WebMvcConfigurer {// 无逻辑视图跳转 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); }}
通过在继承了WebMvcConfigurer接口的MyMvcConfig类中注册bean或重写方法,来自定义SpringBoot底层默认的代码
此时启动ConfigApplication主类,在地址栏输入"localhost:8080/"或"localhost:8080/index.html",无逻辑跳转到index,addViewControllers方法的好处是实现起来比写一个Controller类简单,但只能实现无逻辑跳转
现在浏览器页面中没有配置的css样式和img,在html标签中加入如下配置
xmlns:th="http://www.thymeleaf.org"
Spring官方支持的服务的渲染模板中,并不包含jsp。而是Thymeleaf等,而Thymeleaf与SpringMVC的视图技术,及SpringBoot的自动化配置集成非常完美,几乎没有任何成本,只用关注Thymeleaf的语法即可。也就是说jsp已经被SpringBoot官方淘汰。
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"><link th:href="@{/css/signin.css}" rel="stylesheet">
Thymeleaf语言非常简单,只需在html标签前加 "th:" ,后边类似EL表达式,取地址用@{},取值用${},导入用~{}等等
这样配置后,html页面中的css样式终于显示了出来
i18n页面国际化:
Springboot底层默认实现了国际化,先来看一下官方国际化是怎样配置的:
进入AcceptHeaderLocaleResolver
可以看到这个类继承了LoclaResolver接口,所有我们自定义国际化配置时的类也模仿官方来做
public Locale resolveLocale(HttpServletRequest request) { Locale defaultLocale = this.getDefaultLocale(); if (defaultLocale != null && request.getHeader("Accept-Language") == null) { return defaultLocale; } else { Locale requestLocale = request.getLocale(); List supportedLocales = this.getSupportedLocales(); if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) { Locale supportedLocale = this.findSupportedLocale(request, supportedLocales); if (supportedLocale != null) { return supportedLocale; } else { return defaultLocale != null ? defaultLocale : requestLocale; } } else { return requestLocale; } } }
这是官方的国际化核心方法,可以看出官方是通过将Locale存入request的头文件配置中,再在此方法中取出,如果locale为空,则使用默认国际化,若不为空则new一个与传入值对应的locale,虽然官方给我们实现了,但是从头文件里取出参数难免对我门不友好,操作复杂,所以我们可以自定义一个国际化配置器
首先,将index中转换的标签修改
class= class=
我们直接将参数写在url里,这样取出会很方便,zh_CN即为简体中文,依此类推,接着要新建默认配置文件,简体中文配置文件和英文配置文件
idea提供了编写国际化配置的可视化界面,为每个要国际化的文本位置都写配置
public class MyLocale implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { //获取默认Locale Locale locale = Locale.getDefault(); //获取url中的language参数 String language=httpServletRequest.getParameter("language"); if(!StringUtils.isEmpty(language)){ //若不为空则用_分割,再拼接 String[] strings = language.split("_"); System.out.println(language); locale = new Locale(strings[0], strings[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { }}
MyLocale类就继承LocaleResolver接口,实现它的全部方法,只对resolveLocale重写
再MyMvcConfig中注册bean
// 注册LocaleResolver国际化 @Bean public LocaleResolver localeResolver(){ return new MyLocale(); }
国际化完成
登录功能实现:
form表单提交到/login请求中,编写Controller类
@RequestMapping("/login") public String login(Model model, @RequestParam("username") String username, @RequestParam("password") String password, HttpSession httpSession){ if(!StringUtils.isEmpty(username) & "123".equals(password)){ return "redirect:/main.html"; } httpSession.setAttribute("loginUser",username); model.addAttribute("msg","用户名或密码错误"); return "index"; }
若username不为空且password等于123,重定向到main.html请求中,反之则在session和model中都加入错误信息后返回到index主页
配置拦截器,防止用户自行在地址栏输入main.html直接进入后台
//拦截器public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String msg = (String)request.getSession().getAttribute("loginUser"); if(msg==null){ //未登录 request.setAttribute("loginMsg","请先登录");// response.sendRedirect("/index.html"); request.getRequestDispatcher("/index.html").forward(request,response); return false; }else { return true; } }}
若未登录则跳转到登陆页面,并阻止放行,若已登录则放行
注册拦截器
// 注册拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/main.html");}
只拦截/main.html请求
用户输入/main.html请求时若未登录会拦截,已登录会直接进入后台
用户注销实现:
@RequestMapping("/del") public String del(HttpSession httpSession){ httpSession.removeAttribute("loginUser"); return "index"; }
class="nav-link" th:href="@{/del}">Sign out
展示全部成员信息:用Thymeleaf-each循环实现
@Controllerpublic class UserController { @Autowired private EmployeeDao employeeDao; @RequestMapping("/Users") public String Users(Model model){ Collection employeeAll = employeeDao.getEmployeeAll(); model.addAttribute("users",employeeAll); return "/list"; }}
@Repositorypublic class EmployeeDao { public static Map employMap=null; @Autowired public DepartmentDao departmentDao; static { employMap = new HashMap<>(); employMap.put(101,new Employee(1001,"张三","123@qq.com",1,new Department(101,"吃饭部"))); employMap.put(102,new Employee(1002,"李四","122@qq.com",1,new Department(102,"学习部"))); employMap.put(103,new Employee(1003,"张四","123@qq.com",0,new Department(103,"睡觉部"))); employMap.put(104,new Employee(1004,"李三","121@qq.com",1,new Department(104,"王者部"))); employMap.put(105,new Employee(1005,"李张三","223@qq.com",0,new Department(105,"吃屎部"))); } //查询全部员工信息 public CollectiongetEmployeeAll(){ return employMap.values(); }}
@Data@NoArgsConstructorpublic class Employee { private Integer id; private String lastName; private String email; private Integer gender; private Department department; private Date birth; public Employee(Integer id, String lastName, String email, Integer gender, Department department) { this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; this.department = department; this.birth = new Date(); }}
<tbody> <tr th:each="user,Employee:${users}" > <th th:text="${user.id}">th> <th th:text="${user.lastName}">th> <th th:text="${user.email}">th> <th th:text="${user.gender}">th> <th th:text="${user.department}">th> tr> tbody>
功能实现