javaweb学习

Servlet

开发一个Servlet只需要两部:

  • 编写一个类,实现Servlet接口
  • 把开发好的java类部署到web服务器上

把实现了Servlet的java程序叫做Sevlet

每次都要先进行web.xml修改

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
  • 编写一个类,实现servlet接口,直接继承HttpServlet

    快速调用类的方法的快捷键 ctrl + o

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // super.doGet(req, resp);
    // try (ServletOutputStream servletOutputStream = resp.getOutputStream()) {
    // }

    try (PrintWriter printWriter = resp.getWriter()) { // 响应流
    printWriter.print("hello servlet");
    }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    super.doPost(req, resp);
    }


    }

  • 修改web.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1"
    metadata-complete="true">

    <!--注册servlet-->
    <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloServlet</servlet-class>
    </servlet>

    <!--servlet的请求路径-->
    <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    </web-app>

ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletConText对象,它代表了当前的web应用;

1.共享数据

我在这个Servlet中保存的数据,可以在另一个Servlet的找到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class helloservlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// this.getInitParameter() 初始化参数
// this.getServletConfig() servlet配置原理
// this.getServletInfo() servlet上下文

ServletContext context = this.getServletContext();

String username = "likunsong";
context.setAttribute("username",username); // 将一个数据保存在ServletContext中,名字为username,值为 username

System.out.println("hello");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();

String username = (String) context.getAttribute("username");

resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print(username);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.li.servlet.helloservlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.li.servlet.GetServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>

2.获取初始化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>

<servlet>
<servlet-name>Demo03</servlet-name>
<servlet-class>com.li.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo03</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
1
2
3
4
5
6
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();

String url = context.getInitParameter("url");
resp.getWriter().print(url);
}

3.请求转发

1
2
3
4
5
6
7
8
9
10
11
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();

// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/demo"); // 转发的请求路径
// requestDispatcher.forward(req,resp); // 用forword实现请求转发

context.getRequestDispatcher("/demo").forward(req,resp);

System.out.println("进入了ServlDemo04");
}
1
2
3
4
5
6
7
8
<servlet>
<servlet-name>Demo04</servlet-name>
<servlet-class>com.li.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo04</servlet-name>
<url-pattern>/demo4</url-pattern>
</servlet-mapping>

4.读取资源文件

Properties

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现都被打包打了同一个路径下:classes ,我们俗称这个路径为classpath;

思路:需要一个文件流:

1
2
username = root
password = 123456
1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String password = prop.getProperty("password");

resp.getWriter().print(username+" "+password);

}

访问测试即可。

HttpServletResponse

web服务器接收到客户端的http请求,会针对这个请求分别创建一个代表请求的request的对象,和一个代表相应的response对象

  • 如果要获取我们客户端请求的参数,找request
  • 如果要给客户端响应一些东西,找response

1.常见应用

  1. 向浏览器发送消息
  2. 下载文件
    1. 获取要下载文件的路径
    2. 下载的文件名
    3. 设置想办法让浏览器能够支持我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓存区
    6. 获取OUTputStream对象
    7. 使FileOutStream流写入buffer缓冲区
    8. 使用OutputStream将缓冲区中的数据输出到客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取要下载文件的路径
// String realPath = this.getServletContext().getRealPath("/1.jpg");
String realPath = "E:\\project\\demo\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg";
System.out.println("下载文件的路径"+realPath);
// 下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 设置想办法让浏览器能够支持我们需要的东西
resp.setHeader("Content-Disposition","attachment;filename="+filename);
// 中文名字使用URLEcoder.encode编码,否则有可能乱码
// resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(filename,"UTF-8");
// 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 创建缓存区
int len = 0;
byte[] buffer = new byte[1024];
// 获取OUTputStream对象
ServletOutputStream out = resp.getOutputStream();
// 使FileOutStream流写入buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while((len = in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}

2.验证码功能

验证码怎么来的?

  • 前端实现
  • 后端实现,需要用到java的图片类,生成一个图片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何让浏览器5秒自动刷新一次
