@Override
public List findAll(){
// 调用Dao完成查询
return dao.findAll();
}
}
该方法调用了dao层 UserDaoImpl.java 中操作数据库查询的findAll()方法:
public class UserDaoImpl implements UserDao{
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public List findAll(){
// 使用JDBC操作数据库
String sql = “select * from user”;
List users = template.query(sql, new BeanPropertyRowMapper(User.class));
return users;
}
}
操作数据库使用了Spring框架对JDBC的封装——JDBCTemplate对象template,来简化java操作数据库的开发,由于这里要执行的是查询操作,所以只需定义查询所有用户的sql语句并调用template的query方法即可。创建template时需要传入一个连接池类DataSource的对象,可以使用阿里巴巴druid数据库连接池技术来封装JDBC的工具类,该工具类封装了加载配置文件,初始化连接池对象,获取连接池对象以及获取连接Connection对象的功能,具体实现如下:
package util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
- JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {
private static DataSource ds ;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
//使用ClassLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream(“druid.properties”);
pro.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
- 获取连接池对象
*/
public static DataSource getDataSource(){
return ds;
}
/**
- 获取连接Connection对象
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
相应的druid配置文件为:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///day17
username=root
password=root
初始化连接数量
initialSize=5
最大连接数
maxActive=10
最大等待时间
maxWait=3000
3 添加联系人功能
添加联系人的设计逻辑如下图所示:
点击添加联系人的按钮之后,跳转至后台 AddUserServlet.java 程序,完成五个步骤:
-
设置编码为"utf-8"防止出现中文乱码
-
获取添加的新的联系人的所有数据
-
根据获取的数据封装联系人为User类的对象
-
调用service层的add()方法完成添加
-
跳转回userListServlet再次查询所有联系人并展示
基于以上步骤,AddUserServlet.java 的主要代码如下:
@WebServlet(“/addUserServlet”)
public class AddUserServlet extends HttpServlet {
protected void doPost(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);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// 调用service保存
UserService service = new UserServiceImpl();
service.addUser(user);
// 跳转到userListServlet
response.sendRedirect(request.getContextPath() + “/userListServlet”);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
其中使用了Spring的BeanUtils.populate()方法简化了User类的封装,只需传入初始化的空User类对象user和保存有该user对象的所有属性的map,map又可以由request.getParameterMap()方法快速获取。
添加联系人界面 add.jsp 需要为表单设置action属性,将其指向 addUserServlet
service层 UserServiceImpl.java 类定义add(User user)方法以供AddUserServlet.java 调用:
@Override
public void addUser(User user){
dao.add(user);
}
该方法调用了dao层 UserDaoImpl.java 中添加数据库数据的add(User user)方法:
为了保证动态操作数据库,定义sql语句时将要写数据的地方用 ? 占位,使用template的update()方法时再动态传入数据
@Override
public void add(User user){
String sql = “insert into user values(null,?,?,?,?,?,?,null,null)”;
template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getAddress(), user.getQq(), user.getEmail());
}
4 删除用户功能
删除联系人的设计逻辑如下图所示:
点击删除按钮之后,跳转到后台 DelUserServlet.java 程序,完成三个步骤:
-
获取待删除用户的id
-
调用service层的deleteUser(String id)方法完成删除
-
跳转回userListServlet再次查询所有联系人并展示
基于以上步骤,DelUserServlet.java 的主要代码如下:
@WebServlet(“/delUserServlet”)
public class delUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取id
String id = request.getParameter(“id”);
// 调用service删除
UserService service = new UserServiceImpl();
service.deleteUser(id);
// 跳转到查询所有servlet
response.sendRedirect(request.getContextPath() + “/userListServlet”);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
service层 UserServiceImpl.java 类定义deleteUser(String id)方法以供DelUserServlet.java 调用:
由于数据库存储的id是int型数据,所以在这里简单做一个数据类型转换,并利用java自动拆包特点
@Override
public void deleteUser(String id) {
dao.delete(Integer.parseInt(id));
}
该方法调用了dao层 UserDaoImpl.java 中删除数据库数据的delete(int id)方法:
@Override
public void delete(int id) {
String sql = “delete from user where id = ?”;
template.update(sql, id);
}
修改页面list.jsp,删除操作最好由js控制弹出一个确认提示框再进行相关操作,所以先对按钮增加一个js判断,由于user的id属性只能在foreach循环中获取(局部变量),所以这里js函数要传一个参数:
相应的js代码为,跳转链接要把id也传过去:
function deleteUser(id) {
// 用户确定操作提示
if (confirm(“您确定要删除吗”)){
location.href=“${pageContext.request.contextPath}/delUserServlet?id=”+id;
}
}
5 修改联系人功能
修改联系人的设计逻辑如下图所示:
修改逻辑要分为两个部分进行:回显、修改
5.1 回显部分
点击修改按钮之后,首先进行回显部分的操作,将选中的用户信息事先展示到页面的各个输入框内,跳转到后台 FindUserServlet.java 程序,完成四个步骤:
-
获取待修改用户的id
-
调用service层的findUserById(String id)方法,查询用户信息
-
将User类对象存到request域内
-
转发至修改页面update.jsp并作展示
基于以上步骤,FindUserServlet.java 的主要代码如下:
@WebServlet(“/findUserServlet”)
public class FindUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取id
String id = request.getParameter(“id”);
// 调用service查询
UserService service = new UserServiceImpl();
User user = service.findUserById(id);
// 将user存入request
request.setAttribute(“user”, user);
// 转发到update.jsp
request.getRequestDispatcher(“/update.jsp”).forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
service层 UserServiceImpl.java 类定义findUserById(String id)方法以供FindUserServlet.java 调用:
@Override
public User findUserById(String id) {
return dao.findById(Integer.parseInt(id));
}
该方法调用了dao层 UserDaoImpl.java 中查询数据库数据的findById(int id)方法:
由于要返回一个User类对象,所以要使用template.queryForObject()方法
@Override
public User findById(int id) {
String sql = “select * from user where id = ?”;
return template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
}
获取到待修改的user后,将其各个原本的属性值回显至update.jsp页面的文本输入框内,每一个input输入框的value属性要用el语法设置为待修改用户的属性${user.属性名},如:
5.2 修改部分
对于修改信息界面,需要添加一个隐藏域,用于存储id,后续servlet操作需要根据id来进行
点击提交按钮以后,跳转到后台 UpdateUserServlet.java 程序,完成四个步骤:
-
设置编码为 “utf-8”,防止出现中文乱码问题
-
获取修改页面提交的表单数据集合map
-
使用获得的数据封装User类对象
-
调用service层的updateUser(User user)方法完成修改
-
跳转回userListServlet再次查询所有联系人并展示
基于以上步骤,UpdateUserServlet.java 的主要代码如下:
@WebServlet(“/updateUserServlet”)
public class UpdateUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding(“utf-8”);
// 获取map
Map<String, String[]> map = request.getParameterMap();
// 封装对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// 调用service
UserService service = new UserServiceImpl();
service.updateUser(user);
// 跳转到查询所有Servlet
response.sendRedirect(request.getContextPath()+“/userListServlet”);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
service层 UserServiceImpl.java 类定义updateUser(User user)方法以供UpdateUserServlet.java 调用:
@Override
public void updateUser(User user) {
dao.update(user);
}
该方法调用了dao层 UserDaoImpl.java 中修改数据库数据的update(User user)方法:
修改数据库的sql逻辑和添加联系人的类似
@Override
public void update(User user) {
String sql = “update user set name=?, gender=?, age=?, address=?, qq=?, email=? where id=?”;
template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getAddress(), user.getQq(), user.getEmail(), user.getId());
}
6 删除选中的联系人功能
删除联系人的设计逻辑如下图所示:
点击删除选中按钮之后,跳转到后台 DelSelectServlet.java 程序,完成三个步骤:
-
获取所有选中的用户的id
-
调用service层的deleteUsers(String[] ids)方法,删除所有用户
-
跳转回userListServlet再次查询所有联系人并展示
基于以上步骤,DelSelectServlet.java 的主要代码如下:
@WebServlet(“/delSelectedServlet”)
public class DelSelectedServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取所有id
String[] ids = request.getParameterValues(“uid”);
// 调用service删除
UserService service = new UserServiceImpl();
service.delSelectedUser(ids);
// 跳转查询所有的servlet
response.sendRedirect(request.getContextPath() + “/userListServlet”);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
service层 UserServiceImpl.java 类定义delSelectedUser(String[] ids)方法以供DelSelectServlet.java 调用:
@Override
public void delSelectedUser(String[] ids) {
if (ids != null && ids.length > 0){
for (String id : ids) {
// 调用dao删除
dao.delete(Integer.parseInt(id));
}
}
}
由于之前已经实现过dao层删除单个用户的操作,所以这里只需循环遍历id数组,将每一个id对应的单个用户都删除即可。
修改用户页面list.jsp,将用户展示的table用表单form包裹起来,这样就可以提交所有选中的行了。checkbox的value值要设置为用户的id。
这样提交时才能把选中的用户的id都提交过去
<c:forEach items=“${users}” var=“user” varStatus=“s”>
${s.count} ${user.name} ${user.gender} ${user.age} ${user.address} ${user.qq} ${user.email} 修改</c:forEach>
添加script代码,实现手动确认功能
window.onload = function () {
// 给删除选中按钮添加单击事件
document.getElementById(“delSelected”).onclick = function () {
// 表单提交
if (confirm(“您确定要删除选中条目吗”)){
// 判断是否有选中的条目
var flag = false;
var cbs = document.getElementsByName(“uid”);
for (var i = 0; i < cbs.length; i ++){
if(cbs[i].checked){
flag = true;
break;
}
}
if (flag){
document.getElementById(“form”).submit();
}
}
}
}
接下来设置第一行的checkbox可以实现全选全不选,逻辑上只用保证所有的所有checkbox的checked属性与第一行相同即可
window.onload = function () {
// 第一行checkbox实现全选
document.getElementById(“firstCb”).onclick = function () {
var cbs = document.getElementsByName(“uid”);
for (var i = 0; i < cbs.length; i ++){
// 设置所有checkbox的状态与第一行相同
cbs[i].checked = this.checked;
}
}
}
7 分页查询功能
由于要实现分页查询,需要总记录数、总页码数、每一页的数据集合、当前的页码以及每一页显示的条目数等数据,所以最好用一个类的对象来保存这些数据,如下图所示
于是设计PageBean类来保存这些数据,相应的生成getter、setter及toString方法
package domin;
import java.util.List;
/**
- 分页对象
*/
public class PageBean {
private int totalCount; // 总记录数
private int totalPage; // 总页码
private List list; // 每页数据
private int currentPage;// 当前页码
private int rows; // 每页显示记录数
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
@Override
public String toString() {
return “PageBean{” +
“totalCount=” + totalCount +
“, totalPage=” + totalPage +
“, list=” + list +
“, currentPage=” + currentPage +
“, rows=” + rows +
‘}’;
}
}
实际上,服务器端只需接收到页面传过来的当前页码及每页显示的条目数即可得到所有的PageBean类的属性,具体如上图所示
实现分页查询并显示的设计如下图所示:
查询用户信息时,会自动调用后台 FindUserByPageServlet.java 程序,完成以下四个步骤:
-
接受请求参数 currentPage, rows
-
调用service层的 findUserByPage(currentPage, rows) 方法获取分页查询结果(PageBean类的对象)
-
将该对象存入request域中
-
转发至页面list.jsp展示
基于以上步骤,FindUserByPageServlet.java 的主要代码如下:
@WebServlet(“/findUserByPageServlet”)
public class FindUserByPageServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取参数
String currentPage = request.getParameter(“currentPage”);
String rows = request.getParameter(“rows”);
if (currentPage == null || “”.equals(currentPage)){
currentPage = “1”;
}
if (rows == null || “”.equals(rows)){
rows = “5”;
}
// 调用service查询
UserService service = new UserServiceImpl();
PageBean pb= service.findUserByPage(currentPage, rows);
// 将PageBean存入request
request.setAttribute(“pb”, pb);
// 转发到list.jsp
request.getRequestDispatcher(“/list.jsp”).forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
service层 UserServiceImpl.java 类定义findUserByPage(String _currentPage, String _rows)方法以供FindUserByPageServlet.java 调用,在这里要根据传入的当前页面和每页显示条目数来计算出其他所需要的值,具体分为以下七个步骤:
-
创建PageBean对象pb
-
设置pb的currentPage和rows属性
-
调用dao层的finTotalCount()方法查询总记录数totalCount
-
计算sql查询的起始数据位置 start = (currentPage - 1) * rows
-
调用dao层的findByPage(int start, int rows)方法查询用户集合
-
计算总页码,totalCount % rows 并向上取整
-
返回pb
基于以上步骤,UserServiceImpl.java 中添加方法代码如下:
@Override
public PageBean findUserByPage(String _currentPage, String _rows) {
int currentPage = Integer.parseInt(_currentPage);
int rows = Integer.parseInt(_rows);
// 创建PageBean对象
PageBean pb = new PageBean();
// 查询总记录数
int totalCount = dao.finTotalCount();
pb.setTotalCount(totalCount);
// 计算总页码
int totalPage = (totalCount % rows) == 0 ? (totalCount/rows) : (totalCount/rows) + 1;
pb.setTotalPage(totalPage);
// 设置参数
if (currentPage > totalPage)
currentPage = totalPage;
if (currentPage <= 0)
currentPage = 1;
pb.setCurrentPage(currentPage);
pb.setRows(rows);
// 调用dao查询List集合
int start = (currentPage - 1) * rows;
List list = dao.findByPage(start, rows);
pb.setList(list);
return pb;
}
该方法调用了dao层 UserDaoImpl.java 中查询数据库总数据数的finTotalCount()方法:
@Override
public int finTotalCount() {
String sql = “select count(*) from user”;
return template.queryForObject(sql, Integer.class);
}
还调用了dao层按照页面可展示用户数查询的findByPage(int start, int rows)方法:
@Override
public List findByPage(int start, int rows) {
String sql = “select * from user limit ? , ?”;
return template.query(sql, new BeanPropertyRowMapper<>(User.class), start, rows);
}
改造显示页面list.jsp
首先将循环取出每一条用户数据按行展示的jstl语句中foreach的items参数修改
items=“${pb.list}”
动态显示总记录数
共 p b . t o t a l C o u n t 条记录,共 {pb.totalCount}条记录,共 pb.totalCount条记录,共{pb.totalPage}页
动态修改导航栏个数,高亮当前页面,并绑定servlet
<c:forEach begin=“1” end=“${pb.totalPage}” var=“i”>
<c:if test=“${pb.currentPage == i}”>
- ${i}
</c:if>
<c:if test=“${pb.currentPage != i}”>
- ${i}
</c:if>
</c:forEach>
添加导航栏向左符号《 和 向右符号 》功能
<c:if test=“${pb.currentPage == 1}”>
</c:if>
<c:if test=“${pb.currentPage != 1}”>
</c:if>
«
<c:if test=“${pb.currentPage == pb.totalPage}”>
</c:if>
<c:if test=“${pb.currentPage != pb.totalPage}”>
</c:if>
»
完成分页查询后将 UpdateUserServlet.java 和 AddUserServlet.java 和 DelSelectedServlet.java 和delUserServlet.java 的重定向目标换成分页查询的servlet
8 复杂条件查询
由于根据条件查询所得的结果也要分页展示,所以仍需借助PageBean对象,如下图所示:
当用户点击查询按钮时,会传过来一个表单,这里表单一共有姓名、地址、email三个属性,但有可能用户只输入其中的几个,所以sql语句要动态的生成,如上图所示,如果用户输入了姓名和地址,那么查询总的条目数的模糊查询sql语句变为:
select count(*) from user where name like ? and address like ?;
同理,分页查询的sql语句为:
select * from user where name like ? and address like ? limit ?, ?;
改造list.jsp
给查询部分的表单添加action和method,action传入分页的servlet
注意表单中的input标签必须加上name属性,否则数据到不了服务器。
为了查询条件的回显,将查询输入框的value进行设置
分页导航在点击左右按钮或数字按钮是,要把可能存在的条件查询的条件name=KaTeX parse error: Undefined control sequence: \[ at position 16: {condition.name\̲[̲0\]}&address={condition.address[0]}&email=${condition.eamil[0]} 也加上
- ${i}
改造FindUserByPageServlet.java
添加获取条件查询的参数condition,condition如果为空,则表示默认查询,没有设置查询条件
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取参数
String currentPage = request.getParameter(“currentPage”);
String rows = request.getParameter(“rows”);
if (currentPage == null || “”.equals(currentPage)){
currentPage = “1”;
}
if (rows == null || “”.equals(rows)){
rows = “5”;
}
// 获取条件查询的参数
Map<String, String[]> condition = request.getParameterMap();
// 调用service查询
UserService service = new UserServiceImpl();
PageBean pb= service.findUserByPage(currentPage, rows, condition);
// 将PageBean存入request
request.setAttribute(“pb”, pb);
request.setAttribute(“condition”, condition); // 储存查询条件,用于回显
// 转发到list.jsp
request.getRequestDispatcher(“/list.jsp”).forward(request, response);
}
改造UserServiceImpl.java
其中的findUserByPage方法添加一个参数map,表示条件查询的条件,在方法里面调用UserDaoImpl类的操作数据库方法时,也多传入一个map参数
@Override
public PageBean findUserByPage(String _currentPage, String _rows, Map<String, String[]> condition) {
int currentPage = Integer.parseInt(_currentPage);
int rows = Integer.parseInt(_rows);
// 创建PageBean对象
PageBean pb = new PageBean();
// 查询总记录数
int totalCount = dao.finTotalCount(condition);
pb.setTotalCount(totalCount);
// 计算总页码
int totalPage = (totalCount % rows) == 0 ? (totalCount/rows) : (totalCount/rows) + 1;
pb.setTotalPage(totalPage);
// 设置参数
if (currentPage <= 0)
currentPage = 1;
if (currentPage > totalPage)
currentPage = totalPage;
pb.setCurrentPage(currentPage);
pb.setRows(rows);
// 调用dao查询List集合
int start = (currentPage - 1) * rows;
List list = dao.findByPage(start, rows, condition);
pb.setList(list);
return pb;
}
改造UserDaoImpl.java
动态生成sql语句,注意要排除分页条件参数 “currentPage” 和 “rows”
@Override
public int finTotalCount(Map<String, String[]> condition) {
// 定义模板sql
String sql = “select count(*) from user where 1=1”;
StringBuilder sb = new StringBuilder(sql);
// 遍历map
Set keySet = condition.keySet();
// 参数的集合
List params = new ArrayList<>();
for (String key : keySet) {
// 排除分页条件参数
if (“currentPage”.equals(key) || “rows”.equals(key))
continue;
String value = condition.get(key)[0];
if (value != null && !“”.equals(value)){
// 有值
sb.append(" and “+ key +” like ? ");
params.add(“%” + value + “%”); // 存储sql语句中 ? 的值
}
}
System.out.println(sb.toString());
System.out.println(params);
return template.queryForObject(sb.toString(), Integer.class,params.toArray());
}
findByPage(int start, int rows, Map condition)方法的实现类似于上面的实现,在这里没有将重复代码提取出一个单独的方法,大家可以自己完成一下
@Override
public List findByPage(int start, int rows, Map<String, String[]> condition) {
String sql = "select * from user where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);
// 遍历map
Set keySet = condition.keySet();
// 参数的集合
List params = new ArrayList<>();
for (String key : keySet) {
// 排除分页条件参数
if (“currentPage”.equals(key) || “rows”.equals(key))
continue;
String value = condition.get(key)[0];
if (value != null && !“”.equals(value)){
// 有值
sb.append(" and “+ key +” like ? ");
params.add(“%” + value + “%”); // 存储sql语句中 ? 的值
}
}
// 添加分页查询
sb.append(" limit ?,? ");
// 添加分页查询参数值
params.add(start);
params.add(rows);
sql = sb.toString();
System.out.println(sql);
System.out.println(params);
return template.query(sql, new BeanPropertyRowMapper<>(User.class), params.toArray());
}
9 登录功能
login.jsp页面
将表单的action设置为对应servlet程序的目录
验证码图片的src设置为对应servlet程序的目录
在javascript中定义刷新验证码的函数
function refreshCode() {
// 获取验证码图片对象
var vcode = document.getElementById(“vcode”);
// 设置src属性 加上时间戳
vcode.src = “${pageContext.request.contextPath}/checkCodeServlet?time=” + new Date().getTime();
}
验证码自动生成程序 CheckCodeServlet.java,网上有很多实例代码,这里只将其贴在这里
package web.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
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;
/**
- 验证码
*/
@WebServlet(“/checkCodeServlet”)
public class CheckCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//服务器通知浏览器不要缓存
response.setHeader(“pragma”,“no-cache”);
response.setHeader(“cache-control”,“no-cache”);
response.setHeader(“expires”,“0”);
//在内存中创建一个长80,宽30的图片,默认黑色背景
//参数一:长
//参数二:宽
//参数三:颜色
int width = 80;
int height = 30;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics g = image.getGraphics();
//设置画笔颜色为灰色
g.setColor(Color.GRAY);
//填充图片
g.fillRect(0,0, width,height);
//产生4个随机验证码,12Ey
String checkCode = getCheckCode();
//将验证码放入HttpSession中
request.getSession().setAttribute(“CHECKCODE_SERVER”,checkCode);
//设置画笔颜色为黄色
g.setColor(Color.YELLOW);
//设置字体的小大
g.setFont(new Font(“黑体”,Font.BOLD,24));
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
很多实例代码,这里只将其贴在这里package web.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
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;
/**
- 验证码
*/
@WebServlet(“/checkCodeServlet”)
public class CheckCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//服务器通知浏览器不要缓存
response.setHeader(“pragma”,“no-cache”);
response.setHeader(“cache-control”,“no-cache”);
response.setHeader(“expires”,“0”);
//在内存中创建一个长80,宽30的图片,默认黑色背景
//参数一:长
//参数二:宽
//参数三:颜色
int width = 80;
int height = 30;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics g = image.getGraphics();
//设置画笔颜色为灰色
g.setColor(Color.GRAY);
//填充图片
g.fillRect(0,0, width,height);
//产生4个随机验证码,12Ey
String checkCode = getCheckCode();
//将验证码放入HttpSession中
request.getSession().setAttribute(“CHECKCODE_SERVER”,checkCode);
//设置画笔颜色为黄色
g.setColor(Color.YELLOW);
//设置字体的小大
g.setFont(new Font(“黑体”,Font.BOLD,24));
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-qsPILYr8-1715572484472)]
[外链图片转存中…(img-U2c238hX-1715572484472)]
[外链图片转存中…(img-nL3dWJdA-1715572484473)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!