JavaWeb-2

学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV12J411M7Sj

学习资料笔记:CSDN – https://blog.csdn.net/DDDDeng_/article/details/106826674

JavaWeb:网页编程 B/S

  • B/S即浏览器/服务器(browser/server),不需要安装客户端,采用浏览器浏览就可以了,指的是软件系统的结构.

网络编程:TCP/IP C/S

  • C/S 指的就是 客户端/服务器 Client/server

web开发:

  • web,网页的意思。例如 www.baidu.com
  • 静态web
    • html, css
    • 提供给所有人看的, 这个数据始终不会发生变化
  • 动态Web
    • 几乎是所有的网站。比如淘宝
    • 提供给所有人看到数据始终会发生变化。 每个人在不同的事件,不同的地点看到的信息各不相同。从服务端获取数据Web界面因人而变
    • 技术栈:Servlet / JSP, ASP, PHP

在Java中,动态web资源开发的技术统称为 JavaWeb。

1、Cookie、Session

Cookie: 曲奇饼干

session:会话

1.1、会话

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

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过

那么对于一个网站而言,如何证明你来过呢 ?下面是两种方式:

客户端、服务端:

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

意思就相当于:

  1. 服务端给客户端开了一个证明,下次你拿着证明来,就可以报道,即cookie
  2. 服务端自己进行登记了,下次你来,服务端自己在登记表里面找你的信息,找到了就让你进去。session。

1.2、保存会话的两种技术

cookie

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

session

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

常见问题:

网站登录之后,下次不用再登录了,第二次就直接上去了。 这就是客户端和服务端成功的进行了匹配, 把曾经两个人之间的交易记录(存放在 cookie / session)拿出来能够成功比对。

查看一下Cookie类:都是一些 get 和 set 的方法用来存放和获取数据的

1.3、Cookie 客户端技术

Cookie: 服务端给访问的客户端开了一个证明/信件, 下一次 客户端拿着信件/证明来, 就能直接进去服务端。

客户端技术的例子

cookie

  1. 创建一个Servlet程序,CookieDemo01:服务器先请求客户端,得到其cookie信息。然后服务器响应客户端,生成一个cookie。

    • 在这里,我们试图去保存一个 cookie信息是用户上次访问的时间信息
    • 注意:这个Cookie 是 客户端的,在客户端的手里,客户端拿着证明去 将访问进入服务端。 所以,应该是 服务端从客户端 获取 cookie。
    • 我们可以去设置cookie的存活时间 有效时间。
    package com.AL.servlet;import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.URLEncoder;
    import java.util.Date;// 保存用户上一次访问的时间
    public class CookieDemo01 extends HttpServlet {@Overrideprotected 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,服务器从客户端获取,查看你的发票. 查看你啥时来的,是不是这个班的人Cookie[] cookies = req.getCookies();  //返回的是数组,表明cookie可能存在多个// 判断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("This is you first time");}// 服务器给客户端响应一个cookieCookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");// cookie有效期设置为1天.  以秒为单位cookie.setMaxAge(24*60*60);resp.setCharacterEncoding("utf-8");resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
    }
    
  2. web.xml配置文件。进行注册Servlet 和 Servlet的路径映射。

    <?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_4_0.xsd"version="4.0"><servlet><servlet-name>CookieDemo01</servlet-name><servlet-class>com.AL.servlet.CookieDemo01</servlet-class></servlet><servlet-mapping><servlet-name>CookieDemo01</servlet-name><url-pattern>/c1</url-pattern></servlet-mapping></web-app>
    
  3. 启动Tomcat,进行测试。输入 localhost:8080/c1,结果为:

删除cookie:

1.创建一个cookie,且名字必须和要删除的名字一样:

package com.AL.servlet;import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class CookieDemo02 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 创建一个cookie. 名字必须要和删除的目标cookie一样Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");// 将cookie有效期设置为0, 立马失效cookie.setMaxAge(0);resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}

2.配置文件web.xml:

  <servlet><servlet-name>CookieDemo02</servlet-name><servlet-class>com.AL.servlet.CookieDemo02</servlet-class></servlet><servlet-mapping><servlet-name>CookieDemo02</servlet-name><url-pattern>/c2</url-pattern></servlet-mapping>

3.启动Tomcat,进行测试。 localhost:8080/c2, 结果显示 cookie立马失效。

小结:

cookie

  1. 服务器先向客户端请求,去获取cookie信息。请求中拿到cookie信息。想要得到你的发票,如果你有发票,则将发票展示出来;没有,则给你一个新的发票。
  2. 服务器请求完之后,开始响应给客户端cookie。将得到的信息去生成一个cookie,进行展示,表明你是新来的还是 已经来过。

在这个实现cookie中使用的函数有:

Cookie[] cookies=req.getCookiles();//获得cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie中的value
new Cookie("lastLoginTime",System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie

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

一个网站cookie是否存在上限?

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

删除cookie

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

一关闭浏览器,cookie就自动失效了

中文数据传递

  1. 创建一个cookie:

    package com.AL.servlet;import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.util.Date;public class CookieDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html; charset=utf-8");//服务器告诉你, 你来的时间.把这个时间封装成一个发票,你下次带着发票来,我就知道是你来了// Cookie,服务器从客户端获取,查看你的发票. 查看你啥时来的,是不是这个班的人Cookie[] cookies = req.getCookies();  //返回的是数组,表明cookie可能存在多个PrintWriter out = resp.getWriter();// 判断cookie是否存在if (cookies!=null){// 当存在时的输出out.write("你上一次访问的时间是:");//out.write("you last time is:");for (int i = 0; i < cookies.length; i++) {Cookie cookie = cookies[i];//获取cookie的名字if (cookie.getName().equals("name")){// 获取cookie的值//out.write(cookie.getValue());out.write(URLDecoder.decode(cookie.getValue(),"UTF-8")); // 解码}}}else {out.write("这是你第一次访问本站");}// 服务器给客户端响应一个cookie.   编码: URLEncoder.encode()Cookie cookie = new Cookie("name", URLEncoder.encode("坤坤","utf-8"));// cookie有效期设置为1天.  以秒为单位cookie.setMaxAge(24*60*60);resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
    }
    
  2. web.xml配置文件。发布Servlet程序。

      <servlet><servlet-name>CookieDemo03</servlet-name><servlet-class>com.AL.servlet.CookieDemo03</servlet-class></servlet><servlet-mapping><servlet-name>CookieDemo03</servlet-name><url-pattern>/c3</url-pattern></servlet-mapping>
    
  3. 处理请求参数传递编码问题: 使用编码和解码的方式,使中文不产生乱码。

    • java中编码:URLEncoder.encode(strUri, “UTF-8”);
    • java中解码:URLDecoder.decode(strUri, “UTF-8”);

1.4、Session(重点)

什么是Session

  • 服务器会给每一个用户(浏览器)创建一个Session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登陆之后,整个网站它都可以访问!–>保存用户的信息;保存购物车的信息

Session和cookie的区别

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
  • Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
  • session由服务器创建,且保存在服务器中。

Session使用场景

  • 保存一个登陆用户的信息;

  • 购物车信息;

  • 在整个网站中经常会使用的数据,我们将它保存在session中

