SSM整合2
1. 显示商品信息(简单的增删改查)
- 在ItemsController中写一个list方法,用于将数据库中的商品信息显示到页面上
@RequestMapping("list")
public String list(Model model){
List<Items> itemsList = itemsService.findAll();
model.addAttribute("itemsList",itemsList);
return "/items/itemsList";
}
- 在itemsList.jsp中取出(从数据库中取出)保存到作用域中的数据,显示到页面上
<%--
Created by IntelliJ IDEA.
User: shuyy
Date: 2020/10/10
Time: 19:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>商品列表</title>
</head>
<body>
<table border="1">
<caption>商品列表</caption>
<tr align="center">
<td>名称</td>
<td>价格</td>
<td>描述</td>
<td>图片</td>
<td>创建时间</td>
<td colspan="2">操作</td>
</tr>
<c:forEach items="${itemsList}" var="items">
<tr>
<td>${items.name}</td>
<td>${items.price}</td>
<td>${items.detail}</td>
<td>${items.pic}</td>
<td>${items.createtime}</td>
<td><a href="${pageContext.request.contextPath}/items/delete.do?id=${items.id}">删除</a></td>
<td><a href="${pageContext.request.contextPath}/items/edit.do?id=${items.id}">修改</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
- 效果
2. 删除商品
- 写一个删除方法delete
- 根据传回来的id,删除数据库中的数据,删除完后返回到商品信息显示页面
@RequestMapping("delete")
public String delete(Integer id){
itemsService.deleteById(id);
return "forward:list.do";
}
- 上面的写法点击删除会直接删除掉信息,不是很友好,下面添加一下提示
<a href="javascript:if(window.confirm('是否删除?')){window.location.href='${pageContext.request.contextPath}/items/delete.do?id=${items.id}'}">删除</a>
- 效果
3. 显示修改商品信息页面
- 写一个edit方法,点击修改后,进入修改信息页面
@RequestMapping("edit")
public String edit(Integer id,Model model){
System.out.println("id:"+id);
Items items = itemsService.findById(id);
if (items != null){
model.addAttribute("items",items);
}
return "/items/itemsEdit";
}
- 商品信息详情页面,itemsEdit.jsp
<%--
Created by IntelliJ IDEA.
User: shuyy
Date: 2020/10/10
Time: 19:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>编辑商品</title>
</head>
<body>
编辑商品<br>
<form action="${pageContext.request.contextPath}/items/update.do" method="post">
<table border="1">
<tr>
<td>名称</td>
<td><input type="text" name="name" value="${items.name}">
<input type="hidden" name="id" value="${items.id}"></td>
</tr>
<tr>
<td>价格</td>
<td><input type="text" name="price" value="${items.price}"></td>
</tr>
<tr>
<td>描述</td>
<td><textarea cols="20" rows="5" name="detail">${items.detail}</textarea></td>
</tr>
<tr>
<td>图片</td>
<td>
<img src="${items.pic}">
<input type="file">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="更新">
</td>
</tr>
</table>
</form>
</body>
</html>
- 点击修改,效果
4. 更新商品信息
- 写一个更新方法update
- 发现这样写,直接点击更新会报错,因为没有设置时间
- 更新操作中并没有涉及时间
- 所以需要配置一下更新方法(还发现出现了中文乱码问题)
@RequestMapping("update")
public String update(Items items){
System.out.println(items);
items.setCreatetime(new Date());
itemsService.saveOrUpdate(items);
return "forward:list.do";
}
- 在web.xml中配置编码过滤器解决乱码问题
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 测试更新效果
- 发现描述没有变化
- 这是由于sql语句所致,查看一下逆向工程生成的sql
- 我们使用的方法没有为我们设置描述
- 需要换种方法
- 测试效果
- 成功
- 后台数据也不中文乱码了
5. 文件上传(商品图片设置)
- 导入以下jar包(在spring依赖包中的org.apache.commons包下)
- 在SpringMVC中设置文件上传大小
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10240000"></property>
</bean>
- JSP编写(导入js,使用ajax来提交带文件的表单)
- 设置一个隐藏的图片,用于在修改的时候显示
<%--
Created by IntelliJ IDEA.
User: shuyy
Date: 2020/10/10
Time: 19:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>编辑商品</title>
<script src="${pageContext.request.contextPath}/js/jquery.js"></script>
<script src="${pageContext.request.contextPath}/js/jquery.form.js"></script>
<script>
function submitImage() {
alert("提交图片到后台");
var url = '${pageContext.request.contextPath}/upload/itemsPic.do';
var options = {
type:'post',
dataType:'json',
data:{
username:'shu'
},
url:url,
success:function (respData) {
console.log(respData.imgUrl);
$('#pic').attr('src',respData.imgUrl)
$('#hiddenPic').val(respData.imgUrl)
}
}
$('#itemsForm').ajaxSubmit(options)
}
</script>
</head>
<body>
编辑商品<br>
<form id="itemsForm" action="${pageContext.request.contextPath}/items/update.do" method="post" >
<table border="1">
<tr>
<td>名称</td>
<td><input type="text" name="name" value="${items.name}">
<input type="hidden" name="id" value="${items.id}"></td>
</tr>
<tr>
<td>价格</td>
<td><input type="text" name="price" value="${items.price}"></td>
</tr>
<tr>
<td>描述</td>
<td><textarea cols="20" rows="5" name="detail">${items.detail}</textarea></td>
</tr>
<tr>
<td>图片</td>
<td>
<img id="pic" src="${items.pic}" width="80px" height="80px">
<input type="file" name="itemsPic1" onchange="submitImage();">
<input type="hidden" name="pic" id="hiddenPic" value="${items.pic}">
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="更新">
</td>
</tr>
</table>
</form>
</body>
</html>
- 后台编写
- 可以使用replace把uuid中的-去除
package com.it.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
@Controller
@RequestMapping("upload")
public class UploadController {
@RequestMapping("itemsPic")
public void itemsPic(HttpServletRequest request,PrintWriter printWriter) throws IOException {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
MultipartFile multiFile = multiRequest.getFile("itemsPic1");
String uploadFolder = request.getServletContext().getRealPath("/upload");
System.out.println("uploadFolder:"+uploadFolder);
File uploadFolderFile = new File(uploadFolder);
if (!uploadFolderFile.exists()){
uploadFolderFile.mkdirs();
}
String suffix = multiFile.getOriginalFilename().split("\\.")[1];
String fileName = UUID.randomUUID().toString()+"."+suffix;
String totalPath = uploadFolder+"\\"+fileName;
System.out.println("totalPath:"+totalPath);
FileCopyUtils.copy(multiFile.getInputStream(),new FileOutputStream(new File(totalPath)));
String imgURL = "http://localhost:8080/ssm_war_exploded/upload/" + fileName;
String respJson = "{\"imgUrl\":\"" + imgURL+"\"}";
printWriter.write(respJson);
}
}
- 在itemsList.jsp里设置一下图片显示
- 效果
- 也可以使用日期加三个随机数生成图片名,这样的名字短一点
6. Oscache页面缓存整合ssm项目
cache.memory=false
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=D:\\test
- 在src下配置log4j的配置文件log4j.properties,打印一些日志和加载信息
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
- 在web.xml中配置页面缓存
- 刷新缓存时间3600秒,作用域application都能访问到,/items/*下的所有页面都缓存,也可以设置为/items/list.do只缓存商品列表即可
<filter>
<filter-name>oscache</filter-name> <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>3600</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>application</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>oscache</filter-name>
<url-pattern>/items/*</url-pattern>
</filter-mapping>
7. SpringMVC整合freemarker
- 导入jar包(freemarker的jar在spring依赖包下)
- 在SpringMVC中配置freemarker
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html;charset=utf-8"/>
<property name="suffix" value=".ftl" />
</bean>
- 写一个hello.ftl模板体验一下(先创建个hello.html再重命名为hello.ftl)
- 在itemsController中写一个简单的方法,测试一下(数据通过模板引擎生成)
- 将itemsList.jsp改成itemsList.ftl
- 注意项目名的赋值
- 日期还可以配置成${item.createtime?string(“yyyy-MM-dd HH:mm:ss zzzz”)}
<#--<%--
Created by IntelliJ IDEA.
User: shuyy
Date: 2020/10/10
Time: 19:51
To change this template use File | Settings | File Templates.
--%>-->
<#--<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>--><#--无需标签-->
<#assign projectName = "ssm" />
<html>
<head>
<title>商品列表</title>
</head>
<body>
<table border="1">
<caption>商品列表by freemarker</caption>
<tr align="center">
<td>名称</td>
<td>价格</td>
<td>描述</td>
<td>图片</td>
<td>创建时间</td>
<td colspan="2">操作</td>
</tr>
<#--<c:forEach items="${itemsList}" var="items">-->
<#list itemsList as items><#--遍历-->
<tr>
<td>${items.name}</td>
<td>${items.price}</td>
<td>${items.detail}</td>
<td><img src="${items.pic}" width="80px" height="80px"></td>
<td>${items.createtime?datetime}</td>
<td><a href="javascript:if(window.confirm('是否删除?')){
window.location.href='${projectName}/items/delete.do?id=${items.id}'
}">删除</a></td>
<td><a href="${projectName}/items/edit.do?id=${items.id}">修改</a></td>
</tr>
</#list>
<#--</c:forEach>-->
</table>
</body>
</html>
<#--<a href="${pageContext.request.contextPath}/items/delete.do?id=${items.id}">删除</a>-->
- 效果
- 由于编辑页面没有修改点击会报错
8. 配置SpringMVC的登录拦截器
- Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理
- 在WEB-INF下的views中写一个简单的登录页面login.jsp
<form action="${pageContext.request.contextPath}/login.do" method="post">
<table border="1">
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="登录"></td>
</tr>
</table>
</form>
- 写一个登录控制器LoginController
@Controller
public class LoginController {
@RequestMapping("login")
public String login(HttpServletRequest request,String username,String password){
if ("shu".equals(username) && "123".equals(password)){
request.getSession().setAttribute("user",username);
return "forward:items/list.do";
}
return "login";
}
}
- 这里返回页面没有写斜杠的原因是,在SpringMVC中配置拼接时加了斜杠
- 写一个登录拦截器,放行一些方法和一些逻辑配置
package com.it.web.controller.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
System.out.println("预处理...");
if (request.getRequestURI().indexOf("login.do") >= 0){
return true;
}
if (request.getSession().getAttribute("user") != null){
return true;
}
request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request,response);
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("未返回视图前,后处理...");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("返回视图前,后处理...");
}
}
- 在SpringMVC配置文件中配置登录拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.it.web.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
- 设置首页为登录页面login.jsp(intellij idea启动javaweb项目后,默认打开的是index.jsp页面,在index.jsp页面中转发到login.jsp中即可)
<%--两种方法用其一即可--%>
<%--<%
request.getRequestDispatcher("WEB-INF/views/login.jsp").forward(request,response);
%>--%>
<%--转发到登录页面--%>
<jsp:forward page="WEB-INF/views/login.jsp"></jsp:forward>
- 效果
- 由于已经登录,session中有值,同一个浏览器直接访问items/list.do,能访问到
- 但是换一个浏览器直接访问items/list.do是访问不到的(因为sessionId不同,数据无法共享),会转发到登录页面
- 如果访问的路径,项目中不存在,会直接报错,拦截器不会去拦截(可以考虑自己写404页面)