关于访问首页
如果静态资源文件夹和模板引擎下都有index.html,以下方式会优先访问模板引擎中的。
1、可以在controller中使用一个空方法,
2、自己配置组件,但是一定要使用@Bean
将组件注册到容器中
使用模板引擎(使用th:href链接)的好处
比如当更改项目名时,会自动加上项目名
<link href="asserts/css/bootstrap.min.css" th:href="@{/bootstrap/4.1.2/css/bootstrap.css}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
登录
开发期间模板引擎修改以后要实时生效步骤:
1、禁用模板引擎缓存
spring.thymeleaf.cache=false
2、页面修改后使用Ctrl+F9来进行重新编译
防止重复提交表单
因为在登录成功后是转发到跳转的页面main.html,此时刷新当前页面会提示是否重新提交表单,此时我们可以选择重定向到需要跳转的页面main.html
但此时直接访问main.html也是可以访问到了,所以此时需要使用拦截器
拦截器重点
SpringBoot已经帮我们处理过静态资源的拦截
1、先定义拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
Object user = request.getSession().getAttribute("loginuser");
if(user==null){
request.setAttribute("msg","您还没有权限,请先登录");
request.getRequestDispatcher("index.html").forward(request,response);
return false;
}else{
//是true就表示可以放行
return true;
}
}
2、将拦截器注册到容器中
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
//将登录拦截器注册到容器中,并且拦截所有的访问,然后排除一些访问
//对于静态资源的,SpringBoot已经做好了映射,所以不用排除静态资源的访问
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/","/index.html","/user/login");
}
公共片段的抽取
<div th:fragment="topbar">
.......
</div>
<div id="sidebar">
.......
</div>
//引入公共片段
~{templatename::selector}模板名:选择器
<div th:replace="~{dashboard::topbar}">
</div>
~{templatename::fragmentname}模板名:片段名
<div th:replace="~{dashboard::#sidebar}">
</div>
使用th:insert 等属性引入可以不用写~{},但是行内写法一定要加上
例如[[~{}]],[(~{})]
公共片段引入三种方式:
th:insert 将 公共片段整个插入到声明引入的标签div中
th:replace 将声明引入的div标签替换为整个公共片段
th:include 将被引入的片段的内容包含到进这个标签div中
进行传参引入
当点击某个页面时,该导航栏高亮,此时就可以根据传入参数进行判断
在被引入片段中进行判断
th:class="${activeUrl=='emps'?'nav-link active':'nav-link'}"
在引入时进行传参
<div th:replace="commons/bar::#sidebar(activeUrl='main.html')"></div>
这种传参适合不带~{}
带有~{}方式的传参,自行参考文档
日期的格式化
有很多种,见文档
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
拼接链接
当使用restful风格发送数据时,如果需要加参数,其中特别注意th:href="@{/emp/}+${emp.id}">
要带上路径和参数之间要有/
,注意放的位置
<a class="btn btn-sm btn-primary" href="emp" th:href="@{/emp/}+${emp.id}">编辑</a>
Restful风格请求发送数据
1、SpringMvc中配置HiddenHttpMethodFilter(SpringBoot自动配置好的)
2、创建一个post表单(只要是提交的按钮没有在表单内部,都需要创建表单后,才能使用Restful风格的进行提交)
3、创建一个input项,name=”_method”,值就是我们指定的请求方式
Restful风格url案例:
尽管是一个删除按钮,必须需要写一个表单,
<form th:href="@{/emp/}+${emp.id}" method="post">
<input type="hidden" name="_method" value="delete">
<button class="btn btn-sm btn-danger" href="emp" th:href="@{/emp}">删除</button>
</form>
但是有很多每个都写表单又很浪费,所以可以把表单放到外面,而是使用js进行提交
<button th:attr="del_uri=@{/emp/}+${emp.id}" class="btn btn-sm btn-danger del_btn">删除</button>
<form id="del_form" method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script>
$(".del_btn").click(function(){
//注意:在这个地方发现点击事件没有哦发生,原来是上面的script代码没有执行,js代码是从上执行的,然后导致这个方法也没有执行。
//声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,然后才按顺序执行js代码。
$("#del_form").attr("action",$(this).attr("del_uri")).submit();
});
</script>
花了半小时找到的错误
说什么类型转换错误:最后是:For input string: "list"
原来是因为我是要重定向到某个页面,应当是转向另一个请求,然后通过那个请求转向要去的页面,而我直接重定向到那个页面去了。