创建一个Session程序

  • 创建一个session程序。session对象中去存储一个字符串 name

    • 每个客户端的sessionID是唯一的
package com.AL.servlet;import com.AL.pojo.Person;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;// session。 存放一个字符串
public class SessionDemo01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决乱码问题req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html; charset=utf-8"); // 使文档可以访问,还有编码//得到一个sessionHttpSession session = req.getSession();// 给session中存放东西。 服务器对客户进行登记//session.setAttribute("name", new Person("鑫仔",1));session.setAttribute("name", "鑫仔");// 获取session的ID。  且每个客户端的sessionID是唯一的String sessionId = session.getId();//判断Session是否是新建的if (session.isNew()){resp.getWriter().write("Session创建成功,ID为"+sessionId);}else {resp.getWriter().write("session已经在服务器中创建了,ID为"+sessionId);}//Session创建的时候做了什么事情
//        Cookie cookie = new Cookie("JSESSIONID", sessionId);
//        resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}
  • 配置 web.xml文件。 注册servlet和servlet的映射路径。
  <servlet><servlet-name>SessionDemo01</servlet-name><servlet-class>com.AL.servlet.SessionDemo01</servlet-class></servlet><servlet-mapping><servlet-name>SessionDemo01</servlet-name><url-pattern>/s1</url-pattern></servlet-mapping>
  • 启动Tomcat,进行测试。localhost:8080/s1, 结果为:

获取Session的程序

1.创建一个获取Session的session程序:

package com.AL.servlet;import com.AL.pojo.Person;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;public class SessionDemo02 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决乱码问题req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html; charset=utf-8"); // 使文档可以访问,还有编码//得到一个sessionHttpSession session = req.getSession();//        Person person = (Person) session.getAttribute("name");
//        System.out.println(person.toString());String name = (String) session.getAttribute("name");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}

2.配置 web.xml文件。 这个相当于web容器,发布 Servlet程序。

  <servlet><servlet-name>SessionDemo02</servlet-name><servlet-class>com.AL.servlet.SessionDemo02</servlet-class></servlet><servlet-mapping><servlet-name>SessionDemo02</servlet-name><url-pattern>/s2</url-pattern></servlet-mapping>

3.启动Tomcat,进行测试: localhost:8080/s2。在java控制台可以得到输出。

Session存储一个类

创建一个Person类,建立 name,age 这个属性。session不仅可以存储字符串,也能去存储一个类

1.创建一个Person类: 此时的属性为私有属性,所以利用快捷键 ALT+ INSERT创建公共属性。

package com.AL.pojo;public class Person {private String name;private int age;public Person(){}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

2.在创建的Session类中,去存储一个 person 类:

package com.AL.servlet;import com.AL.pojo.Person;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;// session。 存放一个字符串
public class SessionDemo01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决乱码问题req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html; charset=utf-8"); // 使文档可以访问,还有编码//得到一个sessionHttpSession session = req.getSession();// 给session中存放东西。 服务器对客户进行登记session.setAttribute("name", new Person("鑫仔",1));//存储一个 person类// 获取session的ID。  且每个客户端的sessionID是唯一的String sessionId = session.getId();//判断Session是否是新建的if (session.isNew()){resp.getWriter().write("Session创建成功,ID为"+sessionId);}else {resp.getWriter().write("session已经在服务器中创建了,ID为"+sessionId);}//Session创建的时候做了什么事情
//        Cookie cookie = new Cookie("JSESSIONID", sessionId);
//        resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}

3.启动Tomcat测试。

Session注销

Session注销

  • 移除session信息,手动注销。
  • 注销session信息。自动注销。
  1. 创建一个Session。

    package com.AL.servlet;import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;public class SessionDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();session.removeAttribute("name");// 手动注销sessionsession.invalidate();System.out.println("over!!!");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
    }
    
  2. 配置web.xml文件:

      <servlet><servlet-name>SessionDemo03</servlet-name><servlet-class>com.AL.servlet.SessionDemo03</servlet-class></servlet><servlet-mapping><servlet-name>SessionDemo03</servlet-name><url-pattern>/s3</url-pattern></servlet-mapping>
    
  3. 如果想要自动注销session,那么在web.xml配置文件中进行:

    <!--  设置Session默认的失效时间--><session-config>
    <!--    1分钟后Session自动失效,以分钟为单位--><session-timeout>1</session-timeout></session-config>
    

那么, 一个网站,究竟如何证明你来过 ?

  • Cookie方法: 初次访问的时候,服务器给客户端一个cookie。以后客户端去请求服务端时,带着cookie去

  • Session方法:客户端访问服务器的时候,服务器会登记一个Session,编号为SessionID,且这个ID是唯一的,每个浏览器是一个用户其实。用户其实是拿着SessionID去进行访问。 而在服务器中的Session是可以存放数据的。

假如两个用户去想要得到对方的数据,就需要==ServletContext,即 applicatiContext:==就好比前面的多个servlet程序中共享数据一样。

2、JSP

2.1、JSP简介

javaweb 动态web的技术栈有 JSP/Servlet

前面我们已经创建一个Servlet程序完成了简单的动态web。

  1. 编写一个Servlet类。 我们选择了直接继承HttpServlet接口,就实现了继承Servlet接口。
  2. 将编写的Servlet发布到web服务器中。 即在web.xml里面进行注册 Servlet和Servlet的路径映射。

这里讲解使用 JSP 技术栈的动态 web。

  • jsp也能完成页面跳转,提供动态数据。

什么是JSP?

Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态web技术!

最大的特点:

  • 写jsp就像在写HTML

  • 区别:

    • HTML只给用户提供静态的数据
    • JSP页面中可以嵌入java代码,为用户提供动态数据

2.2、JSP原理

2.2.1、JSP原理解析

思路:JSP究竟是如何执行的?

  • 代码层面没有任何问题

  • 服务器内部工作

    • tomcat中有一个work目录

    • 在IDEA中使用Tomcat的,会在IDEA中的tomcat中产生一个work目录

我的电脑上的地址为:C:\Users\ASUS.IntelliJIdea2019.3\system\tomcat\Unnamed_javaweb-02_servlet\work\Catalina\localhost\r1\org\apache\jsp

在此页面下转换成了 java程序

所以 jsp到底怎么执行?

上面的图片中可以发现, jsp 最终也会被转换成一个 java类

我们去查看里面的代码:

//初始化
public void _JspInit(){}
//销毁
public void _jspDestroy(){}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response){}

在这个 jspService 中的代码的内容有:

  1. 判断请求:

  2. 内置一些对象:

    final javax.servlet.jsp.PageContext pageContext;//页面上下文
    javax.servlet.http.HttpSession session=null; //session
    final javax.servlet.ServletContext application;//applicationContext
    final javax.servlet.ServletConfig config;//config
    javax.servlet.jsp.JspWriter out = null;//out
    final java.lang.Object page = this;//page:当前页
    javax.servlet.jsp.JspWriter _jspx_out = null; //请求
    javax.servlet.jsp.PageContext _jspx_page_context = null;//响应
    
  3. 输出页面前增加的代码:

    response.setContentType("text/html; charset=UTF-8");  //设置响应的页面类型
    pageContext = _jspxFactory.getPageContext(this, request, response,null, false, 8192, true);
    _jspx_page_context = pageContext;
    application = pageContext.getServletContext();
    config = pageContext.getServletConfig();
    out = pageContext.getOut();
    _jspx_out = out;
    
  4. 以上这些对象我们可以在jsp中直接使用。

    • 我们在 index.jsp中输入的代码为:

      <%
      String name = "鑫仔";
      %>
      name:<%=name%>
      
    • 在jsp页面中,只要是java代码就会原封不动的输出

       String name = "鑫仔"; /
      
    • 如果是html代码,就会转换为 下面的格式进行输出到前端。

      out.write("  name:");
      out.print(name);
      out.write("\n");
      