resp.setHeader("refresh","5");

// 在内存中创建图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);

// 得到图片
Graphics2D g = (Graphics2D) image.getGraphics(); // 笔
// 设置图片的背景颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
// 给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);


// 告诉浏览器这个请求用图片的方式打开
resp.setContentType("image/jpeg");
// 网站存在缓存,不然浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Prama","no-cache");

// 把图片写给浏览器
ImageIO.write(image,"jpg", resp.getOutputStream());
}

// 生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for(int i = 0;i < 7 - num.length();i ++){
sb.append("0");
}
String s = sb.toString() + num;
return s;
}
1
2
3
4
5
6
7
8
<servlet>
<servlet-name>img</servlet-name>
<servlet-class>com.li.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>img</servlet-name>
<url-pattern>/img</url-pattern>
</servlet-mapping>

3.实现重定向

B一个web资源收到客户端A请求后,B他会通知A客户端去访问另一个web资源C,这个过程叫重定向

常见场景

  • 用户登录

    1
    void sendRedirect(String varl) throws IOException

测试:

1
2
3
4
5
/**
resp.setHeader("Location","/r/img");
resp.setStatus(302);
*/
resp.sendRedirect("/r/img"); //重定向

面试题:请你聊一聊转发和重定向的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会发生变化
  • 重定向的时候,url会发生变化

登录实现

1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求
String username = req.getParameter("username");
String password = req.getParameter("password");

System.out.println(username+""+password);

// 重定向的时候,一定要注意路径问题,否则404
resp.sendRedirect("/r/success.jsp");
// 自己写的jsp,里面只有一个success的字
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<body>
// 防止乱码
<%@ page contentType="text/html;" pageEncoding="utf-8" %>
<h2>Hello World!</h2>

<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>

</body>
</html>

1
2
3
4
5
6
7
8
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.li.servlet.Requestext</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>

HttpServletRequest

代表客户端的请求,通过http协议访问服务器,http请求中的所有信息会被封装到httpservletrequest。通过这个方法,可以获得客户端的信息。

1.获取前端传递的参数,请求转发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决出现的乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");

String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");

System.out.println("===========================");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("===========================");

// 通过请求转发

// 说明,这里的 / 代表当前的web应用,所以不需要在前面加路径了
req.getRequestDispatcher("/loginsuccess.jsp").forward(req,resp);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>

<h1>登录</h1>

<div>
<%--表单表示的意思,以post的方式提交表单,提交到我们的login请求--%>
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
爱好:
<input type="checkbox" name="hobbys" value="代码"> 代码
<input type="checkbox" name="hobbys" value="唱歌"> 唱歌
<input type="checkbox" name="hobbys" value="电影"> 电影
<input type="checkbox" name="hobbys" value="游戏"> 游戏

<br>
<input type="submit">
</form>
</div>

</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
# loginsuccess.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<h1>登录成功</h1>

</body>
</html>

面试题:请你聊一聊转发和重定向的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会发生变化 ; 307
  • 重定向的时候,url会发生变化; 302

cookie session

1.会话

用户打开一个浏览器,点击了超链接,访问多个web资源,关闭浏览器,这个过程可以称为会话。

有状态会话

一个网站怎么证明你来过

客户端 服务端

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
  2. 服务器登记你来过了,下次你来的时候,我来匹配你

2.保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在session中

常见例子:网站登录之后,第二次访问不用登录,直接就登上去

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
1
2
3
4
5
6
Cookie[] cookies = req.getCookies(); // 获得cookie
cookie.getName() // 获得cookie中的key
cookie.getValue() // 获得cookie中的值
new Cookie("Lasttime", System.currentTimeMillis()+""); // 新建一个cookie
cookie.setMaxAge(24*60*60); // 设置cookie的有效期
resp.addCookie(cookie); // 响应给客户端

cookie:一般会保存在本地的 用户目录下 appdata

一个网站cookie是否存在上限

