JavaWeb(二):Cookie、Session、JSP、过滤器和监听器、JDBC
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资源,关闭浏览器这个过程可以称之为会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过
那么对于一个网站而言,如何证明你来过呢 ?下面是两种方式:
客户端、服务端:
- 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
- 服务器登记你来过了,下次你来的时候我来匹配你;session
意思就相当于:
- 服务端给客户端开了一个证明,下次你拿着证明来,就可以报道,即cookie
- 服务端自己进行登记了,下次你来,服务端自己在登记表里面找你的信息,找到了就让你进去。session。
1.2、保存会话的两种技术
cookie
- 客户端技术(通过响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把信息或者数据放在Session中!
常见问题:
网站登录之后,下次不用再登录了,第二次就直接上去了。 这就是客户端和服务端成功的进行了匹配, 把曾经两个人之间的交易记录(存放在 cookie / session)拿出来能够成功比对。
查看一下Cookie类:都是一些 get 和 set 的方法,用来存放和获取数据的。
1.3、Cookie 客户端技术
Cookie: 服务端给访问的客户端开了一个证明/信件, 下一次 客户端拿着信件/证明来, 就能直接进去服务端。
客户端技术的例子:
cookie:
创建一个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);} }
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>
启动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:
- 服务器先向客户端请求,去获取cookie信息。请求中拿到cookie信息。想要得到你的发票,如果你有发票,则将发票展示出来;没有,则给你一个新的发票。
- 服务器请求完之后,开始响应给客户端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就自动失效了。
中文数据传递
创建一个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);} }
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>
处理请求参数传递编码问题: 使用编码和解码的方式,使中文不产生乱码。
- 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信息。自动注销。
创建一个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);} }
配置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>
如果想要自动注销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。
- 编写一个Servlet类。 我们选择了直接继承HttpServlet接口,就实现了继承Servlet接口。
- 将编写的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 中的代码的内容有:
判断请求:
内置一些对象:
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;//响应
输出页面前增加的代码:
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;
以上这些对象我们可以在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 类实例?用到了什么原理?
- 当容器启动时,会读取在 webapps 目录下所有的 web 应用中的 web.xml 文件,然后对 xml 文件进行解析,并读取 Servlet 注册信息。然后,将每个应用中注册的 servlet 类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)
- 在 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错误的特定信息界面。
设置一个出错的页面。
定义跳转路径。 表示当发生错误的时候,则页面跳转到 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>
自定义的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>
在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>
启动,进行测试。
文件夹格式:
页面拼接
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 页面跳转标签。
在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>
对应的跳转页面 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标签库使用步骤:
- 引入对应的 taglib
- 使用其中的方法
- 在Maven中也需要引入 jstl 的包,否则就会报错: JSTL解析错误。
例子:
在coreif.jsp文件下:
导入对应的taglib: 这个和前面的 <%@ include 类似。
- 引入JSTL核心标签库, 我们才能去使用JSTL标签 core;
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用其中的方法: <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 例子:
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 + '\'' +'}';} }
创建数据库。 数据库为jdbc,表名为people:
创建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、写过滤器
创建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>
编写过滤器 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销毁");} }
编写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);} }
编写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种接口)
- 编写一个监听器。 即实现一个监听器的接口就行。
- web.xml文件中注册监听器
例子:
统计网站在线人数。
编写一个 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);} }
在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>
配置文件web.xml监听事件的注册:
<!-- 注册监听器--><listener><listener-class>com.AL.listener.OnlineCountListener</listener-class></listener>
添加测试:查看是有几个,具体标号
//查看具体标号 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的步骤,整个流程:
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement : CRUD
- 编写SQL (根据业务,不同的SQL)
- 执行SQL
- 关闭连接(先开的后关)
普通的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原则:保证数据的安全。
事务完成的步骤:
- 开启事务
- 事务提交 commit()
- 事务回滚 rollback()
- 关闭事务
需要导入的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程序:
- 数据库配置信息,加载驱动
- 连接数据库,
- 创建能够代表数据库去执行SQL的对象 Statement:CRUD
- 编写 SQL语句
- 执行SQL
- 关闭连接。
但是需要添加事务回滚 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相关推荐
- 第二十六天:cookie+session+jsp入门
1. 会话(Session) 1.1 相关概念 1.1.1 会话 从打开浏览器访问服务器开始,到访问服务器结束(关闭浏览器.到了过期时间)期间,产生的多次请求和响应加在一起就称之为两者之间的一次会话. ...
- 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 ...
- Java程序员从笨鸟到菜鸟之(二十一)java过滤器和监听器详解
过滤器 1.Filter工作原理(执行流程) 当客户端发出Web资源的请求时,Web服务器根据应用程序配置文件设置的过滤规则进行检查,若客户请求满足过滤规则,则对客户请求/响应进行拦截,对请求头和请 ...
- 【JavaWeb】基于 JSP、EL表达式实现登录,并使用过滤器与监听器
文章目录 任务概述 具体需求 涉及知识点 任务过程 思路及代码实现 一. 工具包 properties配置文件 DBUtils.java 二. 创建数据库 三. 对象 User.java 四. 创建登 ...
- 【JSP HTTP 状态码】【JSP 表单处理】【JSP 过滤器】【JSP Cookie 处理】【JSP Session】【JSP 文件上传】
JSP HTTP 状态码 HTTP请求与HTTP响应的格式相近,都有着如下结构: 以状态行+CRLF(回车换行)开始 零行或多行头模块+CRLF 一个空行,比如CRLF 可选的消息体比如文件,查询数据 ...
- 2019尚硅谷大数据Javaweb篇三 Ajax、JSTL、会话技术、过滤器、监听器、xml、json
2019尚硅谷大数据 Javaweb篇三Ajax.JSTL.会话技术.过滤器.监听器 tags: 大数据 2019尚学堂 categories: Ajax异步请求 JSTL中的if和forEach 会 ...
- 【转载】 javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册 - 孤傲苍狼 - 博 http://www.cnblogs.com/xdp-gacl/
javaweb学习总结(二十二)--基于Servlet+JSP+JavaBean开发模式的用户登录注册 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+Ja ...
- JavaWeb学习总结(十二):Session
一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...
- struts2 javaweb 过滤器、监听器 拦截器 原理
转: 过滤器.监听器 拦截器 过滤器 创建一个 Filter 只需两个步骤: (1)创建 Filter 处理类: (2)在 web.xml 文件中配置 Filter . 创建 Filter 必须实现 ...
最新文章
- AttoNets,一种新型的更快、更高效边缘计算神经网络
- 短视频个性化Push工程精进之路
- 实时监控用户输入--中文输入解决方案
- Android_TextSwitcher和ImageSwitcher
- php 安装php soap.dll,php_soap.dll下载
- 【HDU - 5881】Tea(思维,找规律)
- mysql连接数详解_MySQl 修改最大连接数详解
- Ruby eventmachine install
- canvas arc() 方法绘制弧线、曲线、圆形,rect() 绘制矩形
- selenium.common.exceptions.WebDriverException:Message: 'chromedriver' executable needs to be in PATH
- null和空 not null
- 如何判断一个网页是否更新
- python自动交易软件排名_量化投资软件排名 哪个量化交易软件最好用
- 测试页能打印 软件不能打,打印机可以打印测试页不能打印文档怎么处理
- 金融行业网络安全等级保护测评指南
- pano2vr 缩略图添加场景名称
- 注塑工艺工程师视频教程 注塑机调机成型参数教程
- ZIF-67沸石咪唑酯骨架结构材料/cas46201-07-4/2-MethylimidazoleCobaltsalt
- Javascript中最常用的55个经典技巧
- java websocket实现即时聊天系统