所以 JSP的本质就是一个 Servlet浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!

2.2.2、Tmocat创建Servlet类实例原理

Tomcat 容器是如何创建 Servlet 类实例?用到了什么原理?

  1. 当容器启动时,会读取在 webapps 目录下所有的 web 应用中的 web.xml 文件,然后对 xml 文件进行解析,并读取 Servlet 注册信息。然后,将每个应用中注册的 servlet 类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)
  2. 在 Servlet 注册时加上 1 如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。

2.2.3、JSP和java、Servlet之间的关系

从前面的jsp本质上就是一个 Servlet。(自己的理解)jsp前端页面的信息,会经过转换成 *.java文件,再编译变为 *jsp.class 类。 等价于 Servlet类后, 那么这时候 原先的jsp(Servlet类)和Servlet类 会在 web容器中的 web.xml 文件被解析。 读取Servlet注册信息; 然后进行类加载 通过反射的方式实例化 Servlet 类。 有的是 在客户端第一次请求实例化 Servlet类, 然后客户端处理这个经过服务器处理完毕后的 class对象,即Servlet。

视频中的 jsp、java和Servlet的关系图:

2.2.4、Jsp 和 servlet 有什么区别

1、Jsp 经编译后就变成了 Servlet(Jsp 的本质就是 Servlet,JVM 只能识别 Java 的类,不能识别 Jsp 的代码,Web 容器将 Jsp 的代码编译成 JV M能够识别的 Java 类);

2、Jsp 更擅长表现于页面显示,servlet 更擅长于逻辑控制;

3、Servlet 中没有内置对象,Jsp 中的内置对象都是必须通过 HttpServletRequest 对象、HttpServletResponse 对象以及 HttpServlet 对象得到;

4、Jsp 是 Servlet 的一种简化,使用 Jsp 只需要完成程序员需要输出到客户端的内容,Jsp 中的 Java 脚本如何镶嵌到一个类中,由 Jsp 容器完成。而 Servlet 则是个完整的 Java类,这个类的 Service 方法用于生成对客户端的响应。

2.3、JSP基础语法和指令

  • 我们可以直接在创建Maven项目的时候, 选择 一个maven模板进行创建。

  • 另外一种添加webapp模板 maven项目的方法:在创建一个空的maven项目后,在下图位置处,选择添加,然后找到 web application点击添加。

添加所需要的jar包, 即导入 maven依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.AL</groupId><artifactId>javaweb-jsp</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--Servlet 依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>3.0-alpha-1</version></dependency><!--JSP 依赖 --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version></dependency><!--JSTL表达式的 依赖 --><dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl-api</artifactId><version>1.2-rev-1</version></dependency><!--JSTL表达式的 依赖 --><!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --><dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!--Standard标签库 --><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency>
</dependencies></project>

基础语法

任何语言都有自己的语法,JAVA中有。JSP作为java技术的一种应用,它拥有一些自己扩充的语法(了解知道即可),java所有语法都支持!需要符合java语法,所以这个<% %>这个里面的代码注释用//,<% %> 里面是用来写 java代码的 更需要符合java语法。