细节问题

  • 一个cookie只能保存一个信息
  • 一个web站点可以给浏览器发送多个cookie,最多20个
  • cookie大小有限制4kb
  • 浏览器cookie上限300个

删除cookie:

  • 不设置有效期,关闭浏览器,自动失效
  • 把有效期设置为0

4.session(重点)

什么是session

  • 服务器会给每一个用户(浏览器)创建一个session对象
  • 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
  • 用户登录之后,整个网站他都能访问 —-》保存用户的信息,保存购物车的信息….

Session和cookie的区别

  • cookie是吧用户的数据放在浏览器保存
  • session把用户的数据写到用户独占session中,服务端包保存(保存重要的信息,较少服务器自愿的浪费)
  • session对象由服务创建

使用场景

  • 保存一个登录用户的信息
  • 购物车信息
  • 在整个网站中经常会使用到的数据,保存在session中

使用session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// 解决乱码问题
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 得到session
HttpSession session = req.getSession();


// 给session存东西
session.setAttribute("name","李坤松");

// 获取session的ID
String id = session.getId();

// 判断session新创建
if(session.isNew()){
resp.getWriter().write("session已经创建成功,ID"+id);
}else{
resp.getWriter().write("session以及在服务器中存在了,ID"+id);
}


}

// 手动注销session
session.invalidate();

会话自动过期:web.xml部署

1
2
3
4
<session-config>
<!-- 15分钟后session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>

JSP

1.什么是jsp

最大的特点:

  • 写jsp就像写html
  • 区别
    • html只提供动态界面
    • Jsp中可以嵌入java代码,为用户提供动态数据

2.Jsp原理

思路:jsp怎么执行

  • 代码层面没有任何问题

  • 服务器内部工作

    tomcat内部有一个work目录

    IDEA中使用tomcat会在idea中生产一个work目录

JSP本质还是一个Servlet

JSP表达式

1
2
3
4
<%
作用: 用来将程序输出,输出到客户端
<%=b%>
%>

3.jsp标签,JSTL标签,EL表达式

使用JSTL

  • 导入依赖(pom.xml)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <dependencies>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    </dependency>
    <!--导入jsp坐标-->
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
    <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    </dependency>
    <!--导入jstl坐标-->
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
    <dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
    </dependency>
    <dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
    </dependency>

    </dependencies>
  • 在jsp界面上引入JSTL标签

    1
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

JSTL使用的语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<%
ArrayList<String > people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"田七");
people.add(2,"赵六");
people.add(3,"王五");
people.add(4,"里斯");

request.setAttribute("list",people);
%>

<form action="hello.jsp" method="get">

<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>

<c:forEach var="people" items="${list}">
<c:out value="${people}"/> <br>
</c:forEach>

<c:if test="${param.username == 'admin'}" var="admincheck">
<c:out value="管理员欢迎你"/>
</c:if>

<c:set value="111" var="scope"/>
<c:choose>
<c:when test="${scope > 90}">
<c:out value="你的成绩为优秀"/>
</c:when>
<c:when test="${scope > 80}">
<c:out value="你的成绩为良好"/>
</c:when>
<c:when test="${scope > 70}">
<c:out value="你的成绩为一般"/>
</c:when>
<c:when test="${scope > 60}">
<c:out value="你的成绩为及格"/>
</c:when>
</c:choose>

image-20220508135143804

JavaBean

实体类

JavaBean有特定的写法

  • 必须有一个无参构造
  • 属性必须私有化
  • 必须有对应的set/get方法

一般用来和数据库的字段做映射 ORM;

ORM :对象关系映射

  • 表 –> 类
  • 字段 –> 类的属性
  • 行记录 –> 类的对象

people表

id name age address
1 1号 3 郑州
2 2号 18 郑州
1
2
3
4
5
6
7
8
9
10
class people{
private int id;
private String name;
private int age;
private String address;
}

class A{
new people(1,"1号",3,"")
}

MVC三层架构

model

  • 业务处理:业务逻辑(Service)
  • 数据持久层: CURD(Dao)

View

  • 展示数据
  • 提供链接发起的Servlet请求 (a , form , img )

