文章目录
- 1.项目初始化:点击运行即访问服务器
- 2.查询:index.jsp点击查询,xxServlet .java在web层,不在service层
- 3.删除:DeteleServlet.java,href="javascript:void(0);"
- 4.添加:主键自增设为null,BeanUtils
- 5.修改:回显+保存
- 6.分页:this.value
- 7.案例:域对象都写在Servlet中,HelloServlet/HelloFilter.java,web.xml
- 8.案例:登录案例最后改进
- 9.多过滤器:先执行小ASCII
1.项目初始化:点击运行即访问服务器
如下request.getParameterMaps()获取所有请求参数存在map里,value是string数组,一个name可对应多个value。面向接口编程就是接口类型的多态,只看左边
,右边怎么实现不管。很多Servlet(真的做事情,实现具体业务,登录的Servlet,注册的Servlet)由Tomcat(管家)即web容器管理。只有cookie是类不是接口
。Servlet接口定标准,Tomcat来实现,也叫支持Servlet规范。
如下web层和浏览器打交道,jsp写起来像前端,放入web文件夹下,jsp就是servlet。dao层(data access object)和数据库打交道,service层处理业务逻辑,web层中接口调用service层中定义的接口。
web层是调用,web层中红字实现类对象
可用反射解耦,service层绿字实现的东西可以放入配置文件中,用反射获取配置文件信息,动态构建一个实现类对象。如mybatis的实现都是写在配置文件里,底层就是反射和动态代理。
drop table if exists t_user;
create table if not exists t_user(
id int(11) primary key auto_increment,
name varchar(50) not null,
sex varchar(50) not null,
age int(11) not null,
address varchar(50) not null,
qq varchar(50) not null,
email varchar(50) not null
);
-- truncate table t_user;
insert into t_user values(null,'张三','男',21,'广东','766335435','zs@qq.com');
insert into t_user values(null,'李四','男',22,'广东','243424242','ls@qq.com');
insert into t_user values(null,'王五','女',23,'广东','474574574','ww@qq.com');
insert into t_user values(null,'赵六','女',28,'广东','77777777', 'zl@qq.com');
insert into t_user values(null,'钱七','女',25,'湖南','412132145','qq@qq.com');
select * from t_user;
如下创建ee工程,dao和web包可以先创建全路径即com…自动分包。
如下先创建lib包,并将下面全拷进去,右击add as library。
如下c3p0…xml(连接池)放入src目录下,Data…java放入utils文件夹下,没有用druid。
如下前端直接粘到web文件夹路径下。
准备好上面5步后,点乌龟运行,自动跳转出浏览器并显示index.jsp内容如下。
点击上面蓝字是超链接跳转如下伪数据即写死在list.jsp页面上。
2.查询:index.jsp点击查询,xxServlet .java在web层,不在service层
如下index.jsp里的a标签不能跳转到list.jsp,因为list.jsp里是假数据,需要经过中间QueryListServlet查询出数据
传给list.jsp显示。不要请求参数,因为sql里不需要参数。sql是核心,查询出封装进bean对象,串联前后作用。因为要传数据,所以用请求转发。序号3其实是后台的web层。
2.1 前端:index.jsp,list.jsp
//index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=basePath%>"/>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>首页</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
</script>
</head>
<!--11111111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body>
<div align="center"> <!--a标签点击默认是get请求,若要请求参数写成 ?n1=v1 -->
<a
href="/QueryListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息
</a>
</div>
</body>
</html>
如下是最后一步写。
//list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>用户信息管理系统</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<style type="text/css">
td, th {
text-align: center;
}
</style>
<script>
function method01(id,name) {
var result = confirm("确认删除"+name+"吗?");
if(result){
location.href = "/DeteleServlet?id=" + id
}
}
</script>
</head>
<!--1111111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body>
<div class="container">
<h3 style="text-align: center">用户信息列表</h3>
<table border="1" class="table table-bordered table-hover">
<tr class="success">
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<%--TODO: status.count看遍历次数--%>
<c:forEach var="user" items="${list}" varStatus="status">
<tr>
<td>${user.id}</td> <%id是不能改的,因为是逻辑删除,并没有真的删了%>
<%-- <td>${status.count}</td>--%> <%这行遍历的次数来表面上改id,要把上行注释了%>
<td>${user.name}</td>
<td>${user.sex}</td>
<td>${user.age}</td>
<td>${user.address}</td>
<td>${user.qq}</td>
<td>${user.email}</td>
<td><a class="btn btn-default btn-sm" href="/QuerySingleServlet?id=${user.id}">修改</a>
<%--<a class="btn btn-default btn-sm" href="/DeteleServlet?id=${user.id}">删除</a>--%>
<%--
上行按钮注释了,没有删除按钮了,正常思路a标签换为button,但不需要,用如下:
href = "javascript:void(0)" 或 javascript:;
a标签的默认点击事件会被禁止,a标签相当于按钮,自己写onclick事件
--%>
<a class="btn btn-default btn-sm" href="javascript:void(0);" onclick="method01('${user.id}','${user.name}')">删除</a>
</td>
</tr>
</c:forEach>
<tr>
<td colspan="8" align="center"><a class="btn btn-primary" href="add.jsp">添加联系人</a></td>
</tr>
</table>
</div>
</body>
</html>
2.2 web:QueryListServlet.java
package com.itheima.manager.web; //放在..manager.web文件夹下
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
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.io.IOException;
import java.util.List;
@WebServlet(urlPatterns = "/QueryListServlet")
public class QueryListServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 接收请求,无请求参数
//2. 业务处理,servlet是面向接口设计的,以面向接口思路设计service
UserService service = new UserServiceImpl(); //接口UserService 变量service = 实现类对象
List<User> list = service.queryAllUser(); //queryAllUser里面不需要传入参数,因为sql不需要
System.out.println(list);
//3. 响应数据(请求转发)
request.setAttribute("list",list);
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
2.3 entity:User.java
package com.itheima.manager.entity;
//字段名 和 数据表字段
public class User {
private Integer id;
private String name;
private String sex;
private Integer age;
private String address;
private String qq;
private String email;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", address='" + address + '\'' +
", qq='" + qq + '\'' +
", email='" + email + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2.4 service:UserService/UserServiceImpl .java
package com.itheima.manager.service;
import com.itheima.manager.entity.User;
import java.util.List;
public interface UserService {
List<User> queryAllUser(); // 查询所有用户数据
void deleteUser(String id); //根据id删除用户
void addUser(User user); //添加用户
User querySingleUser(String id); //查询单个用户
void updateUser(User user); //修改用户信息
List<User> pageQuery(int offset, int count); //分页查询
int findUserSum(); //查询用户总数
}
如下在impl文件夹里。
package com.itheima.manager.service.impl;
import com.itheima.manager.dao.UserDao;
import com.itheima.manager.dao.impl.UserDaoImpl;
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import java.util.List;
public class UserServiceImpl implements UserService {
UserDao dao = new UserDaoImpl(); //左接口,右实现类
@Override
public List<User> queryAllUser() {
List<User> list = dao.findAllUser(); //调用dao层
return list;
}
@Override
public void deleteUser(String id) {
dao.deleteById(id);
}
@Override
public void addUser(User user) {
dao.addUser(user);
}
@Override
public User querySingleUser(String id) {
return dao.findSingleUser(id);
}
@Override
public void updateUser(User user) {
dao.updateUser(user);
}
@Override
public List<User> pageQuery(int offset, int count) {
List<User> list = dao.findUserByPage(offset,count);
return list;
}
@Override
public int findUserSum() {
int count = dao.findUserSum();
return count;
}
}
2.5 dao:UserDao/UserDaoImpl.java
package com.itheima.manager.dao;
import com.itheima.manager.entity.User;
import java.util.List;
public interface UserDao {
List<User> findAllUser();
void deleteById(String id);
void addUser(User user);
User findSingleUser(String id);
void updateUser(User user);
List<User> findUserByPage(int offset, int count);
int findUserSum();
}
如下在impl文件夹里。
package com.itheima.manager.dao.impl;
import com.itheima.manager.dao.UserDao;
import com.itheima.manager.entity.User;
import com.itheima.manager.utils.DataSourceUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.util.List;
public class UserDaoImpl implements UserDao {
JdbcTemplate template = new JdbcTemplate(DataSourceUtils.getDataSource());
@Override
public List<User> findAllUser() {
String sql = "select * from t_user";
List<User> list = template.query(sql, new BeanPropertyRowMapper<>(User.class));
return list;
}
@Override
public void deleteById(String id) {
String sql = "delete from t_user where id = ?";
template.update(sql,id);
}
@Override
public void addUser(User user) {
String sql = "insert into t_user values(null,?,?,?,?,?,?)"; //下面是这行的填充
template.update(sql,
user.getName(),
user.getSex(),
user.getAge(),
user.getAddress(),
user.getQq(),
user.getEmail());
}
@Override
public User findSingleUser(String id) {
String sql = "select * from t_user where id = ?";
User user = null;
try {
user = template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
} catch (DataAccessException e) {
e.printStackTrace(); //查不到数据会异常!!!!!!!!
}
return user;
}
@Override
public void updateUser(User user) {
String sql = "update t_user set name=?,sex=?,age=?,address=?,qq=?,email=? where id = ?";
template.update(sql,
user.getName(),
user.getSex(),
user.getAge(),
user.getAddress(),
user.getQq(),
user.getEmail(),
user.getId() );
}
@Override
public List<User> findUserByPage(int offset, int count) {
String sql = "select * from t_user limit ?,?";
List<User> list = template.query(sql, new BeanPropertyRowMapper<>(User.class), offset, count);
return list;
}
@Override
public int findUserSum() {
String sql = "select count(*) from t_user";
Integer count = template.queryForObject(sql,Integer.class); //单行单列
return count;
}
}
3.删除:DeteleServlet.java,href=“javascript:void(0);”
如下绿色第一行不走,走第二行。QueryListServlet会自动跳转到list.jsp。没有做批量删除即“你已删除…条数据”,访问数据库不需要返回值。
package com.itheima.manager.web;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
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.io.IOException;
@WebServlet(urlPatterns = "/DeteleServlet")
public class DeteleServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id"); //先写=号右边("id").val回车,自动左边
//list.jsp中href="/DeteleServlet?id=${user.id} 的id
UserService service = new UserServiceImpl();
service.deleteUser(id); //不需要返回值
//request.getRequestDispatcher("/QueryListServlet").forward(request,response);
request.getRequestDispatcher("/QueryPageServlet ").forward(request,response);
}
}
4.添加:主键自增设为null,BeanUtils
首先list.jsp页面点击添加联系人按钮,form表单自动拼接name和value:get请求时name和value拼接在url后,post请求拼接好了放请求体里,这都是自动实现,表单提交和文件上传常用post。
4.1 前端:add.jsp
//add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- HTML5文档-->
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<!-- 指定字符集 -->
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器的渲染方式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>添加用户</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
</head>
<!--1111111111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body>
<div class="container text-left">
<center><h3>添加联系人页面</h3></center>
<form action="/AddServlet" method="post" class="form-horizontal"> <!--这行最重要-->
<div class="form-group">
<label class="col-lg-2 control-label" for="name">姓名:</label>
<div class="col-lg-8">
<input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
</div>
<label class="col-lg-2 control-label" id="nameMsg"></label>
</div>
<div class="form-group">
<label class="col-lg-2 control-label">性别:</label>
<div class="col-lg-3">
<input type="radio" name="sex" value="男" checked="checked"/>男
</div>
<div class="col-lg-3">
<input type="radio" name="sex" value="女"/>女
</div>
<label class="col-lg-2 control-label" id="sexMsg"></label>
</div>
<div class="form-group">
<label for="age" class="control-label col-lg-2">年龄:</label>
<div class="col-lg-8">
<input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄"> <!--如果表单是你写的,name属性一定不要忘写-->
</div>
</div>
<div class="form-group">
<label for="jiguan" class="col-lg-2 control-label">籍贯:</label>
<div class="col-lg-8">
<select name="address" class="form-control" id="jiguan">
<option value="广东">广东</option> <!--选项的话,value属性一定要写-->
<option value="广西">广西</option>
<option value="湖南">湖南</option>
</select>
</div>
</div>
<div class="form-group">
<label for="qq" class="control-label col-lg-2">QQ:</label>
<div class="col-lg-8">
<input type="text" class="form-control" id="qq" name="qq" placeholder="请输入QQ号码"/>
</div>
</div>
<div class="form-group">
<label for="email" class="col-lg-2 control-label">Email:</label>
<div class="col-lg-8">
<input type="text" class="form-control" id="email" name="email" placeholder="请输入邮箱地址"/>
</div>
</div>
<div class="form-group" style="text-align: center">
<input class="btn btn-primary" type="submit" value="提交" />
<input class="btn btn-default" type="reset" value="重置" />
<input class="btn btn-default" type="button" value="返回" />
</div>
</form>
</div>
</body>
</html>
4.2 web:AddServlet.java
package com.itheima.manager.web;
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
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.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
@WebServlet(urlPatterns = "/AddServlet")
public class AddServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); //post请求中文乱码
/* //获取请求参数
Integer age = Integer.parseInt(request.getParameter("age")); // ()里返回string类型
String name = request.getParameter("name");
String sex = request.getParameter("sex");
String address = request.getParameter("address");
String qq = request.getParameter("qq");
String email = request.getParameter("email");
//传到service层,参数太多,封装到JavaBean
User user = new User();
user.setAge(age);
user.setName(name);
user.setAddress(address);
user.setQq(qq);
user.setEmail(email);
user.setSex(sex);*/
//如上代码麻烦,想到反射,行映射器:下面用BeanUtils,原理一样。
//11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
/* Map<String, String[]> parameterMap = request.getParameterMap(); //获取所有的请求参数
Set<String> set = parameterMap.keySet();
for (String name : set) { //name单列集合
String[] value = parameterMap.get(name);
System.out.println(name + "->" + Arrays.toString(value));
}*/
Map<String, String[]> parameterMap = request.getParameterMap();
User user = new User();
try {
/*
* void populate(Object bean, Map properties) : map中的数据填充到bean中
* 原理: 反射
* 1. 遍历map: name = 瘪三
* 2. 反射: clazz = user.getClass(); //因为populate里传入了user
* setName = clazz.getMethod("set" + "Name",String.class);
* setName.invoke(user,"瘪三"); //set进user里,如【Mysql5】第3章
*
* BeanUtils:1. 类必须是javaBean(规范必须有set方法)
* 2. 属性名和参数的key必须一致
* */
BeanUtils.populate(user,parameterMap);
}catch (Exception e) {
e.printStackTrace();
}
UserService service = new UserServiceImpl();
service.addUser(user);
request.getRequestDispatcher("/QueryListServlet").forward(request,response); //刷新数据
}
}
如下根据key(单列)获取value。
5.修改:回显+保存
在list.jsp上点击修改,跳到update.jsp页面,update.jsp要先显示需要修改的这行信息。
5.1 前端:update.jsp,value="${}‘’
如下list.jsp修改按钮。
//update.jsp进行回显
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
<base href="<%=basePath%>"/>
<!-- 指定字符集 -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>修改用户</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery-2.1.0.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<!--11111111111111111111111111111111111111111111111111111111111111111111111111111-->
<body>
<div class="container" style="width: 400px;">
<h3 style="text-align: center;">修改联系人</h3>
<form action="/UpdateServlet" method="post">
<%--TODO: 如下行网页上看不出效果,但是也在form里,也会提交--%>
<input type="hidden" name="id" value="${user.id}">
<div class="form-group">
<label for="name">姓名:</label>
<input type="text" class="form-control" id="name" name="name" value="${user.name}"
readonly="readonly" placeholder="请输入姓名" />
</div>
<div class="form-group">
<label>性别:</label>
<%-- 逻辑: ${user.sex == '男' ? "checked" : ""} --%>
<input type="radio" name="sex" value="男" ${user.sex == '男' ? "checked" : ""}/>男
<input type="radio" name="sex" value="女" ${user.sex == '女' ? "checked" : ""} />女
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄" value="${user.age}"/>
</div>
<div class="form-group">
<label for="address">籍贯:</label>
<select name="address" id="address" class="form-control" >
<option value="广东" ${user.address == '广东' ? "selected" : ""} >广东</option>
<option value="广西" ${user.address == '广西' ? "selected" : ""} >广西</option>
<option value="湖南" ${user.address == '湖南' ? "selected" : ""} >湖南</option>
</select>
</div>
<div class="form-group">
<label for="qq">QQ:</label>
<input type="text" id="qq" class="form-control" name="qq" placeholder="请输入QQ号码" value="${user.qq}"/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" id="email" class="form-control" name="email" placeholder="请输入邮箱地址" value="${user.email}"/>
</div>
<div class="form-group" style="text-align: center">
<input class="btn btn-primary" type="submit" value="提交" />
<input class="btn btn-default" type="reset" value="重置" />
<input class="btn btn-default" type="button" value="返回"/>
</div>
</form>
</div>
</body>
</html>
5.2 web:QuerySingleServlet.java
package com.itheima.manager.web;
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
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.io.IOException;
@WebServlet(urlPatterns = "/QuerySingleServlet")
public class QuerySingleServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
UserService service = new UserServiceImpl();
User user = service.querySingleUser(id);
System.out.println("user:" + user);
request.setAttribute("user",user);
request.getRequestDispatcher("/update.jsp").forward(request,response);
}
}
如上点击乌龟启动,点击前端修改按钮,idea打印如下。
5.3 service:UpdateServlet.java
如下id设为hidden,即用户不可见,但服务器知道。
package com.itheima.manager.web;
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
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.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet(urlPatterns = "/UpdateServlet")
public class UpdateServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
Map<String, String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user,map); //是apache里BeanUtils包,不是spring里
} catch (Exception e) {
e.printStackTrace();
}
UserService service = new UserServiceImpl();
service.updateUser(user);
request.getRequestDispatcher("/QueryListServlet").forward(request,response);
}
}
6.分页:this.value
如下count每页都一样,index=offset。
如下方案A不行,因为list.jsp不是同一个,B覆盖A(刷新页面)。背景色在bootstrap中就是class=“active”。如下QueryPageServlet中page是多传递的。
如下按钮个数要动态显示,btncount是按钮数量,/是整除。
如下坑1:选择"每页显示10条数据",刷新后虽然页面数据变了,但是这个选项还是"每页显示5条数据"。
坑2:第一页"每页显示10条数据“,点击跳到第二页,旁边的还是显示"每页显示5条数据"。count=5都要改成count=${count}
还有一个坑:如果删除一条数据,刷新后会显示全部。解决:DeteleServlet.java中改进如下,但不能加参数如?page=…,因为参数是在前端加的,我们现在在DeteleServlet中,参数不能在服务器的A模块(DeteleServlet)到B模块(QuaryPageServlet)。
如下删除后会显示5条数据,还不是保持之前显示条数不变,改进如下是将每页显示数量count存到session中,因为request域对象生命周期太短。
6.1 前端:list.jsp
https://v3.bootcss.com/components/#pagination 找到分页组件,复制到最后面如下,nav就是div占满整个区域。
如下在list.jsp中,QueryPageServlet传来page并放在request中,如下第一行是EL表达式写法,第二行往后是JSTL标签写法,两种方法都一样。下面page==1,2,3,4,5这5个按钮都要删除,因为没有动态显示按钮个数。
//list.jsp,最后的nav分页组件里,前面内容没变
<nav aria-label="Page navigation" class="text-center" >
<ul class="pagination pagination-lg">
<c:if test="${page == 1}">
<li class="disabled"> <!-- 上一页 《按钮 disabled变灰色-->
<a href="javascript:;" aria-label="Previous"> <!--点击事件禁了-->
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
//没有上一块内容,当page<=1时,《按钮 就被隐藏了
<c:if test="${page > 1}"> <!--page不能为0,offset为负索引了-->
<li>
<a href="/QueryPageServlet?page=${page-1}&count=${count}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
<!--11111111111111111111111111111111111111111111111上面两块内容都为 《 按钮 显示-->
<%--TODO:
1. 问题: 我们发现按钮数量太多了
2. 解决: 参照百度,总共10个按钮, (前5后4)
3. 逻辑
1. pageCount <= 10
1. begin = 1
2. end = pageCount
2. pageCount > 10
1. begin = page(当前页) - 5
2. end = page + 4
3. 越界
1. begin < 1
1. begin = 1
2. end = 10
2. end > pageCount
1. begin = pageCount-9
2. end = pageCount
--%>
<c:forEach var="i" begin="1" end="${btnCount}"> <!--按钮个数动态显示-->
<li <c:if test="${page == i}">class='active' </c:if> ><a href="/QueryPageServlet?page=${i}&count=${count}">${i}</a></li>
</c:forEach>
<!--111111111111111111111111111111111111111111111111111下面内容是 》按钮 -->
<c:if test="${page < count}"> <!--每页显示数量动态化-->
<li>
<a href="/QueryPageServlet?page=${page+1}&count=${count}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
<!--111111111111111111111111111111111111111111111111111111111111111-->
<li>
<select onchange="method02(this.value)" class="btn-lg btn-success"> <!--调下面-->
<option value="5" ${count == 5? "selected" : ""}>每页显示5条数据</option>
<option value="10" ${count == 10? "selected" : ""} >每页显示10条数据</option>
<option value="15" ${count == 15? "selected" : ""} >每页显示15条数据</option>
</select>
</li>
</ul>
</nav>
</div>
</body>
</html>
<script>
function method02(value) {
location.href = "/QueryPageServlet?page=1&count=" + value
}
</script>
//index.jsp 前面不变,这里修改原因是一进来只要显示5页就行,其他增删改也要改一下。
<div align="center">
<%--<a
href="/QueryListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息
</a>--%>
<a
href="/QueryPageServlet?page=1&count=5" style="text-decoration:none;font-size:33px">查询所有用户信息
</a>
</div>
</body>
</html>
6.2 web:QueryPageServlet.java
package com.itheima.manager.web;
import com.itheima.manager.entity.User;
import com.itheima.manager.service.UserService;
import com.itheima.manager.service.impl.UserServiceImpl;
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.io.IOException;
import java.util.List;
@WebServlet(urlPatterns = "/QueryPageServlet")
public class QueryPageServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int page = 1;
int count = 5;
String pageStr = request.getParameter("page"); //传参就用你传来的参数,不传参默认第一页,每页显示5条
String countStr = request.getParameter("count");
if(pageStr != null && countStr != null){
page = Integer.parseInt(pageStr); //前端传来字符串,因为要计算,所以转为int
count = Integer.parseInt(countStr);
}
int offset = (page-1) * count;
//11111111111111111111111111111111111111111111111111111111111111111111
UserService service = new UserServiceImpl();
List<User> list = service.pageQuery(offset,count); //查询用户数据,不需要page了,用到上面得到的offset
int sum = service.findUserSum();
int btnCount = sum%count==0? sum/count : sum/count+1;
request.setAttribute("list",list); //name一定要写list,这样前端list.jsp显示数据就不用再写
request.setAttribute("page",page); //按钮点击显示效果
request.setAttribute("btnCount",btnCount); //按钮个数
request.setAttribute("count",count); //每页显示的数量
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
}
7.案例:域对象都写在Servlet中,HelloServlet/HelloFilter.java,web.xml
组件像
java中类和接口,域对象像
前面类和接口的方法和属性。Listener在spring中,Filter和Servlet是平级关系,Filter不像request和response被包含在Servlet的service方法里。
New-Project-Java Enterprise-用模板,src文件夹里new-Servlet。
package com.itheima01.hello;
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.io.IOException;
@WebServlet(urlPatterns = "/HelloServlet")
public class HelloServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet被访问了");
}
}
package com.itheima01.hello;
import javax.servlet.*;
import java.io.IOException;
public class HelloFilter implements Filter { //javax.servlet包下的Filter
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器被访问了: 请求进来了"); //上行doFilter方法相当于service方法
filterChain.doFilter(servletRequest,servletResponse); //将请求继续往后发送(允许通行)
}
@Override
public void destroy() {
}
}
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>HelloFilter01</filter-name>
<filter-class>com.itheima01.hello.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloFilter01</filter-name>
<url-pattern>/HelloServlet</url-pattern> <!-- 要拦截的地址,url中 -->
</filter-mapping>
<filter>
<filter-name>LifeFilter</filter-name>
<filter-class>com.itheima02.life.LifeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LifeFilter</filter-name>
<url-pattern>/LifeServlet</url-pattern>
</filter-mapping>
</web-app>
7.1 Filter生命周期:LifeServlet/LifeFilter.java,注解是四大类型之一也要导包
package com.itheima02.life;
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.io.IOException;
@WebServlet(urlPatterns = "/LifeServlet")
public class LifeServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("servlet init");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet service");
}
@Override
public void destroy() {
System.out.println("servlet destroy");
}
}
package com.itheima02.life;
import javax.servlet.*;
import java.io.IOException;
public class LifeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter doFilter before");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Filter doFilter after");
}
@Override
public void destroy() {
System.out.println("Filter destroy");
}
}
还没访问,服务器点乌龟运行时即服务器开启时,idea就打印如下。
如下访问LifeServlet会转到com.itheima02.life.LifeFilter,web.xml中。
如下servlet init只打印一次,servlet是职员。
如下点击红色方块关闭服务器。filter生命周期包裹着servlet。
上面New-Serlvet都是有模板注解,New-Filter也可以设置模板,用注解替换web.xml。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebFilter(urlPatterns = "/")
public class ${Class_Name} implements javax.servlet.Filter {
public void init(javax.servlet.FilterConfig config) throws javax.servlet.ServletException {
}
public void doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse resp, javax.servlet.FilterChain chain) throws javax.servlet.ServletException, java.io.IOException {
chain.doFilter(req, resp);
}
public void destroy() {
}
}
上面案例LifeServlet有@WebServlet(urlPatterns = “/LifeServlet”),又在web.xml有映射,相当于web.xml同时存在filter和servlet,当输入一个url后先执行filter。如下是需要拦截的url。
8.案例:登录案例最后改进
//index.jsp
<%-- Created by IntelliJ IDEA. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title></title>
</head>
<body>
<form action="/Servlet01" method="post">
<input type="text" name="msg" value="这是信息1"> <br>
<input type="submit">
</form>
<hr>
<form action="/Servlet02" method="post">
<input type="text" name="msg" value="这是信息2"> <br>
<input type="submit">
</form>
<hr>
<a href="/AServlet">/AServlet</a> <br>
<a href="/BServlet">/BServlet</a> <br>
</body>
</html>
package com.itheima04.post;
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.io.IOException;
@WebServlet(urlPatterns = "/Servlet01")
public class Servlet01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String msg = request.getParameter("msg");
System.out.println("servlet01:" + msg);
}
}
package com.itheima04.post;
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.io.IOException;
@WebServlet(urlPatterns = "/Servlet02")
public class Servlet02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String msg = request.getParameter("msg");
System.out.println("servlet02:" + msg);
}
}
package com.itheima04.post;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class PostFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req; //基于http协议的请求
String method = request.getMethod();
if("post".equalsIgnoreCase(method)){
request.setCharacterEncoding("utf-8"); //请求
}
//如上全是request
resp.setContentType("text/html;charset=utf-8"); //响应体中文乱码
chain.doFilter(req, resp); //引用数据类型,req和request指向同一个地址
}
public void destroy() {
}
}
如下c:if这段代码很多页面都需要。${}是EL表达式简化从域对象中取值操作。
如下是登陆案例的权限过滤,如上c:if里可以注释了。
package com.itheima.login.web;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
//@WebFilter(urlPatterns = "/success.jsp") //urlPatterns是一个string数组,String[] urlPatterns() default {};
@WebFilter(urlPatterns = {"/success.jsp","/buycar.jsp","*.do"}) //多个,{}不能省略
public class PrivilegeFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
String name = (String) request.getSession().getAttribute("name");
if(name == null){
request.setAttribute("errorMsg","请先登录!!!");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
//如上都是request
chain.doFilter(req, resp);
}
public void destroy() {
}
}
9.多过滤器:先执行小ASCII
如下注解是@WebFilter。
package com.itheima05.multi;
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.io.IOException;
@WebServlet(urlPatterns = "/AServlet")
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("AServlet");
}
}
package com.itheima05.multi;
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.io.IOException;
@WebServlet(urlPatterns = "/BServlet")
public class BServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("BServlet");
}
}
下面是中间过滤器:AFilter,BFilter,CFilter,注意@WebFilter。
package com.itheima05.multi;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = {"/AServlet","/BServlet"})
public class AFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws ServletException, IOException {
System.out.println("中文乱码");
chain.doFilter(req, resp);
}
public void destroy() {
}
}
package com.itheima05.multi;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/BServlet")
public class BFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("登录权限");
chain.doFilter(req, resp);
}
public void destroy() {
}
}
package com.itheima05.multi;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/AServlet")
public class CFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("非法字符");
chain.doFilter(req, resp);
}
public void destroy() {
}
}
如下在index.jsp中。
如下点击AServlet。
如下点击BServlet。