6. 添加MD5加密算法(保护密码)
- MD5(message-digest algorithm 5)信息摘要算法,
它的长度一般是32位的16进制数字符串(如81dc9bdb52d04dc20036dbd8313ed055) - 由于系统密码明文存储容易被黑客盗取
- 应用:注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对 - md5不可逆,即没有对应的算法,从产生的md5值逆向得到原始数据。
但是可以使用暴力破解,这里的破解并非把摘要还原成原始数据,如暴力枚举法。
MD5Util工具类
package com.yanyu.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Util {
public final static String getMD5(String str){
try {
MessageDigest md = MessageDigest.getInstance("SHA");//创建具有指定算法名称的摘要
md.update(str.getBytes()); //使用指定的字节数组更新摘要
byte mdBytes[] = md.digest(); //进行哈希计算并返回一个字节数组
String hash = "";
for(int i= 0;i<mdBytes.length;i++){ //循环字节数组
int temp;
if(mdBytes[i]<0) //如果有小于0的字节,则转换为正数
temp =256+mdBytes[i];
else
temp=mdBytes[i];
if(temp<16)
hash+= "0";
hash+=Integer.toString(temp,16); //将字节转换为16进制后,转换为字符串
}
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
测试
@Test
public void testMD5(){
String md5 = MD5Util.getMD5("000000");
System.out.println(md5); //c984aed014aec7623a54f0591da07a85fd4b762d
}
7. 实现登录功能
7.1 业务逻辑层 – 创建AdminService接口,添加登录login
AdminService
package com.yanyu.service;
import com.yanyu.pojo.Admin;
public interface AdminService {
Admin login(String name,String pwd);
}
7.2 业务逻辑层 – 创建AdminServiceImpl,实现AdminService接口登录login
通过数据访问层对象AdminMapper,查找数据,成功返回用户数据,失败返回null
AdminServiceImpl
package com.yanyu.service.impl;
import ...
@Service
public class AdminServiceImpl implements AdminService {
//数据访问层对象,spring自动创建注入
@Autowired
AdminMapper adminMapper;
@Override
public Admin login(String name, String pwd) {
//根据用户名在数据库查找用户
//使用AdminExample对象来封装条件
AdminExample example = new AdminExample();
/* select * from admin where a_name = 'admin' */
//添加用户名a_name = 'admin'条件
example.createCriteria().andANameEqualTo(name);
//执行查询
List<Admin> adminList = adminMapper.selectByExample(example);
if(adminList.size()>0){
Admin admin = adminList.get(0);
//进行密码对比判断 - 密码是密文
String md5 = MD5Util.getMD5(pwd);
/* System.out.println(admin.getaPass()+" "+md5);*/
if(md5.equals(admin.getaPass())){
return admin;
}
}
return null;
}
}
7.3 界面控制层 – 创建AdminAtion,添加login,判断是否登陆成功,并跳转相应页面
调用业务逻辑层对象AdminServiceImpl,获取登录信息,登陆成功,跳转到main.jsp页面,登陆失败,跳转到login.jsp页面
AdminAtion
package com.yanyu.controller;
import ...
@Controller
@RequestMapping("/admin")
public class AdminAction {
//业务逻辑层对象
@Autowired
AdminService adminService;
//实现登陆的判断,进行相应跳转、
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){
Admin admin = adminService.login(name,pwd);
if(admin!=null){
//登陆成功,跳转到main.jsp页面(视图解析器)
request.setAttribute("admin",admin); // 存储用户信息
return "main";
}else {
//登陆失败,跳转到login.jsp页面(视图解析器)
request.setAttribute("errmsg","用户名或密码不正确!"); //返回失败信息
return "login";
}
}
}
8. 实现查询所有商品数据
8.1 业务逻辑层 – 创建ProductInfoService接口,添加查询所有商品功能getAll
ProductInfoService
package com.yanyu.service;
import ...
public interface ProductInfoService {
//显示所有商品、
List<ProductInfo> getAll();
}
8.2 业务逻辑层 – 创建ProductInfoServiceImpl,实现getAll
ProductInfoServiceImpl
package com.yanyu.service.impl;
import ...
@Service
public class ProductInfoServiceImpl implements ProductInfoService {
//数据访问层对象
@Autowired
ProductInfoMapper productInfoMapper;
@Override
public List<ProductInfo> getAll() {
//没有条件,查询所有
return productInfoMapper.selectByExample(new ProductInfoExample());
}
}
8.3 界面控制层 – 创建ProductInfoAtion,添加getAll,传递数据到前台
package com.yanyu.controller;
import ...
@Controller
@RequestMapping("/prod")
public class ProductInfoAction {
//业务逻辑层对象
@Autowired
ProductInfoService productInfoService;
//显示所有商品
@RequestMapping("/getAll")
public String getAll(HttpServletRequest request){
List<ProductInfo> list = productInfoService.getAll();
//传递数据
request.setAttribute("list",list);
//跳转页面
return "product";
}
}
9. 实现分页展示 – mybatis插件pagehelper
9.1 业务逻辑层 – ProductInfoService接口中,添加分页功能splitPage
PageInfo由分页插件pagehelper提供(PageInfo页面数据类,包含当前页,页大小,当前页大小,当前页数据…),pageNum当前页,pageSize页的大小
//分页功能,PageInfo由分页插件pagehelper提供,pageNum当前页,pageSize页的大小
PageInfo splitPage(int pageNum,int pageSize);
9.2 业务逻辑层 – ProductInfoServiceImpl中,实现splitPage,完成分页
@Override
public PageInfo splitPage(int pageNum, int pageSize) {
//分页插件使用PageHelper工具类完成分页设置(),放在取数据集合之前
PageHelper.startPage(pageNum,pageSize);
//条件查询 - 主键降序 select* from product_info order by p_id desc
ProductInfoExample example =new ProductInfoExample();
//添加条件order by p_id desc
example.setOrderByClause("p_id desc");
//查询数据,分页设置PageHelper要放在取数据集合之前
List<ProductInfo> list = productInfoMapper.selectByExample(example);
//将数据封装进PageInfo中,PageInfo自动对list进行分页
PageInfo<ProductInfo> pageInfo = new PageInfo<>(list);
return pageInfo;
}
9.3 界面控制层 – ProductInfoAtion中,添加splitPage,传递数据到前台product.jsp
显示初始页数据(第一页的5条数据)到前台 , 翻页由ajax异步来完成
设置每页显示记录数常量PAGE_SIZE,方便修改
//每页显示记录数
public static final int PAGE_SIZE = 5 ;
//显示初始页数据(第一页的5条数据)
@RequestMapping("/split")
public String split(HttpServletRequest request){
//得到第一页数据
PageInfo info = productInfoService.splitPage(1,PAGE_SIZE);
request.setAttribute("info",info);
return "product";
}
9.4 product.jsp前台接收数据展示,设置分页栏
前台接收初始页数据,通过ajax翻页,ajax传到界面控制层 – ProductInfoAtion中进行分页
<div id="table">
<!--info后台传来的PageInfo页面数据-->
<c:choose>
<!--info.list.size()页面数据大于0-->
<c:when test="${info.list.size()!=0}">
<!--全选按钮-->
<div id="top">
<input type="checkbox" id="all" onclick="allClick()" style="margin-left: 50px"> 全选
<a href="${pageContext.request.contextPath}/admin/addproduct.jsp">
<!--新增商品按钮-->
<input type="button" class="btn btn-warning" id="btn1"
value="新增商品">
</a>
<!--批量删除按钮-->
<input type="button" class="btn btn-warning" id="btn1"
value="批量删除" onclick="deleteBatch()">
</div>
<!--显示分页后的商品-->
<div id="middle">
<table class="table table-bordered table-striped">
<tr>
<th></th>
<th>商品名</th>
<th>商品介绍</th>
<th>定价(元)</th>
<th>商品图片</th>
<th>商品数量</th>
<th>操作</th>
</tr>
<!--从info中获取数据-->
<c:forEach items="${info.list}" var="p">
<tr>
<td valign="center" align="center"><input type="checkbox" name="ck" id="ck" value="${p.pId}" onclick="ckClick()"></td>
<td>${p.pName}</td>
<td>${p.pContent}</td>
<td>${p.pPrice}</td>
<td><img width="55px" height="45px"
src="${pageContext.request.contextPath}/image_big/${p.pImage}"></td>
<td>${p.pNumber}</td>
<td>
<button type="button" class="btn btn-info "
onclick="one(${p.pId},${info.pageNum})">编辑
</button>
<button type="button" class="btn btn-warning" id="mydel"
onclick="del(${p.pId})">删除
</button>
</td>
</tr>
</c:forEach>
</table>
<!--分页栏-->
<div id="bottom">
<div>
<nav aria-label="..." style="text-align:center;">
<ul class="pagination">
<!--利用运用ajax异步翻页 上一页-->
<li>
<a href="javascript:ajaxsplit(${info.prePage})" aria-label="Previous">
<span aria-hidden="true">«</span></a>
<!--利用运用ajax异步翻页 对应页码-->
</li>
<!--当前页加深颜色-->
<c:forEach begin="1" end="${info.pages}" var="i">
<c:if test="${info.pageNum==i}">
<li>
<a href="javascript:ajaxsplit(${i})"
style="background-color: grey">${i}</a>
</li>
</c:if>
<c:if test="${info.pageNum!=i}">
<li>
<a href="javascript:ajaxsplit(${i})">${i}</a>
</li>
</c:if>
</c:forEach>
<!--利用运用ajax异步翻页 下一页-->
<li>
<a href="javascript:ajaxsplit(${info.nextPage})" aria-label="Next">
<span aria-hidden="true">»</span></a>
</li>
<!--总页数-->
<li style=" margin-left:150px;color: #0e90d2;height: 35px; line-height: 35px;">总共 <font style="color:orange;">${info.pages}</font> 页
<!--当前页-->
<c:if test="${info.pageNum!=0}">
当前 <font style="color:orange;">${info.pageNum}</font> 页
</c:if>
<!-- PageInfo的最后一页下一页是0页,手动设置为一页-->
<c:if test="${info.pageNum==0}"> 当前 <font style="color:orange;">1</font> 页
</c:if>
</li>
</ul>
</nav>
</div>
</div>
</div>
</c:when>
<c:otherwise>
<div>
<h2 style="width:1200px; text-align: center;color: orangered;margin-top: 100px">暂时没有符合条件的商品!</h2>
</div>
</c:otherwise>
</c:choose>
</div>
9.5 界面控制层 – ProductInfoAtion中,添加ajaxSplit,对ajax进行解析完成分页
//ajax分页处理
//解析ajax请求,返回客户端
@ResponseBody
@RequestMapping("/ajaxSplit")
public void ajaxSplit(int page, HttpSession session){
//取得当前页page的数据
PageInfo info = productInfoService.splitPage(page,PAGE_SIZE);
System.out.println(info.getList());
session.setAttribute("info",info);
}
本文介绍了在电商后台管理系统中如何使用MD5加密算法保护用户密码,实现了登录功能,包括业务逻辑层和界面控制层的交互。此外,还详细展示了查询所有商品数据、分页展示商品的步骤,使用了MyBatis的PageHelper插件进行分页。整个系统通过AJAX进行页面动态加载,提供友好的用户体验。
273

被折叠的 条评论
为什么被折叠?