在jsp,嵌入java代码即可:

  • <%%>脚本片段

  • <%= %>输出变量或者表达式

  • <%! %>声明

  • <%–注释–%>

  • jsp表达式

    <%–jsp表达式 作用:将程序的输出,输出到客户端
    <% = 变量或者表达式 %> --%>

    <%  = new java.util.Date()   %>
    

    注释写在这样的符号中:<%–注释 --%>

  • jsp脚本片段

    <%–jsp脚本片段–%>

     <%int sum=0;for (int i = 0; i <=100 ; i++) {sum+=i;}out.println("<h1>Sum="+sum+"</h1>");%>
    

    <%–脚本再实现,在代码嵌入HTML元素–%>

    <%for (int i = 0; i <5 ; i++) {%><h1>hello,world</h1><%}%>
    
  • jsp声明

    <%!static{System.out.println("Loading Servlet!");}private int globalVar =0;public void kuang(){System.out.println("进入了方法狂!");}%>
    

    JSP声明会被编译到JSP生成java的类中其他的,会被生成到JSPService方法中。即在IDEA中的tomcat文件中查看root文件里面的java代码可以发现。

    我们查看启动Tomcat运行后, 在work文件中root文件中找到 jsp 下的 index_jsp.java 代码:

    public final class index_jsp extends org.apache.jasper.runtime.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent,org.apache.jasper.runtime.JspSourceImports {// JSP 的声明写在了static{System.out.println("Loading Servlet!");}private  int globalVar =0;public  void xinxin(){System.out.println("进入了春天!");}
    

jsp的注释,不会在客户端显示。html会显示

  <!--我是 HTML的注释 --><%--  我是JSP的注释--%>

写变量的时候,<%=%> 也可以写成**${}** 这样的形式。

<%--  变量表达式
<%=%>
${}  EL表达式
--%><%for (int i = 0; i < 5; i++) { %><h1>hello,girl${i}!</h1><% }%>

上述三种基础语法的代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>$Title$</title></head><body><%-- $END$ --%><%-- JSP表达式<%  = 变量或者表达式 %>  --%><%= new java.util.Date()%><br><%String name = "鑫仔";%>name:<%=name%>
<br>
<%--  jsp 脚本片段
<%  %>脚本片段      --%><%int sum=0;for (int i = 0; i <=100 ; i++) {sum+=i;}out.println("<h1>Sum="+sum+"</h1>");%><br><%--  jsp声明  <%! %>声明--%><%!static{System.out.println("Loading Servlet!");}private  int globalVar =0;public  void xinxin(){System.out.println("进入了春天!");}%><br>
<%--注释--%><!--我是 HTML的注释 --><%--  我是JSP的注释--%><%--  变量表达式
<%=%>
${}  EL表达式
--%><%for (int i = 0; i < 5; i++) { %><h1>hello,girl${i}!</h1><% }%></body>
</html>

2.4、JSP指令

定制错误界面 <%@page … %>

我们在访问页面的时候,有时候会出现访问错误的界面, 如何去定制。

代码 int x =1/0; 错误代码, 因为除数不能为0. 我们定制一个错误的页面,想要在出现 500错误的时候,去跳转到一个500错误的特定信息界面。

  1. 设置一个出错的页面。

    定义跳转路径。 表示当发生错误的时候,则页面跳转到 error/500.jsp 文件这个界面。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %><%-- 定制错误页面--%>
    <%@ page errorPage="error/500.jsp" %>
    <%@ page errorPage="error/404.jsp" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <%int x=1/0;
    %>
    </body>
    </html>
    
  2. 自定义的500的错误的 jsp文件,

    我们可以直接让此页面显示 500错误文字信息, 在这里,我们将500错误页面去换成一个图片。 扫描 web 路径下的图片。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <%--<h1> <h1>这个是用来设置字体大小的
    <h1>自定义500错误的界面</h1>
    --%>
    <img src="../img/500.jpg" alt="">
    </body>
    </html>
    
  3. 在web.xml中进行配置文件的修改。

    —另一种方式:不用在 jsp 文件中定义跳转页面。出现了响应状态码,到对应的jsp页面。

    我们也可以直接在 web.xml文件中进行配置修改:这样出现了错误,就直接去跳转到对应的jsp文件执行。

    <?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_4_0.xsd"version="4.0"><!-- 配置对静态资源的处理 --><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.jpg</url-pattern></servlet-mapping><!--   自定义配置错误页面--><error-page><error-code>404</error-code><location>/error/404.jsp</location></error-page><error-page><error-code>500</error-code><location>/error/500.jsp</location></error-page></web-app>
    
  4. 启动,进行测试。

文件夹格式

页面拼接

JSP指令:
<%@page … %>
<%@>

  • <jsp:include page="/common/header.jsp" />
  • <%@include file=“common/header.jsp”%>

测试指令**<%@include … %>**:拼接指令。

  • 创建两个jsp文件。 header.jsp 和footer.jsp文件:,且这两个 jsp文件建立在 web目录下的common文件中。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <h1>我是header</h1>
    <html>
    <head><title>Title</title>
    </head>
    <body></body>
    </html>
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <h1>我是footer</h1>
    <html>
    <head><title>Title</title>
    </head>
    <body></body>
    </html>
    
  • 定义一个 jsp3.jsp文件。 想要去展现拼接两个页面的结果。**<%@include … %>**指令

    <%--JSP的注释--%>
    <!--HTML的注释--><%--两个页面拼接在一起: 合二为一--%>
    <%@include file="common/header.jsp"%>
    <h1>网页主体</h1>
    <%@include file="common/footer.jsp"%>
    <hr>
    
  • 采用**jsp:include 指令**进行页面拼接。 斜杠 / 表示外部的路径

    <%--两个页面拼接在一起: 单独存在,页面进行拼接--%>
    <jsp:include page="/common/header.jsp" />
    <h1>网页主体</h1>
    <jsp:include page="/common/footer.jsp" />
    
  • 启动tomcat,进行测试观察者这两种方式的结果。http://localhost:8080/jsp3.jsp

    粗略的看,这两种指令 @include 和 jsp.include 完成的效果一样。 但还是存在着一些区别。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <%--JSP的注释--%>
    <!--HTML的注释-->
    <%--两个页面拼接在一起: 合二为一--%>
    <%@include file="common/header.jsp"%>
    <h1>网页主体</h1>
    <%@include file="common/footer.jsp"%>
    <hr><%--两个页面拼接在一起: 单独存在,页面进行拼接--%>
    <jsp:include page="common/header.jsp" />
    <h1>网页主体</h1>
    <jsp:include page="common/footer.jsp" /></body>
    </html>
    

    @include 是将两个页面合二为一;jsp:include是将页面进行拼接。

2.5、JSP内置对象及作用域

2.5.1、9大内置对象

  • PageContext 存东西
  • Request 存东西,封装客户端的请求。 包括来自get和post请求的参数
  • Response 封装服务器对客户端的响应。
  • Session 存东西。 封装用户会话的对象
  • Application [ServletContext] 存东西 封装服务器运行环境的 对象
  • conifg [ServletConfig] Web应用的配置对象
  • out
  • page Jsp 页面本身(相当于 Java 程序中的 this);
  • exception

例子: pageContextDemo01.jsp

使用存放东西的这几个内置对象: pageContext、request、session、 application 去存放数据。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%-- 内置对象
在脚本片段的代码,会原封不动生成.jsp.java 要遵循java语法
--%>
<%pageContext.setAttribute("name1","鑫仔1号");//保存的数据只在一个页面中有效request.setAttribute("name1","鑫仔2号");//保存的数据只在一次请求中有效,请求转发会携带这个数据session.setAttribute("name1","鑫仔3号");//保存的数据只在一次会话中有效,从打开浏览器道关闭浏览器application.setAttribute("name1","鑫仔4号");//保存的数据只在服务器中有效,从打开服务器道关闭服务器
%>
<% //从pageContext取出,我们通过寻找的方式来//作用域:从底层到高层的顺序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");
%>
<%--使用EL表达式输出  形式为:${}--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>

保存的数据,作用的区域不同,从==底层到高层的作用域分别为:page、request(请求)、session(会话)、application==

pageContext.setAttribute("name1","鑫仔1号");//保存的数据只在一个页面中有效
request.setAttribute("name1","鑫仔2号");//保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name1","鑫仔3号");//保存的数据只在一次会话中有效,从打开浏览器道关闭浏览器
application.setAttribute("name1","鑫仔4号");//保存的数据只在服务器中有效,从打开服务器道关闭服务器

新建一个 pageContextDemo02.jsp.

查看哪个有效? 因为作用域不同,存活的时间也是不一样的

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<% //从pageContext取出,我们通过寻找的方式来//作用域:从底层到高层的顺序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");
%>
<%--使用EL表达式输出  形式为:${}--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
</body>
</html>

当我们从 pageContext取出时, 我们通过寻找的方式来。即pageContext.findAttribute()方法

作用域的顺序为: page->request -> session ->application。类似于JVM中的双亲委任机制。

双亲委任机制: 先找最大,级别最高的,一开始就继承的那个类。 没有了再从高往低找。

2.5.2、JSP的4种作用域

Jsp 中的四种作用域包括 page、request、session 和 application,具体来说:

1、page 代表与一个页面相关的对象和属性;

2、request 代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多

个页面,涉及多个 Web 组件,需要在页面显示的临时数据可以置于此作用域;

3、session 代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关

的数据应该放在用户自己的 session 中;

4、application 代表与整个 Web 应用程序相关的对象和属性,它实质上是跨越整个 Web

应用程序,包括多个页面、请求和会话的一个全局作用域。

对应于上面这4种作用域,

  • pageContext的范围只适用于当前页面范围,超过这个范围就不行了。 所以不能使用pageContext去进行页面之间的参数传递。
  • request:用户向服务端发送请求,服务端响应后的数据。用户看完就没用了。 即作用域的范围是 在这一JSP网页 请求到另一 JSP网页之间,然后属性就会消失。 比如:新闻,用户看完后就失效了
  • session:客户端向用户端发送请求,产生的数据。 用户进行使用,会使用一定的时间。 但是当与服务端关闭后,即关闭浏览器,则就没用了。
  • application:客户端向服务端发送请求,产生的数据。 这个用户用完,其它用户还能使用。 范围在服务器一开始执行服务,到服务器关闭为止。它的范围最大,生存周期最长。

不同的作用域它们之间的关系

2.6、jsp标签、jstl标签、EL表达式

在使用这些标签的时候,需要相应的 jar包。

pom.xml文件中 导入maven依赖

<!--JSTL表达式的 依赖 -->
<dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl-api</artifactId><version>1.2-rev-1</version>
</dependency>
<!--JSTL表达式的 依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl</artifactId><version>1.2</version>
</dependency><!--Standard标签库 -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
</dependencies></project>

EL表达式: ${}

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象

我们使用美元符号大括号进行 获取数据和执行运算。

2.6.1、jsp标签

jsp:forward page 页面跳转标签。

  1. 在jsptag.jsp中写入一个程序,并指定跳转页面。 去观察跳转的结果。

    定义一个页面,功能就是用来跳转的,并给这个页面一些数据信息

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <h1>1</h1>
    <%--jsp:include  jsp标签--%>
    <%--页面跳转标签 jsp:forward page --%>
    <jsp:forward page="jsptag2.jsp"><jsp:param name="name" value="ALZN"/><jsp:param name="age" value="18"/>
    </jsp:forward>
    </body>
    </html>
    
  2. 对应的跳转页面 jsptag2.jsp。 利用request.getParameter() 去获取信息。

    功能是用来得到来自跳转页面的信息。用来展示信息的:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>2</h1>
<%--取出参数
<%=变量名%>    <${}>   这两种方式等价
--%>
<%--取出参数--%>名字:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>
</body>
</html>

获取参数的两种方式:

  • =变量名
  • ${}

3.这种 jsp 标签页面跳转。 是不需要像 Servlet程序那样进行 web发布的。 直接启动Tomcat进行测试就行了。

输入:http://localhost:8080/jsptag.jsp 结果为:

可以发现, 我们定义的 jsptag.jsp 页面就是会直接发生跳转,响应到 jsptag2.jsp的信息。但是url路径却没变。

2.6.2、JSTL标签

关于JSTL标签的简单使用链接:https://www.runoob.com/jsp/jsp-jstl.html

JSTL表达式:

  • JSTL标签库的使用是为了弥补HTML标签的不足
  • 自定义许多标签,供我们使用,
  • 标签的功能和 java 代码一样

JSTL标签:

  • 核心标签
  • 格式化标签
  • SQL标签
  • XML标签

核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:

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

标签 描述
<c:ount> 用于在JSP中显示数据,就像<%= … >
<c:set> 用于保存数据
<c:remove> 用于删除数据
<c:catch> 用来处理产生错误的异常状况,并且将错误信息储存起来
<c:if> 与我们在一般程序中用的if一样
<c:choose> 本身只当做<c:when>和<c:otherwise>的父标签
<c:when> <c:choose>的子标签,用来判断条件是否成立
<c:otherwise> <c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行
<c:import> 检索一个绝对或相对 URL,然后将其内容暴露给页面
<c:forEach> 基础迭代标签,接受多种集合类型
<c:forTokens> 根据指定的分隔符来分隔内容并迭代输出
<c:param> 用来给包含或重定向的页面传递参数
<c:redirect> 重定向至一个新的URL.
<c:url> 使用可选的查询参数来创造一个URL

JSTL标签库使用步骤

  1. 引入对应的 taglib
  2. 使用其中的方法
  3. 在Maven中也需要引入 jstl 的包,否则就会报错: JSTL解析错误

例子:

在coreif.jsp文件下:

  1. 导入对应的taglib: 这个和前面的 <%@ include 类似。

    • 引入JSTL核心标签库, 我们才能去使用JSTL标签 core
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  2. 使用其中的方法: <c:if>。 这里面的代码形式和 java代码一样

    if代码测试

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%-- 引入JSTL核心标签库, 我们才能去使用JSTL标签 core--%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <h4>if测试</h4>
    <hr>
    <%--使用EL表达式获取表单中的数据
    ${param.参数名}
    --%>
    <form action="coreif.jsp" method="get"><input type="text" name="username" value="${param.username}"><input type="submit" value="登录">
    </form>
    <%--判断 如果用户提交的是管理员,则登录成功--%>
    <c:if test="${param.username == 'admin'}" var="isAdmin"><c:out value="管理员欢迎您!"></c:out>
    </c:if></body>
    </html>
    

corewhen.jsp文件下测试 jstl标签库中的 <c:when>, 条件判断是否成立。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<%--定义一个变量score,值为85--%>
<c:set var="score" value="55"/><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:choose></body>
</html>

coreforeach.jsp文件下测试:<c:forEach>。 进行遍历:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>Title</title>
</head>
<body>
<%ArrayList<String> 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}"/> <br>
</c:forEach>
<hr><c:forEach var="people" items="${list}" begin="1" end="3" step="1" ><c:out value="${people}"/> <br>
</c:forEach></body>
</html>

