目录
1.Javaweb
1.1 静态web
html,css,提供给所有人看的数据始终不会发生变化
缺点:
- web界面无法动态更新,所有用户看到都是同一个界面
- 它无法和数据库交互(数据无法持久化,用户无法交互)
1.2 动态web
几乎是所有的网站,提供给所有人看的数据始终会发生变化,每个人在不同的时间不同的地点看到的信息各不相同
技术栈:Servlet/JSP,ASP,PHP
优点:
- web界面可以动态更新,所有用户看到的都不是同一个界面
- 它可以和数据库交互(JDBC)
1.3 web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息
- Tomcat
在其中conf文件夹下中server为核心配置文件,在其中:
可以配置主机的端口号
Tomcat的默认端口号为8080
mysql:3306
http:80
https:443
可以配置主机的名称
默认的主机名为:localhost -> 127.0.0.1
默认网站存放的位置为webapps文件夹中(ROOT下的Index.jsp)(该文件夹下的每一个文件夹都是一个程序(网站))
面试题1:谈谈网站是如何进行访问的 - 输入一个域名;回车。
检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名的映射
如果有的话则直接返回对应的ip地址(因此可自己手动修改)
如果没有的话则去DNS服务器寻找,找到的话就返回,找不到的话就返回找不到
1.4 Http
-
Http(超文本传输协议)是一个简单的请求-相应协议,它通常运行在TCP之上。
- 文本:html,字符串
- 超文本:图片,音乐,视频,定位,地图…
- 端口号为80
-
Https:安全的,端口号为443
-
Http的两个时代:
- Http1.0:客户端与web服务器连接后,只能获得一个web资源,断开连接
- Http2.0:客户端与web服务器连接后,可以获得多个web资源。
-
Http请求
- 请求方式:get,post,head,put,delete
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
- post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
- 请求方式:get,post,head,put,delete
-
Http响应
- 响应状态码
- 200:请求响应成功
- 3xx:请求重定向
- 重定向:你重新到我给你的新位置去
- 4xx:找不到资源(404)
- 5xx:服务器代码错误 (500) 502:网关错误
- 响应状态码
1.5 Maven
- 我为什么要学习这个技术?
在javaweb开发中,需要使用大量的jar包,为了能够让一个东西自动帮我导入和配置这个jar包,由此诞生了Maven - 下载maven并安装
- 配置环境变量
- 配置阿里云镜像(加速下载速度) (在conf中settings中的mirrors中贴一段代码)
- 配置本地仓库(在conf中新建一个文件夹并命名maven-repo,然后在settings中贴一行代码,代码中包含上述文件夹的地址)
- 在IDEA中使用Maven
- 打开IDEA
- 创建Maven项目(创建时可以选用Maven的一些模板,若是创建一个Maven Web项目则勾选一个类似 …maven-wepapp的)(也可不采用模板,直接创建,创建完成之后右击项目—>添加框架的支持)
- 填写G(GroupId,组的名称,通常是公司域名)A(ArtifactId,组内构建的名称,通常是项目名)V(Version 版本号)以及项目所存放位置
- 如果是选用的Maven模板进行创建,则还需选择Maven文件的位置,核心配置文件的位置,本地仓库的位置(自己放置的地方,直接选取即可)若想避免每次创建时都需要设置这三项,则可以修改全局设置,在初始创建界面的Configue中的设置,设置一下Maven中的那三项位置即可。
- 在IDEA中配置Tomcat
- 点击右上角Configuration -> 点击加号 -> 选取Tomcat,进行配置即可
- 配置时必须要创建一个Artifact,因为访问一个网站必须指定一个文件夹名字,这个需要创建,并可指定网站名称(这个过程叫虚拟地址映射)
- 配置完成后点击右上角就可启动了,会展示HelloWorld,默认的index.jsp中的内容
- pom.xml是Maven的核心配置文件
- 在此文件中可以添加很多依赖,来导入jar包
1.6 Servlet
-
Servlet就是sun公司开发动态web的一门技术
-
Sun在这些API中提供一个接口叫做Servlet,如果要想开发一个Servlet程序,只需完成两个小步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中
-
实现简单的 HelloServlet
-
Servlet接口sun公司有两个默认的实现类:HttpServlet,
-
构建一个普通的Maven项目,删掉里面的src目录,在其pom文件中添加servlet依赖。一般都是在项目中建立Module;这个空的工程就是Maven主工程,这样的好处在于,在父工程添加的依赖会继承给所有的子工程。每次创建模块不用重复增添依赖
-
建立Module后,在父项目核心文件中中会生成代码
<modules> <module>servlet-01</module> </modules>
在子项目核心文件中会生成代码
<parent> <artifactId>javaweb-01-servlet</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent>
子可继承父中的各种依赖
-
Maven环境搭建
- 修改web.xml为最新
- 将Maven的结构搭建完整
- 在main下添加java目录,并标记为“源码 根”
- 在main下添加resources目录,并标记为“resources 根”
-
编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口,直接继承HttpServlet
public class HelloServlet extends HttpServlet { // 由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入doGet方法"); PrintWriter writer = resp.getWriter(); writer.print("Hello,Servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
-
编写Servlet的映射
- 为什么需要映射?
- 我们写的是Java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的Servlet,并给他一个浏览器能够访问的路径,即映射。
- 如下面代码,由 /hello 映射到 com.liu.servlet.HelloServlet
<!-- 注册Servlet --> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.liu.servlet.HelloServlet</servlet-class> </servlet> <!-- Servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
- 为什么需要映射?
-
配置Tomcat
- 右上角进行配置(注意artifact的选取,不同的子web项目选取的artifact不同。每当创建了一个新的web后运行时记得修改!!)
-
启动
- 会先通过设置好的名称进入index.jsp页面,再通过/hello进入HelloServlet
-
-
Servelet的Mapping问题
-
一个Servlet可以指定一个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
一个Servlet可以指定多个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping>
-
一个Servlet可以指定通用映射路径( *代表可以输入任意)
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
默认请求路径 (启动Tomcat会覆盖首页,直接到达此处)
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
指定一些后缀或者前缀等 (如下为只要以“.liu”结尾就跳转,注意 * 前面不加 “/”)
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.liu</url-pattern> </servlet-mapping>
-
优先级问题
- 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求。(如下,除了输入/hello外,其余均会进入ErrorServlet)
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.liu.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.liu.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
-
ServletContext
web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用-
共享数据
- 所有的Servlet共享ServletContext中保存的数据,在一个Servlet中保存的数据可以在另外一个Servlet中拿到。
- 如下,在HelloServlet中存数据,在GetServlet中取出,先进入/hello中存数据后,再进入/getc获取数据。
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); // ctrl + alt + v 自动补全方法返回值 String username = "刘梦豪"; context.setAttribute("username",username); // 将一个数据保存在了ServletContext中 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
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 { doGet(req, resp); } }
<web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.liu.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>getc</servlet-name> <servlet-class>com.liu.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>getc</servlet-name> <url-pattern>/getc</url-pattern> </servlet-mapping> </web-app>
-
获取初始化参数
- 在web.xml中配置
<!-- 配置一些web应用初始化参数 --> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
public class ServletDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); // 获取初始化参数 resp.getWriter().print(url); //输出 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
请求转发
public class ServletDemo04 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); System.out.println("进入了ServletDemo04"); // RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); // 转发的请求路径 // requestDispatcher.forward(req,resp); // 调用forward实现请求转发 // 下面的 "/" 代表当前的web应用 context.getRequestDispatcher("/gp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
读取资源文件
-
在resources目录下新建properties文件
-
在java目录下新建properties文件(通过在pom文件中添加一段build代码,才能被打包到classes路径下,这个路径为classpath)
-
运行之后,这properties文件会被打包到target下面的classes中
-
通过文件流可以获取properties文件中的内容
username=root password=123456
public class ServletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/dp.properties"); // 注意路径位置,第一个 / 代表当前web,即servlet-02 Properties prop = new Properties(); prop.load(is); String user = prop.getProperty("username"); String pwd = prop.getProperty("password"); resp.getWriter().print(user+":"+pwd); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
-
-
HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象、代表响应的一个HttpServletResponse对象- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
- 常见应用
-
向浏览器输出消息(getwriter)
-
下载文件
public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 要获取下载文件的路径 String realPath = "D:\\all_Java_Project_Code\\javaweb-01-servlet\\response\\src\\main\\resources\\刘梦豪.jpg"; System.out.println("下载文件的路径:"+realPath); // 2. 获取下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1 ); // 3. 设置想办法让浏览器能够支持(Content-Dispositon)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")); // 4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); // 5. 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; // 6. 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端 while((len=in.read(buffer)) > 0) { out.write(buffer, 0, len); } in.close(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
验证码功能
public class ImageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 如何让浏览器3秒自动刷新一次 resp.setHeader("refresh","3"); // 在内存中创建一个图片 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("Progma","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"); } return sb.toString()+num; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
实现重定向
-
一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向
-
与请求转发的区别:
- 请求转发是A向B发送请求,B代替A去找到C然后返回给A,整个过程地址栏地址输入的B,始终是B,即URL地址栏不会发生变化。
- 重定向是A向B发送请求,B给A发送C的位置,A再去找C,整个过程地址栏地址输入的B,然后变成C,即URL地址栏会发生变化。
public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // getContextPath() 返回当前页面所在web项目的路径 resp.sendRedirect(req.getContextPath()+"/image"); // 重定向到image页面 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
由index.jsp页面 -> requestServlet,再通过重定向进入success.jsp页面
<html> <body> <h2>Hello World!</h2> <%@page pageEncoding="UTF-8"%> <%-- ${pageContext.request.contextPath} 代表当前的项目 --%> <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>
public class RequestServlet extends HttpServlet { @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); // 重定向 resp.sendRedirect(req.getContextPath()+"/success.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
-
-
HttpServletRequest
-
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。
-
获取前端传递的参数与请求转发(index.jsp->LoginServlet->succ)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录</title> </head> <body> <h1>登录</h1> <div> <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>
public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //后台接收到的数据中文乱码问题 req.setCharacterEncoding("utf-8"); resp.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("============================="); System.out.println(req.getContextPath()); // 通过请求转发 // 这里的 / 代表当前的web应用,不用再加 req.getContextPath(),这也是与重定向的一点区别。 req.getRequestDispatcher("/success.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
1.7 Cookie Session
- Cookie、Session
- 会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,然后关闭浏览器,这个过程称之为会话
- 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这就称之为有状态会话
- 问:一个网站如何证明你来过?
- 服务端给客户端一个信件,客户端下次访问服务端时带上信件就可以了。(cookie)
- 服务器端有记录,下次来的时候再次匹配。(session)
- 保存会话的两种技术
- cookie
- 客户端技术,服务器通过响应把cookie发给客户端,客户端通过请求把cookie发给服务器
- session
- 服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把数据或信息放在session中
- 常见:网站登陆过后,下次不用再登录,第二次访问直接就上去了。
- cookie
- Cookie
-
1.从请求中拿到cookie信息
-
2.服务器响应给客户端cookie
public class CookieDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 服务器,告诉你,你来的时间,把这个时间封装成一个信件,你下次带来,我就知道你来了 //解决中文乱码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html; charset=utf-8"); PrintWriter out = resp.getWriter(); // Cookie,服务器端从客户端获取,因此是req Cookie[] cookies = req.getCookies(); // 判断Cookie是否存在 if(cookies!=null) { // 如果存在 out.write("你上一次访问的时间是: "); for (int i=0;i<cookies.length;i++) { Cookie cookie = cookies[i]; // 获取cookie的名字 if(cookie.getName().equals("lastLoginTime")) { // 获取cookie中的值 long lastLoginTime = Long.parseLong(cookie.getValue()); Date date = new Date(lastLoginTime); out.write(date.toLocaleString()); } } } else { out.write("这是您第一次访问本站"); } //服务器给客户端响应一个Cookie Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+""); cookie.setMaxAge(60); // 设置cookie有效期,以秒为单位 resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
- Session(重点)
-
什么是Session:
- 服务器会给每一个用户(每一个浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器未关闭,这个Session就存在,用户可访问Session中的信息
-
Session与Cookie的区别
- Cookie是把用户的数据写给用户的浏览器,浏览器(用户)保存
- Session是把用户的数据写到用户独占的Session中,服务器端保存,一般用来保存重要的信息
- Session对象由服务器创建
-
创建Session
public class SessionDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决乱码问题 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); // 得到Session HttpSession session = req.getSession(); // 给Session中存东西 session.setAttribute("name", new Person("刘梦豪", 1)); // 获取Session中的ID String sessionId = session.getId(); // 判断Session是不是新创建 if(session.isNew()){ resp.getWriter().write("session创建成功,ID"+sessionId); }else{ resp.getWriter().write("session已经存在,ID"+sessionId); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
获取Session
public class SessionDemo02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决乱码问题 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); // 得到Session HttpSession session = req.getSession(); Person person = (Person) session.getAttribute("name"); System.out.println(person.toString()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
手动注销Session
public class SessionDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.removeAttribute("name"); //手动注销Session session.invalidate(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
在web.xml中设置自动注销Session
<!-- 设置Session默认的失效时间 --> <session-config> <!-- 60分钟后Session自动失效,以分钟为单位 --> <session-timeout>60</session-timeout> </session-config>
-
1.8 JSP
- JSP
- 什么是JSP
- Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态Web技术!
- 最大的特点:
- 写JSP就像在写HTML
- 区别:
- HTML只给用户提供静态的数据
- JSP页面中可以嵌入Java代码,为用户提供动态数据
- JSP本质上就是Servlet,只是简化了很多东西,进行了一定的封装
- 9大内置对象
-
PageContext (存东西)
-
Request (存东西)
-
Response
-
Session(存东西)
-
Application 【ServletContext】 存东西
-
Config 【ServletConfig】
-
Out
-
Page
-
Exception
<%-- 内置对象 --%> <% pageContext.setAttribute("name1","刘1号"); // 保存的数据只在一个页面中有效 request.setAttribute("name2","刘2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据 session.setAttribute("name3","刘3号"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器 application.setAttribute("name4","刘4号"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器 %>
-
应用场景
- request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻
- session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
- application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据
-
pageContextDemo01 -> pageContextDemo02
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%-- 内置对象 --%> <% pageContext.setAttribute("name1","刘1号"); // 保存的数据只在一个页面中有效 request.setAttribute("name2","刘2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据 session.setAttribute("name3","刘3号"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器 application.setAttribute("name4","刘4号"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器 %> <%-- 脚本片段中的代码,会被原封不动生成到java文件 要求: 这里面的代码,必须保证Java语法的正确性 --%> <% //从pageContext取出,通过寻找的方式来 //从底层到高层(作用域) pageContext->request->session->application String name1 = (String) pageContext.findAttribute("name1"); String name2 = (String) pageContext.findAttribute("name2"); String name3 = (String) pageContext.findAttribute("name3"); String name4 = (String) pageContext.findAttribute("name4"); String name5 = (String) pageContext.findAttribute("name5"); pageContext.forward("/pageContextDemo02.jsp"); // 请求转发,会发现原来在pageContextDemo02中展示不出来的 "刘2号" 可以展示出来了,因为request转发过程不会丢失数据 %> <%-- 使用EL表达式输出 --%> <h1>取出的值为:</h1> <h3>${name1}</h3> <h3>${name2}</h3> <h3>${name3}</h3> <h3>${name4}</h3> <h3>${name5}</h3> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%-- 使用EL表达式输出 name1和name2不会展示,只会展示出name3和name4 --%> <h1>取出的值为:</h1> <h3>${name1}</h3> <h3>${name2}</h3> <h3>${name3}</h3> <h3>${name4}</h3> <h3>${name5}</h3> </body> </html>
-
- JSP标签、JSTL标签、EL表达式
<!-- jstl表达式的依赖 --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <!-- standard标签库 --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
- EL表达式 : ${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
- JSP标签
//请求转发,并携带参数 <jsp:forward page="/jsptag2.jsp"> <jsp:param name="name" value="liumenghao"/> <jsp:param name="age" value="21"/> </jsp:forward>
- JSTL表达式
-
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!
-
JSTL标签库的使用步骤
- 引入对应的taglib
- 使用其中的方法
<body> <h4>if测试</h4> <hr> <form action="coreif.jsp" method="get"> <%-- EL表达式获取表单中的数据!!! ${param.参数名} --%> <input type="text" name="username" value="${param.username}"> <input type="submit" value="登录"> </form> <%-- 判断如果提交的用户名是admin,则登陆成功 --%> <%-- java代码形式 <% if(request.getParameter("username").equals("admin")){ out.print("登陆成功"); } %> --%> <%-- test用来进行判断,var用来接收test的返回值 --%> <c:if test="${param.username=='admin'}" var="isAdmin"> <c:out value="登陆成功"></c:out> </c:if> <c:out value="${isAdmin}"></c:out> </body>
<body> <%-- 定义一个变量score,值为85 --%> <c:set var="score" value="55"></c:set> <%-- 类似switch语句,按顺序逐个判断 --%> <c:choose> <c:when test="${score>=90}">你的成绩优秀</c:when> <c:when test="${score>=80}">你的成绩良好</c:when> <c:when test="${score>=70}">你的成绩一般</c:when> <c:when test="${score>=60}">你的成绩及格</c:when> <c:when test="${score<60}">你的成绩不及格</c:when> </c:choose> </body>
<body> <% ArrayList<Object> people = new ArrayList<>(); people.add(0,"张三"); people.add(1,"李四"); people.add(2,"王五"); people.add(3,"赵六"); people.add(4,"田七"); request.setAttribute("list",people); %> <%-- var: 每一次遍历出来的变量 items: 要遍历的对象 begin: 开始的下标 end: 结束的下标 step: 步长 --%> <c:forEach var="people" items="${list}"> <c:out value="${people}"></c:out> </c:forEach> <hr> <c:forEach var="people" items="${list}" begin="1" end="3" step="2"> <c:out value="${people}"></c:out> </c:forEach> </body>
-
- EL表达式 : ${}
- 什么是JSP
1.9 JavaBean
- JavaBean
实体类-
JavaBean有特定的写法
- 必须有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
-
一般用来和数据库的字段做映射 ORM(对象关系映射)
- 一个表 --> 一个类
- 一个字段 --> 一个属性
- 一行记录 --> 一个对象
package com.liu.pojo; public class People { private int id; private String name; private int age; private String address; public People(){ } public People(int id, String name, int age, String address) { this.id = id; this.name = name; this.age = age; this.address = address; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setAddress(String address) { this.address = address; } public int getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public String getAddress() { return address; } @Override public String toString() { return "People{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; } }
<%@ page import="com.liu.pojo.People" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% // 与下面等价 // People people = new People(); // people.setAddress(); // people.setId(); // people.setAge(); // people.setName(); %> <jsp:useBean id="people" class="com.liu.pojo.People" scope="page"></jsp:useBean> <jsp:setProperty name="people" property="address" value="河南"></jsp:setProperty> <jsp:setProperty name="people" property="id" value="1"></jsp:setProperty> <jsp:setProperty name="people" property="age" value="21"></jsp:setProperty> <jsp:setProperty name="people" property="name" value="刘梦豪"></jsp:setProperty> <%-- 与下面等价 <%= people.getAddress()%> --%> 姓名:<jsp:getProperty name="people" property="name"/> id:<jsp:getProperty name="people" property="id"/> 年龄:<jsp:getProperty name="people" property="age"/> 地址:<jsp:getProperty name="people" property="address"/> </body> </html>
-
1.10 MVC
- MVC三层架构
-
Model、View、Controller 模型、视图、控制器
-
最初时
- 用户直接访问控制层,控制层就可以直接操作数据库
- Servlet->增删改查->数据库
- 程序十分臃肿,不利于维护
-
MVC三层架构
- Model
- 业务处理:业务逻辑(Service层)
- 数据持久层:增删改查CRUD(Dao层)
- View
- 展示数据
- 提供链接发起Servlet请求(a,form,img…)
- Controller(Servlet)
- 接收用户的请求(req:请求参数,Session信息…)
- 交给业务层处理对应的代码
- 控制视图的跳转
- 例:登录—>接受用户的登录请求—>处理用户的请求(获取用户登录的参数,username,password)—>交给业务层处理登录业务(判断用户名密码是否正确)—>Dao层查询用户名和密码是否正确—>数据库
- Model
-
1.11 Filter
- Filter(重点)
- 过滤器,用来过滤网站的数据
- 处理中文乱码
- 登录验证…
- 编写过滤器
-
导包不要错 (implements Filter)(import javax.servlet.*)
-
实现Filter接口,重写对应的方法即可
public class CharacterEncodingFilter implements Filter { // 初始化:web服务器启动,就已经初始化了,随时等待过滤对象的出现 public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化"); } // chain: 链 /* 1. 过滤中的所有代码,在过滤特定请求的时候都会执行 2. 必须要让过滤器继续通行 chain.doFilter(request,response) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); System.out.println("CharacterEncodingFilter执行前...."); chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就会被拦截停止 System.out.println("CharacterEncodingFilter执行后...."); } // 销毁:web服务器关闭的时候,过滤会销毁 public void destroy() { System.out.println("CharacterEncodingFilter销毁"); } }
-
在web.xml中进行配置(与配置Servlet基本相同)
<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_4_0.xsd" version="4.0"> <servlet> <servlet-name>ShowServlet</servlet-name> <servlet-class>com.liu.servlet.ShowServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/servlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/show</url-pattern> </servlet-mapping> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.liu.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <!-- 只要是 /servlet 开始的任何请求,都会经过这个过滤器 --> <url-pattern>/servlet/*</url-pattern> </filter-mapping> </web-app>
-
- 例:登陆验证(用户登录之后才能进入主页,用户注销后就不能进入主页了!)
-
用户登录之后,向Session中放入用户的数据
-
进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!
public class SysFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException {} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; if(request.getSession().getAttribute(Constant.USER_SESSION)==null){ response.sendRedirect("/error.jsp"); } chain.doFilter(req,resp); //这句话是必须的 } public void destroy() {} }
<filter> <filter-name>SysFilter</filter-name> <filter-class>com.liu.filter.SysFilter</filter-class> </filter> <filter-mapping> <filter-name>SysFilter</filter-name> <!-- 只要是 /sys 开始的任何请求,都会经过这个过滤器 --> <url-pattern>/sys/*</url-pattern> </filter-mapping>
- 登陆界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/servlet/login" method="post"> <input type="text" name="username"> <input type="submit"> </form> </body> </html>
- 登陆成功后会向Session中写数据
public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); System.out.println("进来了"); if ("admin".equals(username)){ //登陆成功 req.getSession().setAttribute("USER_SESSION", req.getSession().getId()); resp.sendRedirect("/sys/success.jsp"); }else{ //登陆失败 resp.sendRedirect("/error.jsp"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 由于有过滤器的缘故,因此在未登录成功之前,不可能直接访问到/sys/success.jsp界面
- 登陆界面
-
- 过滤器,用来过滤网站的数据
1.12 监听器
- 监听器
- GUI编程中经常使用
- 编写一个监听器步骤
- 实现监听器的接口
- 在web.xml中注册监听器
1.13 JDBC
- JDBC
-
导入数据库依赖
<!-- 连接数据库 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency>
-
IDEA中连接数据库
- 点击Database->点击加号->Data Source->MySQL->输入密码->在schemas中选择数据库->应用
-
JDBC固定步骤
-
加载驱动
-
连接数据库
-
获取向数据库发送SQL的对象Statement(不安全)
-
编写SQL(根据业务,不同的SQL)
-
执行SQL
-
关闭连接
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 passowrd = "root"; //1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库,代表数据库 Connection connection = DriverManager.getConnection(url, username, passowrd); //3.获取向数据库发送SQL的对象Statement: Statement statement = connection.createStatement(); //4.编写SQL String sql = "select * from users"; //5.执行查询SQL,返回一个ResultSet:结果集;增删改的话为executeUpdate,返回更新的行数 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(); } }
-
-
更安全的步骤(采用PreparedStatement)
-
加载驱动
-
连接数据库
-
编写SQL(根据业务,不同的SQL)
-
PreparedStatement预编译
-
执行SQL
-
关闭连接
public class TestJdbc2 { 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 passowrd = "root"; //1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库,代表数据库 Connection connection = DriverManager.getConnection(url, username, passowrd); //3.编写SQL String sql = "insert into users(id, name, password, email, birthday) values (?,?,?,?,?)"; //4.预编译 PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,4); // 给第一个占位符? 的值赋值为4,下面以此类推 preparedStatement.setString(2,"赵六"); preparedStatement.setString(3,"123456"); preparedStatement.setString(4,"5454455@qq.com"); preparedStatement.setString(5,"2000-01-02"); //5.执行SQL int i = preparedStatement.executeUpdate(); if(i>0){ System.out.println("插入成功!"); } //6.关闭连接,释放资源(一定要做) 先打开的后关 preparedStatement.close(); connection.close(); } }
-
-
事务
- 操作要么全做,要么全部做
- ACID原则:保证数据的安全
- 开启事务
- 事务提交 commit()
- 事务回滚 rollback()
- 关闭事务
-
Junit单元测试
- 依赖
<!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
- 简单使用
@Test方法只有在方法上有效,只要加了这个注解的方法,就可以直接运行!@Test public void test() { System.out.println("Hello"); }
- 依赖
-
事务测试
public class TestJdbc3 { @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 passowrd = "root"; Connection connection=null; //1.加载驱动 try { Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库,代表数据库 connection = DriverManager.getConnection(url, username, passowrd); //3.通知数据库开启事务,false为开启 connection.setAutoCommit(false); String sql = "update account set money=money-100 where name='A'"; connection.prepareStatement(sql).executeUpdate(); String sql2 = "update account set money=money+100 where name='B'"; connection.prepareStatement(sql2).executeUpdate(); //4.提交事务 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(); } } } }
-
1.14 超时订单管理系统SMBMS
- 超时订单管理系统SMBMS
- 项目准备工作
-
搭建一个maven web项目
-
配置Tomcat
-
测试项目是否能够跑起来
-
在pom文件中导入项目中会遇到的jar包:jsp,servlet,mysql驱动,jstl,stand…
<dependencies> <!--servlet与jsp依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> <!--mysql驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.27</version> </dependency> <!--jstl依赖与standard标签库--> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
-
创建项目包结构(com.liu.dao/filter/pojo/service/servlet/util)
-
在pojo中编写实体类:ORM映射:表-类映射
-
编写基础公共类
-
编写数据库配置文件(db.properties)
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?useSSL=true&useUnicode=true&characterEncoding=utf-8 username=root password=root
-
编写数据库的公共类(BaseDao)
package com.liu.dao; 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, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) 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(); return updateRows; } //释放资源 public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){ boolean flag = true; if (resultSet!=null){ try { resultSet.close(); //GC回收 resultSet = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } if (preparedStatement!=null){ try { preparedStatement.close(); //GC回收 preparedStatement = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } if (connection!=null){ try { connection.close(); //GC回收 connection = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } return flag; } }
-
编写字符编码过滤器(CharacterEncodingFilter)
package com.liu.filter; import javax.servlet.*; import java.io.IOException; public class CharaterEncodingFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); chain.doFilter(req,resp); } public void destroy() { } }
-
-
导入静态资源(css,js,html,img)
-
- 登录功能的实现
-
编写登陆界面login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head lang="en"> <meta charset="UTF-8"> <title>系统登录 - 超市订单管理系统</title> <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/style.css" /> <script type="text/javascript"> /* if(top.location!=self.location){ top.location=self.location; } */ </script> </head> <body class="login_bg"> <section class="loginBox"> <header class="loginHeader"> <h1>超市订单管理系统</h1> </header> <section class="loginCont"> <form class="loginForm" action="${pageContext.request.contextPath }/login.do" name="actionForm" id="actionForm" method="post" > <div class="info">${error }</div> <div class="inputbox"> <label >用户名:</label> <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/> </div> <div class="inputbox"> <label >密码:</label> <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/> </div> <div class="subBtn"> <input type="submit" value="登录"/> <input type="reset" value="重置"/> </div> </form> </section> </section> </body> </html>
-
将登录页面设置为首页,在web.xml中加入这段话
<!-- 设置欢迎页面 --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>
-
编写dao层用户登录的接口UserDao
在dao中建立一个user包,在包中建一个UserDao接口,在接口中写package com.liu.dao.user; import com.liu.pojo.User; import java.sql.Connection; import java.sql.SQLException; public interface UserDao { public User getLoginUser(Connection connection, String userCode, String userPassword) throws SQLException; }
-
编写UserDao接口的实现类UserDaoImpl
package com.liu.dao.user; import com.liu.dao.BaseDao; import com.liu.pojo.User; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class UserDaoImpl implements UserDao { //得到要登录的用户 public User getLoginUser(Connection connection, String userCode, String userPassword) 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}; //System.out.println(userPassword); rs = BaseDao.execute(connection,pstm,rs,sql,params); if (rs.next()){ user = new User(); user.setId(rs.getInt("id")); user.setUserCode(rs.getString("userCode")); user.setUserName(rs.getString("userName")); user.setUserPassword(rs.getString("userPassword")); 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("createdBy")); user.setCreationDate(rs.getTimestamp("creationDate")); user.setModifyBy(rs.getInt("modifyBy")); user.setModifyDate(rs.getTimestamp("modifyDate")); } if(!user.getUserPassword().equals(userPassword)) user=null; BaseDao.closeResource(null,pstm,rs); } return user; } }
-
编写业务层接口
在service下建立user包,建立UserService接口package com.liu.service.user; import com.liu.pojo.User; public interface UserService { //用户登录 public User login(String userCode, String password); }
-
编写业务层接口的实现类
在service的user包中建立UserServiceImpl类package com.liu.service.user; import com.liu.dao.BaseDao; import com.liu.dao.user.UserDao; import com.liu.dao.user.UserDaoImpl; import com.liu.pojo.User; import org.junit.Test; import java.sql.Connection; import java.sql.SQLException; public class UserServiceImpl implements UserService { //业务层都会调用dao层,所以我们要引入Dao层; private UserDao userDao; public UserServiceImpl(){ userDao = new UserDaoImpl(); } public User login(String userCode, String password) { Connection connection = null; User user = null; try { connection = BaseDao.getConnection(); //通过业务层调用对应的具体的数据库操作 user = userDao.getLoginUser(connection, userCode,password); } catch (SQLException e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null,null); } return user; } // @Test // public void test(){ // UserServiceImpl userService = new UserServiceImpl(); // User login = userService.login("test", "111"); // System.out.println(login.getUserPassword()); // } }
-
编写Servlet类
在Servlet包中创建user包,在user包中建立LoginServlet类package com.liu.servlet.user; import com.liu.pojo.User; import com.liu.service.user.UserService; import com.liu.service.user.UserServiceImpl; import com.liu.util.Constants; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; 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"); //和数据库中的密码进行对比,调用业务层; UserService userService = new UserServiceImpl(); User user = userService.login(userCode, userPassword); //这里已经把登录的人给查出来了 System.out.println(userCode); System.out.println(userPassword); System.out.println(user.getUserCode()); System.out.println(user.getUserPassword()); if (user!=null){ //查有此人,可以登录 //将用户的信息放到Session中; req.getSession().setAttribute(Constants.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); } }
-
在web.xml中注册当前的Servlet
<!-- 注册登录页面的Servlet--> <servlet> <servlet-name>login</servlet-name> <servlet-class>com.liu.servlet.user.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login.do</url-pattern> </servlet-mapping>
-
- 登录功能的优化
- 注销功能
-
移除session,返回登录页面,servlet.user下创建LogoutServlet类
package com.liu.servlet.user; import com.liu.util.Constants; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class LogoutServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //移除用户的session req.getSession().removeAttribute(Constants.USER_SESSION); //req.getContextPath() 看情况是否加,一般报404就加 resp.sendRedirect(req.getContextPath()+"/login.jsp"); //返回登录页面 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
在web.xml中注册注销servlet
<!-- 注册注销页面 --> <servlet> <servlet-name>LogoutServlet</servlet-name> <servlet-class>com.liu.servlet.user.LogoutServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LogoutServlet</servlet-name> <url-pattern>/jsp/logout.do</url-pattern> </servlet-mapping>
-
- 登录拦截器
-
在filter下创建SysFilter类
package com.liu.filter; import com.liu.pojo.User; import com.liu.util.Constants; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class SysFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //过滤器,从Session中获取用户, User user = (User) request.getSession().getAttribute(Constants.USER_SESSION); if (user==null){ //已经被移除或者注销了,或者未登录 response.sendRedirect("/smbms/error.jsp"); }else { chain.doFilter(req,resp); } } public void destroy() { } }
-
在web.xml中注册
<!-- 登录拦截器 --> <filter> <filter-name>Sysfilter</filter-name> <filter-class>com.liu.filter.SysFilter</filter-class> </filter> <filter-mapping> <filter-name>Sysfilter</filter-name> <url-pattern>/jsp/*</url-pattern> </filter-mapping>
-
- 注销功能
- 密码修改
-
自顶向下设计,自底向上实现
-
为了实现这个功能需要自底向上逐一实现功能,修改密码需要更新数据库的相关行,所以这就需要dao层去进行增删改查操作数据
-
Dao层需要当前的一些信息,比如用户名,当前的密码,要修改的密码,这些就要dao层去从Service层获取这些参数
-
Service需要获取从Servlet层传过来的数据进行相应的处理,验证,核算,然后将最终的信息传递给Dao层
-
而Servlet直接与前端接触,返回当前页面上传递而来的用户输入触发的参数,转发到不同的页面,交给不同的Service来处理这些请求
-
这就意味着先从dao层开始写,分模块,先写接口,再写接口的实现类,依次写service和servlet,最后注册这个servlet,最后测试并完善前端页面
-
编写dao层用户修改密码的接口UserDao
在UserDao的接口下增加updatepwd//修改当前用户密码 //增删改都会影响数据库的变化,所以是返回int类型,说明有几行受到了影响 public int updatePwd(Connection connection,int id,String userPassword)throws SQLException;
-
编写dao层用户修改密码的接口实现方法
在UserDaoImpl下增加//修改当前用户密码 //增删改都会影响数据库的变化,所以是返回int类型,说明有几行受到了影响 public int updatePwd(Connection connection, int id, String userPassword) throws SQLException { int updateRows=0; PreparedStatement pstm = null; if(connection!=null){ String sql="update smbms_user set userPassword=? where id=?"; Object []params={userPassword,id}; updateRows=BaseDao.execute(connection,pstm,sql,params); } BaseDao.closeResource(null,pstm,null); return updateRows; }
-
编写业务层Service的用户修改密码的接口
UserService下增加//根据用户id修改密码 public boolean updatePwd(int id,String password);
-
编写业务层Service的用户修改密码的接口实现方法
UserServiceImpl下增加//根据用户id修改密码 //通过返回的参数flag判断是否修改成功 public boolean updatePwd(int id, String password) { boolean flag = false; Connection connection = null; try{ connection = BaseDao.getConnection(); if(userDao.updatePwd(connection,id,password) > 0) flag = true; }catch (Exception e) { e.printStackTrace(); }finally{ BaseDao.closeResource(connection, null, null); } return flag; }
-
编写修改密码的Servlet类UserServlet
public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //实现Servlet复用,实现复用需要提取出方法,然后在doGet函数中调用即可 String method = req.getParameter("method"); // 获取前端隐藏域中的name if(method.equals("savepwd") && method!=null){ this.updatePwd(req,resp); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } //在doGet外写复用方法 public void updatePwd(HttpServletRequest req, HttpServletResponse resp){ //从session中获得用户id,这里的attribute包括了用户的所用信息 Object attribute = req.getSession().getAttribute(Constants.USER_SESSION); //获得新密码 String newpassword = req.getParameter("newpassword"); boolean flag= false; //判断是否有这个用户是否存在,以及新密码不为空 if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){ UserService userService = new UserServiceImpl(); flag = userService.updatePwd(((User) attribute).getId(), newpassword); if (flag) { req.setAttribute(Constants.SYS_MESSAGE,"修改密码成功,请退出后重新登录"); //密码修改成功后移除当前session req.getSession().removeAttribute(Constants.USER_SESSION); }else{ req.setAttribute(Constants.SYS_MESSAGE,"密码修改失败请重新输入"); } }else{ req.setAttribute(Constants.SYS_MESSAGE,"新密码设置错误请重新输入"); } try { req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
-
在web.xml中注册这个servlet
<!-- 注册UserServlet页面--> <servlet> <servlet-name>UserServlet</servlet-name> <servlet-class>com.liu.servlet.user.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserServlet</servlet-name> <url-pattern>/jsp/user.do</url-pattern> </servlet-mapping>
-
密码修改的前端页面pwdmodify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/jsp/common/head.jsp"%> <div class="right"> <div class="location"> <strong>你现在所在的位置是:</strong> <span>密码修改页面</span> </div> <div class="providerAdd"> <form id="userForm" name="userForm" method="post" action="${pageContext.request.contextPath }/jsp/user.do"> <input type="hidden" name="method" value="savepwd"> <!--div的class 为error是验证错误,ok是验证成功--> <div class="info">${message}</div> <div class=""> <label for="oldPassword">旧密码:</label> <input type="password" name="oldpassword" id="oldpassword" value=""> <font color="red"></font> </div> <div> <label for="newPassword">新密码:</label> <input type="password" name="newpassword" id="newpassword" value=""> <font color="red"></font> </div> <div> <label for="rNewPassword">确认新密码:</label> <input type="password" name="rnewpassword" id="rnewpassword" value=""> <font color="red"></font> </div> <div class="providerAddBtn"> <!--<a href="#">保存</a>--> <input type="button" name="save" id="save" value="保存" class="input-button"> </div> </form> </div> </div> </section> <%@include file="/jsp/common/foot.jsp" %> <script type="text/javascript" src="${pageContext.request.contextPath }/js/pwdmodify.js"></script>
-
- 使用Ajax优化密码修改(前面的修改密码并没有管旧密码是否正确)
-
导入阿里巴巴的json包
<!-- 阿里巴巴的fastjson.jar包 --> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency>
-
编写验证旧密码的servlet类,还是servlet方法复用
else if(method.equals("pwdmodify") && method!=null){//收到前端发来的请求,根据不同的method值来启动不同的方法应对 this.modifyPwd(req,resp); //在下面继续写 //验证旧密码,session中可以获得旧密码,不需要重复去数据库中寻找 public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){ //从session中获得用户的旧密码,这里的attribute包括了用户的所用信息 Object o = req.getSession().getAttribute(Constants.USER_SESSION); //从前端输入的页面中获得输入的旧密码 String oldpassword = req.getParameter("oldpassword"); //万能的Map Map<String, String> resultMap = new HashMap<String,String>(); if (o==null){//取到的session为空,意味着session过期了 resultMap.put("result","sessionerror"); }else if (StringUtils.isNullOrEmpty(oldpassword)){//如果输入的旧密码为空 resultMap.put("result","error"); }else{//session不为空,输入的旧密码也不为空,则取出当前旧密码与之比较 String userPassword = ((User) o).getUserPassword(); if(oldpassword.equals(userPassword)){ resultMap.put("result","true"); }else { resultMap.put("result","false"); } } try { // 将返回值的格式设置为json格式 resp.setContentType("application/json"); PrintWriter out = resp.getWriter(); // 将map中的值,转换到json,并传回去 out.write(JSONArray.toJSONString(resultMap)); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } }
-
前端js代码为pwdmodify.js
var oldpassword = null; var newpassword = null; var rnewpassword = null; var saveBtn = null; $(function(){ oldpassword = $("#oldpassword"); newpassword = $("#newpassword"); rnewpassword = $("#rnewpassword"); saveBtn = $("#save"); oldpassword.next().html("*"); newpassword.next().html("*"); rnewpassword.next().html("*"); oldpassword.on("blur",function(){//JQuery失去焦点 $.ajax({ type:"GET", url:path+"/jsp/user.do", data:{method:"pwdmodify",oldpassword:oldpassword.val()},//data就是ajax传递的参数 /* 上面这句话等价于path+"/jsp/user.do?method="pwdmodify"&&oldpassword=oldpassword.val() */ dataType:"json",//主流开发都是用JSON实现前后端开发{} success:function(data){ if(data.result == "true"){//旧密码正确 validateTip(oldpassword.next(),{"color":"green"},imgYes,true); }else if(data.result == "false"){//旧密码输入不正确 validateTip(oldpassword.next(),{"color":"red"},imgNo + " 原密码输入不正确",false); }else if(data.result == "sessionerror"){//当前用户session过期,请重新登录 validateTip(oldpassword.next(),{"color":"red"},imgNo + " 当前用户session过期,请重新登录",false); }else if(data.result == "error"){//旧密码输入为空 validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请输入旧密码",false); } }, error:function(data){ //请求出错 validateTip(oldpassword.next(),{"color":"red"},imgNo + " 请求错误",false); } }); }).on("focus",function(){ validateTip(oldpassword.next(),{"color":"#666666"},"* 请输入原密码",false); }); newpassword.on("focus",function(){ validateTip(newpassword.next(),{"color":"#666666"},"* 密码长度必须是大于6小于20",false); }).on("blur",function(){ if(newpassword.val() != null && newpassword.val().length > 6 && newpassword.val().length < 20 ){ validateTip(newpassword.next(),{"color":"green"},imgYes,true); }else{ validateTip(newpassword.next(),{"color":"red"},imgNo + " 密码输入不符合规范,请重新输入",false); } }); rnewpassword.on("focus",function(){ validateTip(rnewpassword.next(),{"color":"#666666"},"* 请输入与上面一致的密码",false); }).on("blur",function(){ if(rnewpassword.val() != null && rnewpassword.val().length > 6 && rnewpassword.val().length < 20 && newpassword.val() == rnewpassword.val()){ validateTip(rnewpassword.next(),{"color":"green"},imgYes,true); }else{ validateTip(rnewpassword.next(),{"color":"red"},imgNo + " 两次密码输入不一致,请重新输入",false); } }); saveBtn.on("click",function(){ oldpassword.blur(); newpassword.blur(); rnewpassword.blur(); if(oldpassword.attr("validateStatus") == "true" &&newpassword.attr("validateStatus") == "true" && rnewpassword.attr("validateStatus") == "true"){ if(confirm("确定要修改密码?")){ $("#userForm").submit(); } } }); }); ```
-
- 项目准备工作
- 用户管理模块的实现
流程图
用户列表:根据搜索框和下拉框查询到的列表
角色列表:下拉框展示的可以勾选的列表(系统管理员,经历,普通员工)
分页:对查询到的用户列表分页-
按照自底向上的流程,编写顺序
- Dao
- DaoImpl
- Service
- ServiceImpl
- Servlet
-
编写分页要用到的工具类
package com.liu.util; public class PageSupport { //当前页码-来自于用户输入 private int currentPageNo = 1; //总数量(表) private int totalCount = 0; //页面容量 private int pageSize = 0; //总页数- totalCount/pageSize(+1) private int totalPageCount = 1; public int getCurrentPageNo() { return currentPageNo; } public void setCurrentPageNo(int currentPageNo) { if(currentPageNo > 0){ this.currentPageNo = currentPageNo; } } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { if(totalCount > 0){ this.totalCount = totalCount; //设置总页数 this.setTotalPageCountByRs(); } } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { if(pageSize > 0){ this.pageSize = pageSize; } } public int getTotalPageCount() { return totalPageCount; } public void setTotalPageCount(int totalPageCount) { this.totalPageCount = totalPageCount; } public void setTotalPageCountByRs(){ if(this.totalCount % this.pageSize == 0){ this.totalPageCount = this.totalCount / this.pageSize; }else if(this.totalCount % this.pageSize > 0){ this.totalPageCount = this.totalCount / this.pageSize + 1; }else{ this.totalPageCount = 0; } } }
-
获取用户的数量
-
首先是UserDao接口添加一个函数
-
然后UserDaoImpl里实现上面接口里新增的函数
//根据用户输入的名字或者角色id来查询计算用户数量 public int getUserCount(Connection connection, String userName, int userRole) throws Exception { int count=0; PreparedStatement pstm = null; ResultSet rs=null; if (connection!=null) { StringBuffer sql=new StringBuffer(); sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole=r.id"); ArrayList<Object> list = new ArrayList<Object>();//存放可能会放进sql里的参数,就是用来替代?的params 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("当前的sql语句为------------>"+sql); //输出最后完整的sql语句 rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params); if(rs.next()){ count=rs.getInt("count"); // 从结果集中获取最终的数量 } BaseDao.closeResource(null,pstm,rs); } return count; }
-
继续在UserService接口里面增加一个新的函数
-
接口里新增后,在UserServiceImpl实现这个方法
//根据条件(用户的查询输入)查询用户记录数 public int getUserCount(String queryUserName, int queryUserRole) { int count=0; Connection connection=null; try { connection = BaseDao.getConnection(); count = userDao.getUserCount(connection, queryUserName, queryUserRole); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection, null, null); } return count; }
-
-
根据输入的条件获取当前的用户列表
-
首先是UserDao接口添加一个函数
-
然后UserDaoImpl里实现上面接口里新增的函数
//通过用户输入的条件查询用户列表 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); } //实现分页显示 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, pstm, rs, sql.toString(), params); 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, pstm, rs); } return userList; }
-
继续在UserService接口里面增加一个新的函数
-
接口里新增后,在UserServiceImpl实现这个方法
//根据条件查询用户列表 public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) { // TODO Auto-generated method stub Connection connection = null; List<User> userList = null; 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; }
-
-
获取角色列表
-
首先在dao层新建role目录,下面新建RoleDao接口
-
然后在dao层role目录下新建RoleDaoImpl实现接口
public List<Role> getRoleList(Connection connection) throws Exception { PreparedStatement pstm=null; ResultSet rs=null; List<Role> roleList = new ArrayList<Role>(); if(connection!=null){ String sql="select * from smbms_role"; Object[] params={}; rs = BaseDao.execute(connection, pstm, rs, sql, params); while(rs.next()){ Role role = new Role(); role.setId(rs.getInt("id")); role.setRoleCode(rs.getString("roleCode")); role.setRoleName(rs.getString("roleName")); roleList.add(role); } } BaseDao.closeResource(null,pstm,rs); return roleList; }
-
在service层新建role目录,新建RoleService接口
-
在service层role目录下,新建RoleServiceImlp接口实现
public List<Role> getRoleList() { Connection connection=null; List<Role> roleList=null; try { connection= BaseDao.getConnection(); roleList = roleDao.getRoleList(connection); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null,null); } return roleList; }
-
-
用户管理query模块的Servlet编写
else if (method.equals("query") && method!=null){ // 用户查询 this.query(req,resp); } //用户管理模块页面查询 //怎么处理 public void query(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ //接收前端传来的参数 String queryUserName = req.getParameter("queryname"); String temp = req.getParameter("queryUserRole"); //从前端传回来的用户角色码不知是否为空或者是有效角色码,所以暂存起来 String pageIndex = req.getParameter("pageIndex"); int queryUserRole=0; //通过UserServiceImpl得到用户列表,用户数 UserServiceImpl userService = new UserServiceImpl(); //通过RoleServiceImpl得到角色表 RoleService roleService = new RoleServiceImpl(); List<User> userList=null;//用来存储查询到的用户列表 List<Role> roleList=null;//用来存储角色列表 //设置每页显示的页面容量 int pageSize=Constants.pageSize; //设置当前的默认页码 int currentPageNo=1; //前端传来的参数若不符合查询sql语句,即如果用户不进行设置,值为空会影响sql查询,需要给它们进行一些约束 if(queryUserName==null){ //这里为空,说明用户没有输入要查询的用户名,则sql语句传值为"",%%,会查询所有记录 queryUserName=""; } if(temp!=null && !temp.equals("")){ //不为空,说明前端有传来的用户所设置的userCode,更新真正的角色码 queryUserRole=Integer.parseInt(temp);//强制转换,前端传递的参数都是默认字符串,要转成int类型 } if(pageIndex!=null){//说明当前用户设置了要跳转的页码 currentPageNo=Integer.valueOf(pageIndex); } //有了用户名和用户角色后可以开始查询了,所以需要显示当前查询到的总记录条数 int totalCount = userService.getUserCount(queryUserName, queryUserRole); //根据总记录条数以及当前每页的页面容量可以算出,一共有几页,以及最后一页的显示条数 PageSupport pageSupport = new PageSupport(); pageSupport.setCurrentPageNo(currentPageNo); pageSupport.setPageSize(pageSize); //设置一下每页的条目个数 pageSupport.setTotalCount(totalCount); //设置一下条目总数 //获取可显示的总页数 int totalPageCount=pageSupport.getTotalPageCount(); //约束首位页,即防止用户输入的页面索引小于1或者大于总页数 if(currentPageNo<1){ currentPageNo=1; }else if(currentPageNo>totalPageCount){ currentPageNo=totalPageCount; } //有了,待查询条件,当前页码,以及每页的页面容量后,就可以给出每页的具体显示情况了 userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize); roleList = roleService.getRoleList(); //得到了用户表与角色表以及各种经过处理后的参数,都存进req中 req.setAttribute("userList",userList); req.setAttribute("roleList",roleList); req.setAttribute("queryUserName", queryUserName); req.setAttribute("queryUserRole", queryUserRole); req.setAttribute("totalPageCount", totalPageCount); req.setAttribute("totalCount", totalCount); req.setAttribute("currentPageNo", currentPageNo); //将所得到的的所有req参数送回给前端 req.getRequestDispatcher("userlist.jsp").forward(req,resp); }
-
用户管理模块的增删改查
-
Dao
//增加用户信息 public int add(Connection connection,User user) throws Exception; //通过用户id删除用户信息 public int deleteUserById(Connection connection, Integer delId)throws Exception; //通过userId查看当前用户信息 public User getUserById(Connection connection, String id)throws Exception; //修改用户信息 public int modify(Connection connection, User user)throws Exception;
-
DaoImpl
//增加用户信息 public int add(Connection connection, User user) throws Exception { PreparedStatement pstm=null; int updateNum=0; if(connection!=null) { String sql = "insert into smbms_user (userCode,userName,userPassword," + "userRole,gender,birthday,phone,address,creationDate,createdBy) " + "values(?,?,?,?,?,?,?,?,?,?)"; Object[] params = {user.getUserCode(), user.getUserName(), user.getUserPassword(), user.getUserRole(), user.getGender(), user.getBirthday(), user.getPhone(), user.getAddress(), user.getCreationDate(), user.getCreatedBy()}; updateNum = BaseDao.execute(connection, pstm, sql, params); BaseDao.closeResource(null, pstm, null); } return updateNum; } //根据用户id删除该用户 public int deleteUserById(Connection connection, Integer delId) throws Exception { PreparedStatement pstm=null; int deleteNum=0; if(connection!=null){ String sql="delete from smbms_user where id=?"; Object[] params={delId}; deleteNum=BaseDao.execute(connection, pstm, sql, params); BaseDao.closeResource(null, pstm,null); } return deleteNum; } //通过userId查看当前用户信息 public User getUserById(Connection connection, String id) throws Exception { PreparedStatement pstm=null; ResultSet rs=null; User user = new User(); if(connection!=null){ String sql="select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.id=? and u.userRole = r.id"; Object[] params={id}; rs = BaseDao.execute(connection, pstm, rs, sql, params); while(rs.next()){ user.setId(rs.getInt("id")); user.setUserCode(rs.getString("userCode")); user.setUserName(rs.getString("userName")); user.setUserPassword(rs.getString("userPassword")); 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("createdBy")); user.setCreationDate(rs.getTimestamp("creationDate")); user.setModifyBy(rs.getInt("modifyBy")); user.setModifyDate(rs.getTimestamp("modifyDate")); user.setUserRoleName(rs.getString("userRoleName")); } BaseDao.closeResource(null,pstm,rs); } return user; } //修改用户的信息 public int modify(Connection connection, User user) throws Exception { int updateNum = 0; PreparedStatement pstm = null; if(null != connection){ String sql = "update smbms_user set userName=?,"+ "gender=?,birthday=?,phone=?,address=?,userRole=?,modifyBy=?,modifyDate=? where id = ? "; Object[] params = {user.getUserName(),user.getGender(),user.getBirthday(), user.getPhone(),user.getAddress(),user.getUserRole(),user.getModifyBy(), user.getModifyDate(),user.getId()}; updateNum = BaseDao.execute(connection, pstm, sql, params); BaseDao.closeResource(null, pstm, null); } return updateNum; }
-
Service
//增加用户 public boolean add(User user); //修改用户信息 public boolean modify(User user) throws Exception; //根据用户id删除用户 public boolean deleteUserById(Integer delId); //根据用户id得到当前用户 public User getUserById(String id); //根据用户编码,判断用户是否存在 public User selectUserCodeExist(String userCode, String userPassword);
-
ServiceImpl
//增加用户 public boolean add(User user) { boolean flag = false; Connection connection = null; try { connection = BaseDao.getConnection();//获得连接 connection.setAutoCommit(false);//开启JDBC事务管理 int updateRows = userDao.add(connection,user); connection.commit(); if(updateRows > 0){ flag = true; System.out.println("add success!"); }else{ System.out.println("add failed!"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); try { System.out.println("rollback=================="); connection.rollback();//失败就回滚 } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } }finally{ //在service层进行connection连接的关闭 BaseDao.closeResource(connection, null, null); } return flag; } //修改用户信息 public boolean modify(User user) { Boolean flag=false; Connection connection=null; try { connection=BaseDao.getConnection(); connection.setAutoCommit(false);//开启JDBC事务 int updateNum = userDao.modify(connection, user);//执行修改sql connection.commit();//提交事务 if(updateNum>0){ flag=true; System.out.println("修改用户成功"); }else{ System.out.println("修改用户失败"); } } catch (Exception e) { e.printStackTrace(); //若抛出异常,则说明修改失败需要回滚 System.out.println("修改失败,回滚事务"); try { connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } }finally { BaseDao.closeResource(connection,null,null); } return flag; } public boolean deleteUserById(Integer delId) { Boolean flag=false; Connection connection=null; connection=BaseDao.getConnection(); try { int deleteNum=userDao.deleteUserById(connection,delId); if(deleteNum>0)flag=true; } catch (Exception e) { }finally { BaseDao.closeResource(connection,null,null); } return flag; } public User getUserById(String id) { User user = new User(); Connection connection=null; try { connection=BaseDao.getConnection(); user = userDao.getUserById(connection,id); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null,null); } return user; } public User selectUserCodeExist(String userCode, String userPassword) { Connection connection = null; User user = null; try { connection = BaseDao.getConnection(); user = userDao.getLoginUser(connection, userCode, userPassword); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ BaseDao.closeResource(connection, null, null); } return user; }
-
增删改查Servlet(放个总的)
public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //实现Servlet复用,实现复用需要提取出方法,然后在doGet函数中调用即可 String method = req.getParameter("method"); // 获取前端隐藏域中的name if(method.equals("savepwd") && method!=null){ this.updatePwd(req,resp); }else if(method.equals("pwdmodify") && method!=null){//收到前端发来的请求,根据不同的method值来启动不同的方法应对 this.modifyPwd(req,resp); }else if (method.equals("query") && method!=null){ // 用户查询 this.query(req,resp); }else if(method != null && method.equals("add")){//增加操作 this.add(req, resp); }else if(method != null && method.equals("deluser")){//删除用户 this.delUser(req, resp); }else if(method != null && method.equals("modify")){ //通过用户id得到该用户,并跳转到用户修改界面显示该用户信息 this.getUserById(req, resp,"usermodify.jsp"); }else if(method != null && method.equals("modifyexe")){ //验证用户,判断是否修改成功 this.modify(req, resp); }else if(method != null && method.equals("view")){ //通过用户id得到该用户,并跳转到用户展示界面展示该用户信息 this.getUserById(req, resp,"userview.jsp"); }else if(method != null && method.equals("getrolelist")){ //查询用户角色表 this.getRoleList(req, resp); }else if(method != null && method.equals("ucexist")){ //查询当前用户编码是否已经存在,若已存在则不能add this.userCodeExist(req, resp); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } //在doGet外写复用方法 public void updatePwd(HttpServletRequest req, HttpServletResponse resp){ //从session中获得用户id,这里的attribute包括了用户的所用信息 Object attribute = req.getSession().getAttribute(Constants.USER_SESSION); //获得新密码 String newpassword = req.getParameter("newpassword"); boolean flag= false; //判断是否有这个用户是否存在,以及新密码不为空 if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){ UserService userService = new UserServiceImpl(); flag = userService.updatePwd(((User) attribute).getId(), newpassword); if (flag) { req.setAttribute(Constants.SYS_MESSAGE,"修改密码成功,请退出后重新登录"); //密码修改成功后移除当前session req.getSession().removeAttribute(Constants.USER_SESSION); }else{ req.setAttribute(Constants.SYS_MESSAGE,"密码修改失败请重新输入"); } }else{ req.setAttribute(Constants.SYS_MESSAGE,"新密码设置错误请重新输入"); } try { req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //在下面继续写 //验证旧密码,session中可以获得旧密码,不需要重复去数据库中寻找 public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){ //从session中获得用户的旧密码,这里的attribute包括了用户的所用信息 Object o = req.getSession().getAttribute(Constants.USER_SESSION); //从前端输入的页面中获得输入的旧密码 String oldpassword = req.getParameter("oldpassword"); //万能的Map Map<String, String> resultMap = new HashMap<String,String>(); if (o==null){//取到的session为空,意味着session过期了 resultMap.put("result","sessionerror"); }else if (StringUtils.isNullOrEmpty(oldpassword)){//如果输入的旧密码为空 resultMap.put("result","error"); }else{//session不为空,输入的旧密码也不为空,则取出当前旧密码与之比较 String userPassword = ((User) o).getUserPassword(); if(oldpassword.equals(userPassword)){ resultMap.put("result","true"); }else { resultMap.put("result","false"); } } try { // 将返回值的格式设置为json格式 resp.setContentType("application/json"); PrintWriter out = resp.getWriter(); // 将map中的值,转换到json,并传回去 out.write(JSONArray.toJSONString(resultMap)); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } //用户管理模块页面查询 //怎么处理 public void query(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ //接收前端传来的参数 String queryUserName = req.getParameter("queryname"); String temp = req.getParameter("queryUserRole"); //从前端传回来的用户角色码不知是否为空或者是有效角色码,所以暂存起来 String pageIndex = req.getParameter("pageIndex"); int queryUserRole=0; //通过UserServiceImpl得到用户列表,用户数 UserServiceImpl userService = new UserServiceImpl(); //通过RoleServiceImpl得到角色表 RoleService roleService = new RoleServiceImpl(); List<User> userList=null;//用来存储查询到的用户列表 List<Role> roleList=null;//用来存储角色列表 //设置每页显示的页面容量 int pageSize=Constants.pageSize; //设置当前的默认页码 int currentPageNo=1; //前端传来的参数若不符合查询sql语句,即如果用户不进行设置,值为空会影响sql查询,需要给它们进行一些约束 if(queryUserName==null){ //这里为空,说明用户没有输入要查询的用户名,则sql语句传值为"",%%,会查询所有记录 queryUserName=""; } if(temp!=null && !temp.equals("")){ //不为空,说明前端有传来的用户所设置的userCode,更新真正的角色码 queryUserRole=Integer.parseInt(temp);//强制转换,前端传递的参数都是默认字符串,要转成int类型 } if(pageIndex!=null){//说明当前用户设置了要跳转的页码 currentPageNo=Integer.valueOf(pageIndex); } //有了用户名和用户角色后可以开始查询了,所以需要显示当前查询到的总记录条数 int totalCount = userService.getUserCount(queryUserName, queryUserRole); //根据总记录条数以及当前每页的页面容量可以算出,一共有几页,以及最后一页的显示条数 PageSupport pageSupport = new PageSupport(); pageSupport.setCurrentPageNo(currentPageNo); pageSupport.setPageSize(pageSize); //设置一下每页的条目个数 pageSupport.setTotalCount(totalCount); //设置一下条目总数 //获取可显示的总页数 int totalPageCount=pageSupport.getTotalPageCount(); //约束首位页,即防止用户输入的页面索引小于1或者大于总页数 if(currentPageNo<1){ currentPageNo=1; }else if(currentPageNo>totalPageCount){ currentPageNo=totalPageCount; } //有了,待查询条件,当前页码,以及每页的页面容量后,就可以给出每页的具体显示情况了 userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize); roleList = roleService.getRoleList(); //得到了用户表与角色表以及各种经过处理后的参数,都存进req中 req.setAttribute("userList",userList); req.setAttribute("roleList",roleList); req.setAttribute("queryUserName", queryUserName); req.setAttribute("queryUserRole", queryUserRole); req.setAttribute("totalPageCount", totalPageCount); req.setAttribute("totalCount", totalCount); req.setAttribute("currentPageNo", currentPageNo); //将所得到的的所有req参数送回给前端 req.getRequestDispatcher("userlist.jsp").forward(req,resp); } //增加用户 private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("当前正在执行增加用户操作"); //从前端得到页面的请求的参数即用户输入的值 String userCode = req.getParameter("userCode"); String userName = req.getParameter("userName"); String userPassword = req.getParameter("userPassword"); //String ruserPassword = req.getParameter("ruserPassword"); String gender = req.getParameter("gender"); String birthday = req.getParameter("birthday"); String phone = req.getParameter("phone"); String address = req.getParameter("address"); String userRole = req.getParameter("userRole"); //把这些值塞进一个用户属性中 User user = new User(); user.setUserCode(userCode); user.setUserName(userName); user.setUserPassword(userPassword); user.setAddress(address); user.setGender(Integer.valueOf(gender)); user.setPhone(phone); try { user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday)); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } user.setUserRole(Integer.valueOf(userRole)); user.setCreationDate(new Date()); //查找当前正在登陆的用户的id user.setCreatedBy(((User)req.getSession().getAttribute(Constants.USER_SESSION)).getId()); UserServiceImpl userService = new UserServiceImpl(); Boolean flag = userService.add(user); //如果添加成功,则页面转发,否则重新刷新,再次跳转到当前页面 if(flag){ resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query"); }else{ req.getRequestDispatcher("useradd.jsp").forward(req,resp); } } //删除用户,需要当前的Id,来找到这个用户然后删除 private void delUser(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ String id = req.getParameter("uid"); Integer delId = 0; try{ delId = Integer.parseInt(id); }catch (Exception e) { // TODO: handle exception delId = 0; } //需要判断是否能删除成功 HashMap<String, String> resultMap = new HashMap<String, String>(); if(delId <= 0){ resultMap.put("delResult", "notexist"); }else{ UserService userService = new UserServiceImpl(); if(userService.deleteUserById(delId)){ resultMap.put("delResult", "true"); }else{ resultMap.put("delResult", "false"); } } //把resultMap转换成json对象输出 resp.setContentType("application/json"); PrintWriter outPrintWriter = resp.getWriter(); outPrintWriter.write(JSONArray.toJSONString(resultMap)); outPrintWriter.flush(); outPrintWriter.close(); } //通过id得到用户信息 private void getUserById(HttpServletRequest req, HttpServletResponse resp,String url) throws ServletException, IOException{ String id = req.getParameter("uid"); if(!StringUtils.isNullOrEmpty(id)){ //调用后台方法得到user对象 UserService userService = new UserServiceImpl(); User user = userService.getUserById(id); req.setAttribute("user", user); req.getRequestDispatcher(url).forward(req, resp); } } //修改用户信息 private void modify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ //需要拿到前端传递进来的参数 String id = req.getParameter("uid");; String userName = req.getParameter("userName"); String gender = req.getParameter("gender"); String birthday = req.getParameter("birthday"); String phone = req.getParameter("phone"); String address = req.getParameter("address"); String userRole = req.getParameter("userRole"); //创建一个user对象接收这些参数 User user = new User(); user.setId(Integer.valueOf(id)); user.setUserName(userName); user.setGender(Integer.valueOf(gender)); try { user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday)); } catch (ParseException e) { e.printStackTrace(); } user.setPhone(phone); user.setAddress(address); user.setUserRole(Integer.valueOf(userRole)); user.setModifyBy(((User)req.getSession().getAttribute(Constants.USER_SESSION)).getId()); user.setModifyDate(new Date()); //调用service层 UserServiceImpl userService = new UserServiceImpl(); Boolean flag = userService.modify(user); //判断是否修改成功来决定跳转到哪个页面 if(flag){ resp.sendRedirect(req.getContextPath()+"/jsp/user.do?method=query"); }else{ req.getRequestDispatcher("usermodify.jsp").forward(req, resp); } } //得到用户角色表 private void getRoleList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ List<Role> roleList = null; RoleService roleService = new RoleServiceImpl(); roleList = roleService.getRoleList(); //把roleList转换成json对象输出 resp.setContentType("application/json"); PrintWriter outPrintWriter = resp.getWriter(); outPrintWriter.write(JSONArray.toJSONString(roleList)); outPrintWriter.flush(); outPrintWriter.close(); } //增加用户时,判断当前输入用户编码是否可用,即是否与已经存在的编码发生冲突 private void userCodeExist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ //先拿到用户的编码 String userCode = req.getParameter("userCode"); String userPassword = req.getParameter("userPassword"); //用一个hashmap,暂存现在所有现存的用户编码 HashMap<String, String> resultMap = new HashMap<String, String>(); if(StringUtils.isNullOrEmpty(userCode)){ //userCode == null || userCode.equals("") //如果输入的这个编码为空或者不存在,说明可用 resultMap.put("userCode", "exist"); }else{//如果输入的编码不为空,则需要去找一下是否存在这个用户 UserService userService = new UserServiceImpl(); User user = userService.selectUserCodeExist(userCode, userPassword); if(null != user){ resultMap.put("userCode","exist"); }else{ resultMap.put("userCode", "notexist"); } } //把resultMap转为json字符串以json的形式输出 //配置上下文的输出类型 resp.setContentType("application/json"); //从response对象中获取往外输出的writer对象 PrintWriter outPrintWriter = resp.getWriter(); //把resultMap转为json字符串 输出 outPrintWriter.write(JSONArray.toJSONString(resultMap)); outPrintWriter.flush();//刷新 outPrintWriter.close();//关闭流 } }
-
-