Controller (servlet)

  • 接收用户的请求:(req:请求参数,Session 信息 。。)
  • 交给业务层对应的代码
  • 控制试图的跳转
1
登录 --> 接收用户的登录请求 -->处理用户的请求(获取用户登陆的参数,username,password) --> 交给业务层处理业务(判断用户名密码是否正确:事务) --> Dao层查询用户名和密码是否正确 --> 数据库

Filter(过滤器)重点

Filter:过滤器,用来过滤网站的数据

  • 处理中文乱码
  • 登录验证

Filter开发步骤

导包

要导入Filter(javax.servlet)的包

编写过滤器

实现Filter接口,重写对应的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CharacterEncodingFilter implements Filter {

// 初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化");
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset = utf-8");

filterChain.doFilter(servletRequest,servletResponse) ; // 让我们的请求继续走,否则我们的程序到这里就被拦截

}
// 销毁,服务器关闭的时候,会销毁
@Override
public void destroy() {
System.out.println("销毁");
}
}

在web.xml中配置Filter

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>filter</filter-name>
<filter-class>com.li.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<!-- show/ 的所有目录都经过过滤器-->
<url-pattern>/show/*</url-pattern>
</filter-mapping>

监听器

监听器的接口

  1. 编写一个监听器

    实现监听器的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    // 统计网站在线人数监听; 统计session
    public class OnlineCountlisterner implements HttpSessionListener {

    // 创建session监听
    // 一旦创建一个session就会出发事件
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    ServletContext sct = httpSessionEvent.getSession().getServletContext();
    Integer oct = (Integer) sct.getAttribute("OnlineCount");

    if(oct == null)
    {
    oct = new Integer(1);
    }
    else {
    int count = oct.intValue();
    oct = new Integer(count + 1);
    }

    sct.setAttribute("OnlineCount",oct);
    }

    // 销毁session监听
    // 一旦销毁一个session就会出发事件
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    ServletContext sct = httpSessionEvent.getSession().getServletContext();
    Integer oct = (Integer) sct.getAttribute("OnlineCount");

    if(oct == null)
    {
    oct = new Integer(0);
    }
    else {
    int count = oct.intValue();
    oct = new Integer(count - 1);
    }

    sct.setAttribute("OnlineCount",oct);
    }

    /*
    session 销毁:
    1.手动销毁 getSession().invalidate()
    2.自动销毁
    * */
    }
  2. web.xml注册监听器

    1
    2
    3
    <listener>
    <listener-class>com.li.listenter.OnlineCountlisterner</listener-class>
    </listener>
  3. 看情况是否使用!(几乎不用)

过滤器,监听器的常见应用

监听器:GUI编程中经常使用:

  1. 用户登录后,向session中放数据
  2. 进入主页要判断用户是否登录;要求,在过滤器中实现
1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

if(request.getSession().getAttribute("USER_SESSION") == null){
response.sendRedirect("/j/login.jsp");
}

filterChain.doFilter(servletRequest,servletResponse);
}

JDBC

就是java连接数据库

导入jdbc的jar包

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>

JDBC固定步骤:

  1. 加载驱动
  2. 连接数据库
  3. 向数据库发送对象Statement:CRUD
  4. 编写SQL(根据业务,不同的SQL)
  5. 执行SQL
  6. 关闭连接

未预编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class testjdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 配置信息
// useUnicode=true&characterEncoding=utf-8 解决中文乱码问题
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";


// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");

// 2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);

// 3.向数据库发送SQL的对象statement ,preparedStatemetn : CRUD
Statement statement = connection.createStatement();

// 4.编写SQL
// String sql = "select * from jdbc.users";
String sql = "delete from jdbc.users where id=3";

// 受影响行数,增删改查都是使用 executeUpdate
// int i = statement.executeUpdate(sql);


// 5.执行SQL ,返回一个ResultSet : 结果集
ResultSet rs = statement.executeQuery(sql);

while(rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}

// 6.关闭连接,释放资源(一定要做) 先开后关
rs.close();
statement.close();
connection.close();

}
}

