页面效果和之前的是一样的,最近在学spring boot所以这次使用了spring boot来重构代码,可以进我的博客去看之前用servlet+tomcat实现的
JavaWeb-jsp+mybatis+servlet简易购书系统
JavaWeb-简易购书系统使用Bootstrap
这里大概介绍下这次的项目:
模板引擎使用的是:Thymeleaf
界面使用的是:BootStrap
数据库使用的是:Mysql
持久层框架使用的是:Mybatis(注解版)
使用了RESTful:通过GET,POST,DELETE,PUT请求实现各种功能
项目结构
页面效果
因为代码量不少,所以这里只记录我在过程中遇到的问题,代码都在我的GitHub中,链接在最后,Springboot是刚学有很多不对的地方,欢迎指出,欢迎一切讨论
本次使用的模板引擎是:thymeleaf
在开发的过程中最好关闭thymeleaf的缓存
spring:
thymeleaf:
cache: false
也就是清除缓存,实现热部署。也就是修改了html后不用重启,刷新页面就能看到效果。不过这儿特别强调一下,修改完html后一定要ctrl+f9重新build一下。
Reason: Failed to determine a suitable driver class
这个没有添加数据配置或者数据库没有配置好
org.apache.ibatis.binding.BindingException: Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
在使用mybatis中遇到了这个问题,这是因为当有多个参数的时候,它会找不到对应的参数从而报错,在有多个参数的时候就需要在每个参数前加上@Param,括号中注解的名称就是mapper中映射的值.
@Select("select *from bookuser where user_name = #{username} and user_password = #{userpassword}")
public User login(@Param("username") String username, @Param("userpassword") String userpassword);
@Controller和@RestController
@RestController 是@ResponseBody + @Controller合在一起 如果使用@RestController注解Controller,controller无法返回HTML,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
@Controller 配合视图解析器 InternalResourceViewResolver 返回到指定的HTML
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
thymeleaf引入公共片段:
在公共代码上写
id="sidebar"或者th:fragment="sidebar"
在引用处写
<div th:replace="模板名 :: 选择器"></div>或者<div th:replace="模板名 :: 片段名"></div>
replace会覆盖引用的标签,而insert不会
在这里提一下如何用thymeleaf实现列表动态动态高亮,即点那个选项那个选项就高亮
在thymeleaf语法可以为片段函数设置参数
利用这一性质,我们就可以加入一个参数,根据这个参数来判断当前的链接是否要高亮
<a th:href="@{/page}" >图书列表a>li>
<li th:class="${url=='search' ? 'nav-link active' : 'nav-link'}"><a th:href="@{/search}" >搜索图书a> li>
<li th:class="${url=='userupdate' ? 'nav-link active' : 'nav-link'}" ><a th:href="@{/userup}">个人中心a>li>
<li th:class="${url=='usercar' ? 'nav-link active' : 'nav-link'}"><a th:href="@{/usercar}">购物车a>li>
<li><a th:href="@{/logout}">退出系统a>li>
<div th:replace="common/usersidebar :: #sidebar (url='main')">div>
springboot推荐使用thymeleaf模板,thymeleaf的语法和jstl有着不小的区别,我在写分页的列表的时候在各种条件判断卡了我好久,因为th语法必须放在标签里面用不能单独用,后面发现
<th:block>th:block>
对于多种条件判断和循环很好用,我给个分页的HTML你没感受一下
<th:block th:if="${page.pageNum >1 && page.pageNum" >
<li><a th:href="@{'/page?pageNum='+${(page.pageNum)-1}}">上一页a>li>
<th:block th:each="num,stat:${#numbers.sequence(page.start,page.end)}">
<li th:if="${page.pageNum == num}"><span style="color: deeppink" th:text="${num}">span>li>
<li th:if="${page.pageNum != num}"><a th:href="@{'/page?pageNum='+${num}}" th:text="${num}">a>li>
th:block>
<li><a th:href="@{'/page?pageNum='+${(page.pageNum)+1}}">下一页a>li>
th:block>
springMvc拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor{
//目标方法执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
User user = (User) request.getSession().getAttribute("user");
if(null == user){
request.setAttribute("msg","没有权限请先登录" );
request.getRequestDispatcher("/login").forward(request,response );
return false;
}else{
return true;
}
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login.html","/login","/resource/**","/webjars/**","/img","/regist","/user/regist");
}
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'key' in 'class java.lang.String'
实体类中没有对应的参数’key’ 加上@param注解,不使用@Param注解时,参数只能有一个,并且是Javabean。在SQL语句里可以引用JavaBean的属性,而且只能引用JavaBean的属性。
使用Ajax进行post请求时
function addCartFun(bookId,ind) {
var number = document.getElementsByClassName("bookNumber");
var num = number[ind].value;
var ajax;
if (window.XMLHttpRequest){
ajax = new XMLHttpRequest();
} else if (window.ActiveXObject){
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
ajax.onreadystatechange = function () {
if (ajax.readyState == 4){
if (ajax.status == 200){
}
}
}
ajax.open("post","user",true);
ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");//post请求一定要加上这句话
ajax.send("bookId=" + bookId + "&number=" + num+"&pageNum="+[[${page.pageNum}]]);
}
在thymeleaf中,可以这样调用javascript
th:οnclick="'javascript:addCartFun('+${book.bookId}+','+${stat.index}+');'"
这样就可以传入后台的数据为参数
因为form表单只支持get和post请求,所以在spring boot中使用delete请求,可以用如下的方法
添加一个表单,并在表单添加一个input,name为_method,value为delete
然后使用javascript,提交表单
Missing URI template variable ‘bookid’ for method parameter of type String
@PathVariable的属性名要与请求参数相同
本次代码都在我的GitHub中:GitHub