3、JavaBean

实体类

JavaBean有特定的写法:

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

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

ORM:对象关系映射

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

people表:

id name age address
1 鑫仔1号 1 山西
2 鑫仔2号 2 山西
3 鑫仔3号 3 山西

这个表去对应位一个类的话:

class People{private int id;private String name;private String adress}
class A{new People(1,"鑫仔1号",1,"山西");new People(2,"鑫仔2号",2,"山西");new People(3,"鑫仔3号",3,"山西");
}

JavaBean 例子:

  1. people类 java程序。

    属性私有化:即 private, 这种属性子类不能直接继承,需要get/set方法去将属性创建为一些公共属性去进行调用。

    package com.AL.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 int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "people{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", address='" + address + '\'' +'}';}
    }
    
  2. 创建数据库。 数据库为jdbc,表名为people:

  1. 创建javabean.jsp文件。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <%--<br>换行
    <hr>是html标签 表示一条直线
    --%>
    <jsp:useBean id="people" class="com.AL.pojo.people" scope="page"/>
    <jsp:setProperty name="people" property="address" value="秦皇岛"/>
    <jsp:setProperty name="people" property="id" value="1"/>
    <jsp:setProperty name="people" property="age" value="18"/>
    <jsp:setProperty name="people" property="name" value="鑫仔"/>姓名:<jsp:getProperty name="people" property="name"/>
    年龄:<jsp:getProperty name="people" property="age"/>
    id:<jsp:getProperty name="people" property="id"/>
    地址:<jsp:getProperty name="people" property="address"/>
    </body>
    </html>
    

启动Tomcat进行测试:http://localhost:8080/javabean.jsp

4、MVC三层架构

什么是MVC:Model View Controller 模型、视图、控制器

4.1、以前的架构

用户直接访问控制层,控制层就可以直接操作数据库

就好比,我们前面创建的一个javaweb的 Servlet程序+jsp。 不过jsp主要是用来渲染界面的,虽然本质上也是一个Servlet。 客户端访问服务端,我们在Servlet程序中接收到请求 req, 然后回响应 resp。而当加入数据库后,直接在Servlet代码中进行 JDBC的工作,处理数据库的数据, 然后把操作得到的数据返回给客户端,并且你改了数据还要在服务端中对数据库完成同步 数据持久化。 代码臃肿,不利于维护。

servlet–CRUD–>数据库
弊端:程序十分臃肿,不利于维护 (要在Servlet里面写JDBC的代码)
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的!
程序猿调用
|
JDBC (实现该接口)
|
Mysql Oracle SqlServer …(不同厂商)

4.2、MVC三层架构

改进:MVC架构如下所示, Model、View、Controller

