该项目要求【联系人管理系统】
用户登录时需使用验证码防止恶意请求数据库,
个人首页需展示个人信息或进入联系人管理,
联系人管理页需在基础的增、删、改、查上进一步实现分页查、模糊查、批量删功能。
重点一 分页查
分页查,我们需要获取一些数据:联系人总记录数 totalCount 、总页码 totalPage 、每页的数据集合 List<T> 、当前页码 currentPage 、每页显示的记录数 rows 。
我们可以将这五种数据当成属性放在实体类 Page<T>.java 中,在servlet中获取数据后放在request域交由前端展示。
参考源码:
public class Page<T> {
private int totalCount;
private int totalPage ;
private List<T> list ;
private int currentPage ;
private int rows;
}
Map<String, String[]> condition = request.getParameterMap();
String currentPage = request.getParameter("currentPage");
String rows = request.getParameter("rows");
if (currentPage==null || currentPage.equals("")){
currentPage = "1";
}
if (rows==null || rows.equals("")){
rows = "5";
}
MainService service = new MainService();
Page<People> allPeopleByP = service.getAllPeopleByP(currentPage, rows, condition);
request.setAttribute("pb", allPeopleByP);
request.setAttribute("condition", condition);
request.getRequestDispatcher("/list.jsp").forward(request, response);
public class MainService {
private PeopleDao peopleDao = new PeopleDao();
public Page<People> getAllPeopleByP(String _currentPage, String _rows, Map<String, String[]> condition){
Page<People> peoplePage = new Page<People>();
int currentPage = Integer.parseInt(_currentPage);
int rows = Integer.parseInt(_rows);
if (currentPage <= 0){
currentPage = 1;
}
int totalCount = peopleDao.getCountByPage(condition);
int start = (currentPage-1) * rows;
List<People> allByPage = peopleDao.getAllByPage(start, rows, condition);
int totalPage = (totalCount % rows) == 0 ? totalCount/rows : (totalCount/rows) + 1;
peoplePage.setCurrentPage(currentPage);
peoplePage.setRows(rows);
peoplePage.setTotalCount(totalCount);
peoplePage.setList(allByPage);
peoplePage.setTotalPage(totalPage);
return peoplePage;
}
}
public class PeopleDao{
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
public int getCountByPage(Map<String, String[]> condition) {
String sql = "select count(*) from people where 1=1";
StringBuilder sbu = new StringBuilder(sql);
Set<String> keySet = condition.keySet();
List<Object> params = new ArrayList<Object>();
for (String key : keySet){
if ("currentPage".equals(key) || "rows".equals(key)){
continue;
}
String value = condition.get(key)[0];
if (value!=null && !value.equals("")){
sbu.append(" and ").append(key).append(" like ? ");
params.add("%" + value + "%");
}
}
sql = sbu.toString();
return template.queryForObject(sql, Integer.class, params.toArray());
}
public List<People> getAllByPage(int start, int rows, Map<String, String[]> condition) {
String sql = "select * from people where 1=1";
StringBuilder sbu = new StringBuilder(sql);
Set<String> keySet = condition.keySet();
List<Object> params = new ArrayList<Object>();
for (String key : keySet){
if ("currentPage".equals(key) || "rows".equals(key)){
continue;
}
String value = condition.get(key)[0];
if (value!=null && !value.equals("")){
sbu.append(" and ").append(key).append(" like ? ");
params.add("%" + value + "%");
}
}
sbu.append(" limit ?,? ");
params.add(start);
params.add(rows);
sql = sbu.toString();
return template.query(sql, new BeanPropertyRowMapper<People>(People.class), params.toArray());
}
}
重点二 模糊查
模糊查主要在于sql语句的编写,在数据库中我们是这样写的:select * from 表名 where 字段名 like '%输入值%' 。
但在java代码中,我们需要注意 like 关键字的后面,' 和 % 两者的位置,错误经常在这两个地方:String sql = "select * from 表名 where 字段名 like '%?%'"; 。
在 输入值 前后都加 % ,是左右都模糊,只要该字段下的值含有该 输入值 ,那么就返回这些结果。
在 输入值 左边添加 % ,是模糊该字段下的值的左边部分,只对比查找最右边是否有该 输入值 。
复习一下,sql语句中的like关键字使用语法:
select * from student where stuname like '王%';
select * from student where stuname like '_一%';
重点三 批量删
说到批量处理,我们一般都是对单个数据进行的增删改,所以在批量删除这一点上,我们只需要想办法获取到批量的数据集合(数据一般是表字段编号id),遍历这个集合,依次执行删除操作即可。
在删除数据时,我们一般使用该条数据的唯一编号id作为条件进行删除,那么我们只需要从前端获取批量的数据id就可以了。
前端我们只需要给复选框添加 name 属性和 value 属性即可:<input type="checkbox" name="uid" value="${user.id}"> ,当然不要忘记在复选框外面添加 <form> 标签。
在servlet中获取同一个 name 属性的标签值,使用的是 request.getParameterValues("uid") 方法,它将返回一个String数组 String[] ,我们遍历数组得到id并对该id下的数据进行删除,遍历完成即批量删除完成。
重点四 登录页的动态验证码
验证码在这里是用的 <img> 标签显示:
<label for="verifycode">验证码:</label>
<input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/>
<a href="javascript:refreshCode()"><img src="${pageContext.request.contextPath}/getVCode" title="看不清点击刷新" id="vcode"/></a>
其中的js函数:
function refreshCode(){
document.getElementById("vcode").src = "${pageContext.request.contextPath}/getVCode?time" + new Date().getTime();
}
在servlet中生成动态验证码:
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
@WebServlet("/getVCode")
public class GetVCode extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
int width = 80;
int height = 30;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0, width,height);
String checkCode = getCheckCode();
System.out.println("生成的验证码是:" + checkCode);
request.getSession().setAttribute("CHECKCODE_SERVER", checkCode);
g.setColor(Color.LIGHT_GRAY);
g.setFont(new Font("黑体",Font.BOLD,24));
g.drawString(checkCode,15,25);
ImageIO.write(image,"PNG",response.getOutputStream());
}
private String getCheckCode() {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghigklmnopqrstuvwxyz";
int size = base.length();
Random r = new Random();
StringBuffer sb = new StringBuffer();
for(int i=1;i<=4;i++){
int index = r.nextInt(size);
char c = base.charAt(index);
sb.append(c);
}
return sb.toString();
}
}
不重点五 增、删、改
JavaWeb项目的增删改,从获取关键数据,到调用逻辑代码,实现数据交互,都无太多需要注意的地方,这里只写两点。
一是复习经常到的增删改的sql语句:
insert into 表名 values(值, ……);
insert into 表名 set 列名=值, 列名=值, ……;
delete from 表名 where 筛选条件;
delete from 表名;
truncate table 表名;
update 表名 set 字段=新值, 字段=新值, …… where 筛选条件;
二是前端传参到后端的几种方法:
-
使用 <form> 表单可根据文本框的 name 属性传参它的 value 值。且使用 method="post" 提交表单,可使参数值不显示在地址栏。 -
使用 <a> 标签,在 href 属性后使用 ? 和 && 确定传参的键值和数量,如:<a href="home.jsp?myId=${requestScope.userId}&&myTel=${requestScope.userTel}">查看个人信息</a> ,但a标签的传值是get方法,地址栏中会显示参数的所有信息。 -
如果想用 <a> 标签传值,又不想参数显示在地址栏,那么可以通过js生成 <form> 表单进行post方法提交: <a href="javascript:nextHref('home.jsp',{'myId':'${requestScope.userId}'},{'myTel':'${requestScope.userTel}'});">查看个人信息</a>
function nextHref(to, p, p2) {
var myForm = document.createElement("form");
myForm.method = "post";
myForm.action = to;
for (var i in p){
var myInput = document.createElement("input");
myInput.setAttribute("name", i);
myInput.setAttribute("value", p[i]);
myForm.appendChild(myInput);
}
for (var j in p2){
var myInput = document.createElement("input");
myInput.setAttribute("name", j);
myInput.setAttribute("value", p2[j]);
myForm.appendChild(myInput);
}
document.body.appendChild(myForm);
myForm.submit();
document.body.removeChild(myForm);
}
|