预编译SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class test2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 配置信息
// useUnicode=true&characterEncoding=utf-8 解决中文乱码问题
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";


// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");

// 2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);

// 3.编写SQL
// String sql = "select * from jdbc.users";
String sql = "insert into jdbc.users(id, name, password, email, birthday) values (?,?,?,?,?)";

// 4.预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);

preparedStatement.setInt(1,4); // 给第一个占位符?赋值为1
preparedStatement.setString(2,"lks"); // 给第二个占位符?赋值为 lks
preparedStatement.setString(3,"123456"); // 给第三个占位符?赋值为 123456
preparedStatement.setString(4,"1537628435@qq.com"); // 给第四个占位符?赋值为 1537628435@qq.com
preparedStatement.setDate(5,new Date(new java.util.Date().getTime())); // 给第五个占位符?赋值为 new Date(new java.util.Date().getTime())

// 执行SQL
int i = preparedStatement.executeUpdate();

if(i > 0){
System.out.println("插入成功");
}

// 6.关闭连接,释放资源(一定要做) 先开后关
preparedStatement.close();
connection.close();

}
}

事务

要么都成功,要么都失败

ACID原则:保证数据的安全

1
2
3
4
5
6
7
8
9
10
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务

转账
A:1000
B:1000

A(900) --100--> B(1100)

Junit(单元测试)

1
2
3
4
5
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

@Test 只有在方法上有效,只要加了这个注解的方法,就能直接运行

1
2
3
4
@Test
public void test(){
System.out.println("nimenhao");
}

image-20220508232830305

搭建一个环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class test3 {

@Test
public void test(){
// 配置信息
// useUnicode=true&characterEncoding=utf-8 解决中文乱码问题
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";

Connection connection = null;

// 1.加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
// 2.连接数据库,代表数据库
connection = DriverManager.getConnection(url, username, password);

// 3.通知数据库开启事务,false 开启,true 关闭
connection.setAutoCommit(false);

String sql1 = "update jdbc.account set money = money - 100 where name='A'";
connection.prepareStatement(sql1).executeUpdate();


// 制造错误
// int i= 1/0;

String sql2 = "update jdbc.account set money = money + 100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();

connection.commit();
System.out.println("success");


} catch (Exception e) {
try {
// 如果出现异常,数据库回滚
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

}
}

image-20220508234802928


项目实战SMBMS

项目搭建准备工作

  1. 使用maven搭建
  2. 配置tomcat创建服务器
  3. 测试项目能不能跑

Dao层是进行数据库的操作类的封装。Service层是业务层,调用Dao层的操作类。Servlet是表示层,处理页面的传过来的数据,然后调用service 来实现功能

导入项目遇到的jar包

jar 包jsp,servlet,jstl,mysql驱动,stand

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!--导入jsp坐标-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<!--导入jstl坐标-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>

</dependencies>

创建项目包结构

编写实体类

表映射

编写基础公共类

数据库配置文件

1
2
3
4
driver = com.mysql.jdbc.Driver
usl = jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username = root
password = 123456

编写数据库的公共类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.li.dao;

import javax.xml.transform.Result;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

// 操作数据库的公共类
public class BaseDao {

private static String driver;
private static String url;
private static String username;
private static String password;

// 静态代码块,类加载的时候初始化
static {

Properties properties = new Properties();
//通过类加载器读取对应的资源
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");

try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}

driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");

}

// 获取数据库的连接
public static Connection getConnection(){
Connection connection = null;
try {
// 加载驱动
Class.forName(driver);
// 连接数据库
connection = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}

return connection;
}

// 编写查询公共类
public static ResultSet execute(Connection connection,String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement) throws SQLException {

// 预编译 的sql 在后面直接执行
preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i < params.length;i ++){
preparedStatement.setObject(i + 1,params[i]);
}
resultSet = preparedStatement.executeQuery();

return resultSet;

}