三层架构中,各自主要负责的功能为

Model

  • 业务处理 :业务逻辑(Service)
  • 数据持久层:CRUD (Dao - 数据持久化对象)

View

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

Controller (Servlet)

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

在MVC三层架构中, 我们不再让Servlet独自一人完成刚才的 请求、响应、视图跳转、JDBC、业务代码等工作。

  • 我们让Servlet程序 作为一个控制器 Controller,处理请求,然后去调用Model中的 service层进行业务处理,响应完成后去调用 view 视图层进行视图跳转。
  • View专心的渲染视图,展现给用户页面; 并且接收客户端的链接 去发送请求
  • Model 模型中分为 Service 业务层专门进行业务逻辑处理; Dao层进行底层的数据库处理,完成数据持久化。

5、过滤器 Filter

5.1、Filter

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

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

5.2、写过滤器

  1. 创建maven项目。导入maven依赖,这里特地增加了 数据库连接的依赖。

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.AL</groupId><artifactId>javaweb-filter</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--Servlet 依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>3.0-alpha-1</version></dependency><!--JSP 依赖 --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version></dependency><!--JSTL表达式的 依赖 --><dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl-api</artifactId><version>1.2-rev-1</version></dependency><!--JSTL表达式的 依赖 --><!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --><dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!--Standard标签库 --><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.47</version></dependency></dependencies></project>
    
  2. 编写过滤器 filter类。

    • 我们想要去进行过滤所有的代码,让其进行编码 UTF-8。 新建一个 CharacterEncodingFilter 类。

    • 注意:此时的过滤器导入的包为 java.servlet.* 。

    • package com.AL.filter;import javax.servlet.*;
      import java.io.IOException;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 servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {servletRequest.setCharacterEncoding("utf-8");servletResponse.setCharacterEncoding("utf-8");servletResponse.setContentType("text/html;charset=UTF-8");System.out.println("CharacterEncodingFilter执行前");filterChain.doFilter(servletRequest,servletResponse); //让我们的请求继续走,如果不写的话,程序到这里就被拦截停止System.out.println("CharacterEncodingFilter执行后");}// 销毁: web服务器关闭的时候,过滤器就会被销毁public void destroy() {System.out.println("CharacterEncodingFilter销毁");}
      }
      
  3. 编写Servlet类。

    新建一个showFilter,servlet程序。添加编码和没有编码,分别进行调试:

    注意:如果有1000个servlet程序响应, 那么我们就要输1000次编码 utf-8。 所以我们想要过滤器去做这件事情。

    package com.AL.servlet;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 ShowServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setCharacterEncoding("utf-8");resp.getWriter().write("你好,李焕英!");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
    }
    
  4. 编写web.xml配置文件.

    • 注册Servlet类和 Servlet的映射路径。定义两种 添加编码和没有编码,分别进行调试: 即一种

    • 过滤器 filetr的注册和映射路径。

    • <?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_4_0.xsd"version="4.0"><servlet><servlet-name>ShowServlet</servlet-name><servlet-class>com.AL.servlet.ShowServlet</servlet-class></servlet><servlet-mapping> <!--经过了 过滤器filter的 servlet程序(ShowFilter)--><servlet-name>ShowServlet</servlet-name><url-pattern>/servlet/show</url-pattern></servlet-mapping><servlet-mapping> <!--正常情况下的 servlet程序(ShowFilter)--><servlet-name>ShowServlet</servlet-name><url-pattern>/show</url-pattern></servlet-mapping><!--    过滤器的配置--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>com.AL.filter.CharacterEncodingFilter</filter-class></filter><!--    只要是/servlet的任何请求,都会经过这个过滤器--><!--  <url-pattern>/*</url-pattern>  --><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/servlet/*</url-pattern></filter-mapping></web-app>
      

启动Tomcat进行测试。

  • 没有经过过滤器 filter的servlet程序。 输入 localhost:8080/show.结果为:

  • 经过过滤器 filter的servlet程序。 输入 **localhost:8080/servlet/show.**结果为:

设计一个过滤器的步骤:

  • 编写一个过滤器 filetr类。实现Filter接口
  • web.xml配置文件中注册过滤器

在 servlet程序和服务器之间添加一些过滤器,完成请求和响应的一些功能,解决乱码和过滤不必要的请求。

6、监听器

实现一个监听器的接口;(有N种接口)

  1. 编写一个监听器。 即实现一个监听器的接口就行。
  2. web.xml文件中注册监听器

例子:

统计网站在线人数

  1. 编写一个 session的监听器程序。 在服务器中存储这种 网站在线人数的信息, 不存放在 cookie里面。

    • 创建session监听:每次创建session,就触发httpSessionEvent 事件。观察得到的ID

    • 销毁session监听:

    package com.AL.listener;import javax.servlet.ServletContext;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;public class OnlineCountListener implements HttpSessionListener {//创建 session监听: 查看你的一举一动// 一旦创建了 Session就会触发一次这个事件public void sessionCreated(HttpSessionEvent httpSessionEvent) {ServletContext ctx = httpSessionEvent.getSession().getServletContext();System.out.println(httpSessionEvent.getSession().getId());Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");if (onlineCount == null){onlineCount = new Integer(1);}else {int count = onlineCount.intValue();onlineCount = new Integer(count+1);}ctx.setAttribute("OnlineCount", onlineCount);}//销毁session监听//一旦销毁Session就会触发一次这个事件!public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {ServletContext ctx = httpSessionEvent.getSession().getServletContext();Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");if (onlineCount == null){onlineCount = new Integer(1);}else {int count = onlineCount.intValue();onlineCount = new Integer(count-1);}ctx.setAttribute("OnlineCount", onlineCount);}
    }
    
  2. 在index.jsp中去获得在线人数的数据,用于界面展示:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html><head><title>$Title$</title></head><body><h1>当前有 <span><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线</h1></body>
    </html>
    
  3. 配置文件web.xml监听事件的注册:

    <!--    注册监听器--><listener><listener-class>com.AL.listener.OnlineCountListener</listener-class></listener>
    
  4. 添加测试:查看是有几个,具体标号

    //查看具体标号
    System.out.println(httpSessionEvent.getSession().getId());
    

多开几个浏览器进行测试。此时java控制台显示的3个人的标号 getId. 三个人在线。

E94BC8A2E7DF88FE4397B8A0D0C032E4
DD3304FD19601E9BC73FF08F3AE96B81
123623BDC7FAE4355487EEEE0F801047

session销毁有自动和手动两种方式,如下所示:

  • 手动销毁

        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {ServletContext ctx = httpSessionEvent.getSession().getServletContext();httpSessionEvent.getSession().invalidate();//手动销毁
    
  • 自动销毁

    <!--    手动销毁session--><session-config><session-timeout>1</session-timeout></session-config>
    

7、监听器和过滤器的常见应用

7.1、监听器GUI中理解

监听事件的例子:

package com.AL.listener;import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;//监听事件的例子
public class TestPanel {public static void main(String[] args) {Frame frame = new Frame("中秋节快乐");  //新建一个窗体Panel panel = new Panel(null); //面板frame.setLayout(null); //设置窗体的布局frame.setBounds(300,300,500,500);frame.setBackground(new Color(0,0,255)); //设置背景颜色panel.setBounds(50,50,300,300);panel.setBackground(new Color(0,255,0)); //设置背景颜色frame.add(panel);frame.setVisible(true);//监听事件,监听关闭事件frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {super.windowClosing(e);}});}
}

7.2、Filter实现权限拦截

  • 用户登录之后才能进入主页。
  • 用户注销后不能进入主页。

1.登录界面 login.jsp

在这里定义登录界面, 使用 post方法去获取页面前端参数。 请求路径为 /servlet/login。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>登录</h1>
<form action="/servlet/login" method="post"><input type="text" name="username"><input type="submit">
</form>
</body>
</html>

2.创建一个 servlet程序

获取前端的数据后,进行重定向,实现页面跳转。 方法和前端处的一样为 post。

package com.AL.servlet;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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取前端请求的参数String username = req.getParameter("username");if (username.equals("admin")){ //登录成功req.getSession().setAttribute("USER_session", req.getSession().getId());resp.sendRedirect("/sys/success.jsp");} else { //登录失败resp.sendRedirect("/error.jsp");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}

3.定义登录成功和失败的 jsp页面

注意路径,success.jsp在 sys目录下。 error.jsp在同一级目录下。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>主页</h1>
<p><a href="/servlet/logout">注销</a> </p>
</body>
</html>

error.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>错误</h1>
<h3>没有权限,用户名错误</h3>
<a href="login.jsp">返回登录界面</a>
</body>
</html>

4.web.xml配置文件。

<!--    登陆页面和注销页面的 Servlet注册--><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>com.AL.servlet.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/servlet/login</url-pattern></servlet-mapping><servlet><servlet-name>LogoutServlet</servlet-name><servlet-class>com.AL.servlet.LogoutServlet</servlet-class></servlet><servlet-mapping><servlet-name>LogoutServlet</servlet-name><url-pattern>/servlet/logout</url-pattern></servlet-mapping>

启动Tomcat进行测试:在浏览器中输入 localhost:8080/login.jsp, 然后在接收到请求后,即提交动作 submit会 会在web.xml文件中找到此Servlet的注册信息去进行 servlet ,对前端客户端的信息进行获取,然后去响应 进行重定向 页面跳转。

成功进入登录页面:

在用户名错误的时候:

无法登录成功.

但是在测试的时候,你直接输入http://localhost:8080/sys/success.jsp 也会直接进入 登录成功的页面。 我们要使用过滤器 去阻止这种操作。 页面拦截的作用

5.过滤器拦截。

对于登录成功的页面:/sys/success.jsp 这个界面。 我们设置了一个 USER_SESSION 去获取 session的ID, 当ID==null的时候,这说明没有进行页面登录中进行登录成功的 事件, 所以会直接拦截,让其去跳转到 错误页面。

package com.AL.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class SysFilter implements Filter {// 初始化: web服务器启动,就已经初始化了,随时等待过滤对象出现public void init(FilterConfig filterConfig) throws ServletException {System.out.println("CharacterEncodingFilter初始化");}//SysFilter过滤器public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;if (request.getSession().getAttribute("USER_SESSION") == null) {response.sendRedirect("/error.jsp");}chain.doFilter(request, response);}// 销毁: web服务器关闭的时候,过滤器就会被销毁public void destroy() {System.out.println("CharacterEncodingFilter销毁");}
}

在拦截器 Servlet接口实现类的步骤:

  • 初始化。public void init(FilterConfig filterConfig) throws ServletException{} 在web服务器启动的时候,就会初始化,然后去随时等待过滤对象出现
  • 过滤器。doFilter。 此时的过滤器 拦截器作用是 sessiID为空的时候,就让其去跳转到错误界面
  • ==销毁。destroy() 。==web服务器关闭的时候,过滤器就会被销毁

6.过滤器的web.xml配置文件信息。

    <filter><filter-name>SysFilter</filter-name><filter-class>com.AL.filter.SysFilter</filter-class></filter><filter-mapping><filter-name>SysFilter</filter-name><url-pattern>/sys/*</url-pattern></filter-mapping>

启动Tomcat进行测试,直接输入:localhost:8080/sys/success.jsp 发现此时无法将纳入登录成功的页面:

8、JDBC

简单的来说 JDBC就是一个统一驱动, 用于 java去连接 数据库驱动。

我们在 mysql数据库学习中, 在IDEA中去进行JDBC练习时,导入的jar包有:

需要jar包的支持:

  • java.sql
  • javax.sql
  • mysql-conneter-java… 连接驱动(必须要导入)

在这里,我们使用Maven,创建 maven项目后,直接导入 maven的依赖即可:

<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency>
</dependencies>

创建数据库:

CREATE TABLE `users` (`id` INT(11) NOT NULL,`name` VARCHAR(40) DEFAULT NULL,`password` VARCHAR(40) DEFAULT NULL,`email` VARCHAR(40) DEFAULT NULL,`birthday` DATE DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

向其中添加几组数据: 例子:

-- 注意,在进行创建数据库的时候, 关于 列表名 column 要使用 飘号进行包裹, 而不是单引号,
-- 因为在这里的意义不是字符串,而是属性段
INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`)
VALUES('3','坤坤','123456','kunkun@qq.com','2021-1-1'),('4','略略','123456','luelue@qq.com','2021-1-1')INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`)
VALUES('5','坤坤','123456','kunkun@qq.com','2021-1-1');INSERT INTO `users`(`id`, `name`, `password`, email, birthday)
VALUES(6,'呜呜','123456','wuwu@qq.com','2021-1-1');

8.1、JDBC的步骤和执行SQL的对象 Statement、PreparedStatement

JDBC的步骤,整个流程:

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

普通的SQL执行对象 Statement

  • Statement statement = connection.createStatement(); 创建一个去执行SQL的对象。 简单来说,就是把 sql语句丢给这个对象 statement里面去执行。
  • 查询使用executeQuery. 增删改使用executeUpdate()
package com.AL.test;import java.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 password = "123456";// 1.加载驱动Class.forName("com.mysql.jdbc.Driver");// 2.连接数据库, 代表数据库Connection connection = DriverManager.getConnection(url, username, password);// 3. 向数据库发送 SQL的对象 Statement: CRUD.  用这个对象去完成 操作CRUDStatement statement = connection.createStatement();// 4.编写 SQL语句String sql = "select * from users";// 5.使用 statement 即能够执行sql的对象   去 进行具体的sql语句。  查询语句返回的是一个结果集: ResultSetResultSet rs = statement.executeQuery(sql); // 查询使用executeQuery. 增删改使用executeUpdate()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语句。
  • 使用 PreparedStatement preparedStatement = connection.prepareStatement(sql);
package com.AL.test;import java.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 password = "123456";// 1.加载驱动Class.forName("com.mysql.jdbc.Driver");// 2.连接数据库, 代表数据库Connection connection = DriverManager.getConnection(url, username, password);// 3. 编写 SQL。  使用占位符 ?String sql = "insert into users(`id`, `name`, `password`, `email`, `birthday`) values(?,?,?,?,?);";// 4. 预编译.   向数据库发送 SQL的对象 PreparedStatement: CRUD.  用这个对象去完成 操作CRUDPreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,7); //给第一个占位符?的赋值为 1;preparedStatement.setString(2, "乌日三省吾身");preparedStatement.setString(3,"787878");preparedStatement.setString(4,"1356207897@qq.com");preparedStatement.setString(5, String.valueOf(new Date(new java.util.Date().getTime())));// 5.使用 preparedStatement 即能够执行sql的对象   去 进行具体的sql语句。// 查询语句返回的是一个结果集: ResultSet.查询使用executeQuery.// 增删改使用executeUpdate(). 返回的是一个int i = preparedStatement.executeUpdate();if (i>0) System.out.println("插入成功");// 6.关闭连接,释放资源。  遵循先开后关的原则preparedStatement.close();connection.close();}
}

8.2、JDBC事务

事务的性质: ACID原则:原子性、一致性、隔离性、持久性

事务

  • 要么都成功,要么都失败!
  • ACID原则:保证数据的安全。

事务完成的步骤

  1. 开启事务
  2. 事务提交 commit()
  3. 事务回滚 rollback()
  4. 关闭事务

需要导入的jar包: Junit单元测试

    <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

简单使用

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

@Test
public void test(){System.out.println("Hello");
}

搭建一个环境去设计事务: 银行转账

创建数据库:

-- 创建账单 account  数据表
CREATE TABLE `account`(
`id` INT(3) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET = utf8INSERT INTO  `account`(`name`,`money`)
VALUES ('A',2000.00),('B',1000);
-- 此时输入的A是字符串的意思,并不是表名,所以用单引号,不用`。

JDBC程序:

  1. 数据库配置信息,加载驱动
  2. 连接数据库,
  3. 创建能够代表数据库去执行SQL的对象 Statement:CRUD
  4. 编写 SQL语句
  5. 执行SQL
  6. 关闭连接。

但是需要添加事务回滚 rollback, 所以采用 try catch方法去进行判断:事务失败则回滚

package com.AL.test;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class TestJDBC3 {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: CRUD.  用这个对象去完成 操作CRUD
//            Statement statement = connection.createStatement();try {// 3.通知数据库开启事务, false开启connection.setAutoCommit(false);String sql = "update account set money = money-1000 where name='A';";connection.prepareStatement(sql).executeUpdate();// 制造错误//int i =1/0;String sql2 = "update account set money = money-200 where name='B';";connection.prepareStatement(sql2).executeUpdate();connection.commit(); //以上两条SQL都执行成功了,就提交事务System.out.println("success");} catch (Exception e) {try {//如果出现异常,就通知数据库回滚事务connection.rollback();}catch (SQLException e1) {e1.printStackTrace();}e.printStackTrace();}finally {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

JavaWeb(二):Cookie、Session、JSP、过滤器和监听器、JDBC相关推荐

  1. 第二十六天:cookie+session+jsp入门

    1. 会话(Session) 1.1 相关概念 1.1.1 会话 从打开浏览器访问服务器开始,到访问服务器结束(关闭浏览器.到了过期时间)期间,产生的多次请求和响应加在一起就称之为两者之间的一次会话. ...

  2. DW-CHEN的Java点滴记录JavaWeb之HTTP协议/Servlet/Cookie/Session/JSP/EL/JSTL/Filter/Listener

    JavaEE规范 JavaEE(Java Enterprise Edition):Java企业版,早期叫J2EE(J2EE的版本从1.0到1.4结束):现在Java版本从JavaEE 5开始 Java ...

  3. Java程序员从笨鸟到菜鸟之(二十一)java过滤器和监听器详解

     过滤器 1.Filter工作原理(执行流程) 当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请 ...

  4. 【JavaWeb】基于 JSP、EL表达式实现登录,并使用过滤器与监听器

    文章目录 任务概述 具体需求 涉及知识点 任务过程 思路及代码实现 一. 工具包 properties配置文件 DBUtils.java 二. 创建数据库 三. 对象 User.java 四. 创建登 ...

  5. 【JSP HTTP 状态码】【JSP 表单处理】【JSP 过滤器】【JSP Cookie 处理】【JSP Session】【JSP 文件上传】

    JSP HTTP 状态码 HTTP请求与HTTP响应的格式相近,都有着如下结构: 以状态行+CRLF(回车换行)开始 零行或多行头模块+CRLF 一个空行,比如CRLF 可选的消息体比如文件,查询数据 ...

  6. 2019尚硅谷大数据Javaweb篇三 Ajax、JSTL、会话技术、过滤器、监听器、xml、json

    2019尚硅谷大数据 Javaweb篇三Ajax.JSTL.会话技术.过滤器.监听器 tags: 大数据 2019尚学堂 categories: Ajax异步请求 JSTL中的if和forEach 会 ...

  7. 【转载】 javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册 - 孤傲苍狼 - 博 http://www.cnblogs.com/xdp-gacl/

    javaweb学习总结(二十二)--基于Servlet+JSP+JavaBean开发模式的用户登录注册 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+Ja ...

  8. JavaWeb学习总结(十二):Session

    一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

  9. struts2 javaweb 过滤器、监听器 拦截器 原理

    转: 过滤器.监听器 拦截器 过滤器 创建一个 Filter 只需两个步骤: (1)创建 Filter 处理类: (2)在 web.xml 文件中配置 Filter . 创建 Filter 必须实现 ...

最新文章

  1. AttoNets,一种新型的更快、更高效边缘计算神经网络
  2. 短视频个性化Push工程精进之路
  3. 实时监控用户输入--中文输入解决方案
  4. Android_TextSwitcher和ImageSwitcher
  5. php 安装php soap.dll,php_soap.dll下载
  6. 【HDU - 5881】Tea(思维,找规律)
  7. mysql连接数详解_MySQl 修改最大连接数详解
  8. Ruby eventmachine install
  9. canvas arc() 方法绘制弧线、曲线、圆形,rect() 绘制矩形
  10. selenium.common.exceptions.WebDriverException:Message: 'chromedriver' executable needs to be in PATH
  11. null和空 not null
  12. 如何判断一个网页是否更新
  13. python自动交易软件排名_量化投资软件排名 哪个量化交易软件最好用
  14. 测试页能打印 软件不能打,打印机可以打印测试页不能打印文档怎么处理
  15. 金融行业网络安全等级保护测评指南
  16. pano2vr 缩略图添加场景名称
  17. 注塑工艺工程师视频教程 注塑机调机成型参数教程
  18. ZIF-67沸石咪唑酯骨架结构材料/cas46201-07-4/2-MethylimidazoleCobaltsalt
  19. Javascript中最常用的55个经典技巧
  20. java websocket实现即时聊天系统

热门文章

  1. Linux安装aMule下载eDonkey200网络共享文件
  2. Swarm Bee配置
  3. dbeaver的安装
  4. 6、 函数模板和类模板
  5. 原码、补码、反码、移码的介绍与比较
  6. UE4 创建自定义 Slate UI 控件
  7. 删除电脑中的msi程序
  8. 越疆科技dobot(magician)机械臂在ROS moveit下gazebo仿真控制和真实控制功能包 有兴趣的可以下载来玩
  9. 多角度解析Tesla FSD自动驾驶芯片
  10. Java中 Controller、Service 、Dao/Mapper层的区别