// 编写增删改查的公共方法
public static int execute(Connection connection,String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException {

// 预编译
preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i < params.length;i ++){
preparedStatement.setObject(i + 1,params[i]);
}

int updateRows = preparedStatement.executeUpdate(sql);
return updateRows;

}

// 释放资源
public static boolean closeResource(Connection connection,ResultSet resultSet,PreparedStatement preparedStatement){
boolean flag = true;
if(resultSet != null)
{
try {
resultSet.close();
resultSet = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if(connection != null)
{
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if(preparedStatement != null)
{
try {
preparedStatement.close();
preparedStatement = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}

return flag;
}
}

编写字符编码过滤器

1
2
3
4
5
6
7
8
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html");

filterChain.doFilter(servletRequest,servletResponse);
}

导入静态资源

https://github.com/five517/SMBMS

登录功能实现

1.编写前端界面

2.设置欢迎界面

1
2
3
4
<!--    设置欢迎界面-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

3.编写dao层登录用户的接口

1
2
// 得到登录的用户
public User getLoginUser(Connection connection,String usercode) throws SQLException;

4.编写dao接口的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class UserDaoIm1 implements UserDao{
@Override
public User getLoginUser(Connection connection, String userCode) throws SQLException {

PreparedStatement pstm = null;
ResultSet rs = null;
User user = null;

if(connection != null)
{
String sql = "select * from smbms_user where userCode=?";
Object[] params = {userCode};

rs = BaseDao.execute(connection, sql, params, rs, pstm);
if(rs.next()){
user = new User();
user.setId(rs.getInt("id"));
user.setUserCode(rs.getString("userCode"));
user.setUserName(rs.getString("username"));
user.setGender(rs.getInt("gender"));
user.setBirthday(rs.getDate("birthday"));
user.setPhone(rs.getString("phone"));
user.setAddress(rs.getString("address"));
user.setUserRole(rs.getInt("userRole"));
user.setCreatedBy(rs.getInt("createBy"));
user.setCreationDate(rs.getTimestamp("creationDate"));
user.setModifyBy(rs.getInt("modifyBy"));
user.setModifyDate(rs.getTimestamp("modifyDate"));
}


}

return user;
}
}

5.业务层实现类的接口

1
2
3
4
5
6
public interface UserService {

// 用户登录
public User login(String userCode , String password);

}

6.编写业务实现类的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class UserServiceImp1 implements UserService{

// 业务层,都会调用dao层,所以我们要引入dao层
private UserDao userDao;

public UserServiceImp1(){
userDao = new UserDaoIm1();
}

@Override
public User login(String userCode, String password) {
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnection();
// 通过业务层,调用对应的具体的数据库操作
user = userDao.getLoginUser(connection, userCode);
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return user;
}

}

7.编写Servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class loginServlet extends HttpServlet {

// Servlet :控制层,调用业务层

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("LoginServlet--start....");
// 获取用户名和密码
String usercode = req.getParameter("userCode");
String userPassword = req.getParameter("userPassword");

// 和数据库中的数据进行对比,调用业务层
UserServiceImp1 userServiceImp1 = new UserServiceImp1();
User user = userServiceImp1.login(usercode, userPassword); // 查到了登陆的人

if(user != null) { // 如果有这个人
// 将用户的信息放在session中
req.getSession().setAttribute(Constant.USER_SESSION,user);
// 登录成功后挑战到内部主页
resp.sendRedirect("jsp/frame.jsp");
}else{ // 查无此人,无法登录
// 转发回到登录界面,顺带提示它,用户名或密码错误
req.setAttribute("error","用户名或密码不正确");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

8.注册Servlet

1
2
3
4
5
6
7
8
9
<!--    Servlet-->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.li.servlet.user.loginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>

登录功能优化

注销功能:

思路: 移除session,返回登录界面

LoginoutServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
public class loginoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 一处登录界面
req.getSession().removeAttribute(Constant.USER_SESSION);
resp.sendRedirect(req.getContextPath()+"/login.jsp"); // 返回登陆界面
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}

xml

1
2
3
4
5
6
7
8
9
<!--    注销登录-->
<servlet>
<servlet-name>LogintoutServlet</servlet-name>
<servlet-class>com.li.servlet.user.loginoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogintoutServlet</servlet-name>
<url-pattern>/jsp/logout.do</url-pattern>
</servlet-mapping>

登录拦截优化

SysFilter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req1 = (HttpServletRequest) req;
HttpServletResponse resp1 = (HttpServletResponse) resp;

// 过滤器从session中获取用户
User attribute = (User) req1.getSession().getAttribute(Constant.USER_SESSION);

if(attribute == null){ // 已经注销了,或者未登录
resp1.sendRedirect("/smbms/error.jsp");
}

filterChain.doFilter(req1,resp1);

}

xml

1
2
3
4
5
6
7
8
9
<!--    用户登录过滤器-->
<filter>
<filter-name>sysfilter</filter-name>
<filter-class>com.li.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sysfilter</filter-name>
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>

密码修改

UserDao接口

1
2
// 修改当前的密码
public int updatePwd(Connection connection,int id , int password) throws SQLException;

UserDao接口实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//修改密码
// 如果返回的值大于1,则执行成功,否则执行失败。
@Override
public int updatePwd(Connection connection, int id, int password) throws SQLException {

PreparedStatement pstm = null;
int execute = 0;

if(connection != null)
{
String sql = "update smbms.smbms_user set userPassword = ? where id = ?";
Object params[] = {password,id};
execute = BaseDao.execute(connection, sql, params, pstm);
BaseDao.closeResource(null,null,pstm);
}

return execute;
}

UserService层接口

1
2
// 根据userid修改密码
public boolean updatePwd( int id , int pwd);

UserService实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 修改密码
@Override
public boolean updatePwd(int id, int pwd) {
Connection connection = null;
boolean flag = false;
connection = BaseDao.getConnection();

try {
if(userDao.updatePwd(connection,id,pwd)>0){
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}

return flag;
}

UserServlet编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String method = req.getParameter("method");
if(method != null && method.equals("savepwd")){
this.upadtePwd(req,resp);
}else if(method != null && method.equals("pwdmodify")){
this.pwdModeify(req,resp);
}

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}

// 修改密码
public void upadtePwd(HttpServletRequest req, HttpServletResponse resp){
// 从session里面拿id
Object attribute = req.getSession().getAttribute(Constant.USER_SESSION);
String newpassword = req.getParameter("newpassword");


boolean flag = false;

if(attribute != null && newpassword != null){
UserService userService = new UserServiceImp1();
flag = userService.updatePwd(((User) attribute).getId(), newpassword);

if(flag) {
req.setAttribute("message","修改密码成功,请退出使用新密码登录");
// 密码修改成功,一处当前session
req.getSession().removeAttribute(Constant.USER_SESSION);
} else{
req.setAttribute("message","密码修改失败");

}

}else{
req.setAttribute("message","密码修改失败");
}

try {
req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

优化密码使用Ajax

阿里巴巴的fastJaon

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.2</version>
</dependency>

修改userServlet内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public void pwdModeify(HttpServletRequest req, HttpServletResponse resp){
Object attribute = req.getSession().getAttribute(Constant.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");

// 万能的map
Map<String, String> resultMap = new HashMap<String, String>();

if(attribute == null){ // session失效了
resultMap.put("result","sessionerror");
}else if(StringUtils.isNullOrEmpty(oldpassword)){
resultMap.put("result","error");
}else {
String userPassword = ((User) attribute).getUserPassword();
if(oldpassword.equals(userPassword)){
resultMap.put("result","true");
}else {
resultMap.put("result","false");
}
}
try {
resp.setContentType("application/jsion");
PrintWriter writer = resp.getWriter();
// JSONArray 阿里巴巴的json工具类,转化格式
writer.write(JSONArray.toJSONString(resultMap));
writer.flush();
writer.close();

} catch (IOException e) {
e.printStackTrace();
}
}

用户管理实现

导入分页的工具类

用户列表页面导入

获取用户数量

UserDao,UserDaoImpl,UserService,UserServiceImpl

UserDao

1
2
// 查询用户总数
public int getUserCount(Connection connection,String username , int userrole)throws SQLException;

UserDaoImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 根据用户名或者角色,查询用户总数
@Override
public int getUserCount(Connection connection, String username, int userrole) throws SQLException {

PreparedStatement pstm = null;
ResultSet rs = null;
int count = 0;

if(connection != null){
StringBuffer sql = new StringBuffer();
sql.append("select count(1) as count from smbms.smbms_user u,smbms.smbms_role r where u.userRole = r.id");

ArrayList<Object> list = new ArrayList<Object>();// 存放我们的参数

if(!StringUtils.isNullOrEmpty(username)){
sql.append(" and u.userName like ?");
list.add("%"+username+"%"); // 默认的index = 0
}
if(userrole > 0){
sql.append(" and u.userRole = ?");
list.add(userrole); // index = 1
}

Object[] params = list.toArray();

System.out.println("text:"+sql.toString());

rs = BaseDao.execute(connection, sql.toString(), params, rs, pstm);

if(rs.next()){
count = rs.getInt("count");//从结果集获取最后的数量
}
BaseDao.closeResource(null,rs,pstm);
}
return count ;
}

UserService

1
2
// 查询记录数
public int getUserCount(String username,int userrole);

UserServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 记录查询数
@Override
public int getUserCount(String username, int userrole) {

Connection connection = null;
int count = 0;
try {
connection = BaseDao.getConnection();
count = userDao.getUserCount(connection,username,userrole);
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return count;
}

获取用户列表

UserDao,UserDaoImpl,UserService,UserServiceImpl

UserDao

1
2
//通过用户输入的条件查询用户列表
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception;

UserDaoImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//根据条件查询用户列表
@Override
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception {
List<User> userList = new ArrayList<User>();
PreparedStatement pstm=null;
ResultSet rs=null;
if(connection!=null){
StringBuffer sql = new StringBuffer();
sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id");
List<Object> list = new ArrayList<Object>();
if(!StringUtils.isNullOrEmpty(userName)){
sql.append(" and u.userName like ?");
list.add("%"+userName+"%");
}
if(userRole > 0){
sql.append(" and u.userRole = ?");
list.add(userRole);
}

// 在数据库中,分页使用 limit startIndex, PageSize 总数

sql.append(" order by creationDate DESC limit ?,?");
currentPageNo = (currentPageNo-1)*pageSize;
list.add(currentPageNo);
list.add(pageSize);

Object[] params = list.toArray();
System.out.println("sql ----> " + sql.toString());
rs = BaseDao.execute(connection,sql.toString(),params,rs,pstm);
while(rs.next()){
User _user = new User();
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
userList.add(_user);
}
BaseDao.closeResource( null, rs, pstm);
}
return userList;
}

UserService

1
2
//根据条件查询用户列表
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);

UserServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//根据条件查询用户列表
@Override
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
// TODO Auto-generated method stub
Connection connection = null;
List<User> userList = null;
System.out.println("queryUserName ---- > " + queryUserName);
System.out.println("queryUserRole ---- > " + queryUserRole);
System.out.println("currentPageNo ---- > " + currentPageNo);
System.out.println("pageSize ---- > " + pageSize);
try {
connection = BaseDao.getConnection();
userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
return userList;
}

出现错误总结:

web.xml中添加servlet 注释报错

出现错误信息: Element 'web-app' cannot have character [children], because the type's content type is element-only

原因:web.xml中注释写的有问题,不能直接使用 // ,要使用;

java文件中添加HttpServlet报错

解决办法:

找到自己的tomcat目录下lib目录下的 servlet-api.jar

image-20220430151358714

由于我的已经处理好,下面附上别的博主的照片

img

img

最后在java文件中import即可解决。

引用博客链接

运行后java显示的有乱码

在java文件中添加

1
2
3
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");

添加 useSSL=false

image-20220513133427776