JavaWeb
javaWeb
1.基本概念
1.1
web开发:
- web:网页的意思
- 静态web
- 数据不会发生变化
- 动态web
- 数据会发生变化,每个人看到的都不一样
- 技术栈:Servlet/JSP,ASP,PHP
在java中,动态web资源开发的技术统称为javaWeb
1.2.Web应用程序
web应用程序:可以提供浏览器访问的程序
-
web资源可以被外界访问,为外界提供服务
-
可以被访问到的资源或页面,都存在于计算机上
-
统一的web资源会被放在同一个文件夹上,web应用程序–>Tomcat:服务器
-
应该web应用有多部分组成(静态web,动态web)
- html,css,js
- jsp,servlet
- java
- jar
- 配置文件
web应用程序编写完毕后,需要提供给外界访问,就需要应该服务器来统一管理
1.3 静态Web
- 缺点:
- 页面无法动态更新,所有用户看到的都是一样的
- 无法和数据库交互(数据无法持久化,用户无法交互)
1.4动态Web
- 缺点
- 加入服务器的动态Web资源初心了错误,就需要后台重新编写后台程序,程序发布
- 优点
- Web页面可以动态更新,用户看到的界面都是不一样的
- 可以与数据库交互
2.Web服务器
Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。
Tomact:Tomcat是jsp/servlet容器,用于发布jsp及java的
3.Tomcat
3.1下载
- 解压
- 不需要安装
3.2环境配置
-
服务器核心配置外界
-
可以配置端口号
-
tomcat默认端口号:8080
-
mysql:3306
-
http:80
-
https:443
-
-
可以配置主机名称
-
是
HOST
里面- 默认主机名称为–>localhost == 127.0.0.1(如果要该这个名称还要取电脑系统文件添加名称)
- 默认的网站存放位置为webapps
-
面试题
- 网站如何进行访问
- 输入一个域名,提交
- 检查本机的C:\Windows\System32\drivers\etc\hosts有没有这个域名的映射
- 有:直接返回对于的ip地址,这个地址中有我们要访问的Web程序,可以直接访问
- 没有:去NDS服务器找(这个管理着全世界的所有域名),找到就返回,没有就返回找不到
- 网站如何进行访问
-
-
3.3启动/关闭
- 启动
-
启动完-访问默认端口号:
localhost:8080
可以就代表成功
-
关闭
3.4发布一个网站
-
将自己写的网站放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下
结构
--webapps:Tomcat服务器的web目录 -ROOT -tzeao:网站目录名 -WEB-INF -classes:java程序 -lib:jar包 -web.xml:网站配置 -index.html:默认首页 -staic:资源文件 -css -js -其他
4.HTTP
4.1 什么是HTTP
HTTP(超文本传输协议)上一个简单的请求-响应协议,他通常运行在TCP之上
https:安全的
4.2 请求
-
客户端 – 发请求(Request) – 服务器
请求行
Request URL: https://www.baidu.com 请求地址 Request Method: GET 请求方法 Status Code: 200 OK 状态码 Remote(远程) Address: 14.215.177.39:443
消息头
Accept: application/json, text/javascript Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Connection: keep-alive
4.3 响应
-
服务器 – 响应 – 客户端
Cache-Control:private 缓存控制 Connection:keep-Alive 连接 Content-Encoding:gzip 编码 Content-Type:text/html 类型
1. 响应体
Accept 告诉浏览器它所支持的类型
Accept-Enocoding 支持哪一种编码
Accept-Language 语言环境
Connecion 告诉浏览器请求完成后是断开还是保持
HOST 主机
Refresh 多久刷新一次
Location 网页重定位
2. 状态响应码
200:请求成功
3xx:请求重定向
4xx:找不到资源
-
400 请求类型不匹配
-
404 资源不存在
5xx:服务器代码错误
-
500 java程序抛出异常
-
502:网关错误
5. Maven
项目架构管理工具:方便导入jar包
核心思想:约定大于配置
- 约束不要违反
5.1 下载
解压
5.2配置环境变量
在path中%MAVEN_HOME%\bin
- 查看是否安装完毕
5.3阿里云镜像
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
5.4本地仓库
5.5 使用IDEA
- 主要看一下这里的配置,防止被改为IDEA自带的
5.6 补全文件
- 标记文件,使得变为系统文件
5.7 IDEA配置Tomcat
- No artifacts marked for deploymen解决
然后选择第一个
–
5.8 pom.xml
pom.xml是Maven的核心配置文件
<?xml version="1.0" encoding="UTF-8"?> <!--Maven版本和头文件--> <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> <!--配置的GAV,就是插件项目时候的组名 id--> <groupId>com.tzeao</groupId> <artifactId>javaweb-01-maven</artifactId> <version>1.0-SNAPSHOT</version> <!--packaging:项目的打包方式 jar:Java应用 war:javaWeb应用 --> <packaging>war</packaging> <name>javaweb-01-maven Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <!--配置--> <properties> <!-- 项目默认构建编码--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 编码版本--> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!--项目依赖--> <dependencies> <!-- 具体依赖的jar包 配置文件--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>javaweb-01-maven</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
-
maven高级之处在于他会导入这个jar包所依赖的其他jar包
-
Maven资源导出问题:
-
<!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
- 目录树
6.Maven仓库
Maven Repository: org.springframework (mvnrepository.com)
查看jar包:tomcat-webapps-exmple-里面
7. Servlet
java默认编码:ISO-8859-1
7.1 servlet简介
- 是 Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。
- 自己编写Servlet程序:
- 编写一个类,实现Servlet接口
- 把开发好的java程序部署到Web服务器上
把实现了Servlet接口的Java程序叫 Servlet
- Servlet的功能:
- 创建并返回基于客户请求的动态HTML页面
- 与数据库进行通信
7.2 第一个Servlet程序
-
创建项目
-
创建好的java类,因为客户端不能直接访问WEB-INF,所以要使用映射来间接访问,有俩种配置方式:
-
第一张基于XML文件的配置
<!-- 注册Servlet--> <servlet> <!-- 名称--> <servlet-name>HelloServlet</servlet-name> <!-- 类的路径--> <servlet-class>com.example.demo.HelloServlet</servlet-class> </servlet> <!-- 映射--> <servlet-mapping> <!-- 注册时的名称--> <servlet-name>HelloServlet</servlet-name> <!-- 客户端访问的路径 记得加/--> <url-pattern>/tzeao</url-pattern> </servlet-mapping>
-
基于注解的方式
web.xml <!-- 打开扫描注解 为true 代表关闭--> metadata-complete="false"
//注解的形式 两个参数name可选 ,urlPatterns路径名称 @WebServlet(name = "tzeao",urlPatterns = "/tzeao") public class HelloServlet implements Servlet {}
-
-
package com.example.demo; import javax.servlet.*; import javax.servlet.http.HttpServlet; import java.io.IOException; public class HelloServlet implements Servlet { // 初始化 @Override public void init(ServletConfig servletConfig) throws ServletException { } // 获取servlet的信息 @Override public ServletConfig getServletConfig() { return null; } //核心方法 获取处理客户端 @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("你好"); // 获取客户端的传参 String id = servletRequest.getParameter("id"); // 设置响应类型 servletResponse.setContentType("text/html"); // 设置编码 servletResponse.setCharacterEncoding("utf-8"); // 响应客户端的请求,输出东西 servletResponse.getWriter().write("Hello!Client"+id); } // 返回字符串信息 @Override public String getServletInfo() { return null; } // 销毁 @Override public void destroy() { } }
7.3 Servlet的生命周期
属于生命周期的方法:无参构造函数 init servlet destroy
-
创建(只调用一次)—当浏览器访问Servlet的时候,toncat会查询Servlet的实例化对象是否存在,如果不存在就通过反射机制创建,如果存在,则直接执行第三步
-
// 提供反射来创建MyServlet对象 public Servlet(){ System.out.println("创建MyServlet对象"); } package com.example.demo; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) { // 获取到要反射的类路径 String str = "com.example.demo.MyServlet"; try { // 通过运行池类 来寻找到 Class cla = Class.forName(str); // 找到构造方法 括号里面带参数就是有参构造 Constructor constructor = cla.getConstructor(); // 执行得到的构造函数 Object o = constructor.newInstance(); System.out.println(o); } catch (ClassNotFoundException | NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
-
-
创建(严格来说是初始化) init
- 第一次访问时调用
-
使用 servlet
- 每次刷新页面都执行一次
-
回收 destroy
- 服务器停止时执行
- 只调用一次
7.4 ServletConfig
该接口是用来描述Servlet基本信息的
-
getServletName() 返回Servlet全类名(带包名的)
如果这里设置了名称就输出这个名称
-
getInitParameter(str) 获取init的值 使用这个方法需要在xml文件里面进行注册,不能使用注解
<!-- 注册Servlet--> <servlet> <!-- 名称--> <servlet-name>MyServlet</servlet-name> <!-- 类的路径--> <servlet-class>com.example.demo.MyServlet</servlet-class> <!-- 初始化参数--> <init-param> <!-- key--> <param-name>username</param-name> <!-- value--> <param-value>admin</param-value> </init-param> </servlet> <!-- 映射--> <servlet-mapping> <!-- 注册时的名称--> <servlet-name>MyServlet</servlet-name> <!-- 客户端访问的路径 记得加/--> <url-pattern>/demo</url-pattern> </servlet-mapping>
-
getInitParameterNames() 返回所有的InitParameter的name值
// 获取所有参数的name 这个类是数组
Enumeration<String> enumeration = servletConfig.getInitParameterNames();
while (enumeration.hasMoreElements()){
String s = enumeration.nextElement();
System.out.println(s);
}
-
getServletContext() 返回ServletContext对象,她是Servlet的上下文
ServletContext servletContext = servletConfig.getServletContext(); // 获取tomcat里面的Application context的名称 System.out.println(servletContext.getContextPath()); // 获取服务器名称 System.out.println(servletContext.getServerInfo());
ServletConfig与ServletContext的区别:
-
ServletConfig作用与某个Servlet实例,每个Servlet都对应的一个ServletConfig,ServletContext作用与web全局,一个web应用对应一个ServletContext,多个ServletConfig对应一个ServletContext
-
一个是局部对象,一个是全局对象
7.5 Servlet的层次结构
Servlet –> GenericServlet –> HttpServlet
-
Http请求有很多种,常用的有四种:
- GET –> 读取
- POST –> 保存
- PUT –> 修改
- DELETE –> 删除
-
GenericServlet实现Servlet接口,同时为他的子类屏蔽了不常用的方法,子类只需要重写servlet方法即可。
-
HttpServlet继承GenericServlet类,根据请求类型进行分发处理,GET请求进入doGet方法,POST请求加入doPost方法。
-
开发者自定义的Servlet类只需继承HttpServlet即可,重写doGet,doPost方法
实现原理:
package com.example.demo1; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/ss") public class MyTest extends MyHttpServlet{ @Override public void doGet(HttpServletRequest res, HttpServletResponse resp) throws IOException { resp.getWriter().write("GET"); } @Override public void doPost(HttpServletRequest res, HttpServletResponse resp) throws IOException{ resp.getWriter().write("POST"); } }
-
package com.example.demo1; import javax.servlet.*; import java.io.IOException; public class MyGenericServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
-
package com.example.demo1; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyHttpServlet extends MyGenericServlet{ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { // 强转为它的子类 HttpServletRequest res = (HttpServletRequest)servletRequest; HttpServletResponse resp = (HttpServletResponse)servletResponse; // 判断客户端的请求类型 String method = res.getMethod(); switch (method){ case "GET": this.doGet(res, resp); break; case "POST": this.doPost(res, resp); break; } } public void doGet(HttpServletRequest res,HttpServletResponse resp)throws IOException{ } public void doPost(HttpServletRequest res,HttpServletResponse resp)throws IOException{ } }
8. JSP
JSP本质就是一个Servlet,JSP主要负责与用户页面交互,将最终的页面呈现给用户,HTML+JS+CSS的混合文件。
当服务器接收到一个后缀为JSP的请求时,将该请求交给JSP引擎取处理,每一个JSP页面第一次被访问的时候,JSP引擎会将它翻译成一个Servlet文件,再由Web容器调用Servlet完成响应。
开发角度看,就是HTML里面嵌入JAVA程序
-
具体嵌入方式有三种:
-
JSP脚本:执行java代码
<%java代码%>
-
JSP声明:定义java方法
<!% 声明java方法 %>
-
JSP表达式:把java对象直接输出到HTML页面
<%= "Hello World" %>
-
<%!
public String test() {
return "Hello World";
}
%>
<%
System.out.println(test());
String str = "Hello World";
System.out.println(str);
%>
<%=
"Hello World"
%>
8.1 JSP内置对象
1. 九个对象
-
- request:表示一个请求,HttpServletRequest
-
- response:表一次响应,HttpServletResponse
-
- pageContext:页面上下文,获取页面信息,PageContext
-
- seession:表示一次会话,保存用户信息,HttpSeession
-
- application:表示当前Web应用,全局对象,能保存所有用户共享信息,ServletContext
-
- config:获取当前Servlet的信息,当前JSP对应的Servlet的ServletConfig对象
- out:向浏览器输出数据,JspWriter
-
- page:当前JSP对应的Servlet对象,Servlet
-
- excerption:表示JSP页面发生的异常,Exceptiot
2. request常用方法:
- String getParameter(String key) 获取客户端传来的参数
- void setAttribute(String key,Object value) 通过键值对的形式保存数据
- Object getAttibute(String key) 通过key取出value
2-3用于两个页面的交互
-
RequestDispatcher getRequestDispatcher(String path) 该方法返回一个RequestDispatcher对象,forward()方法用于转发请求
-
String[] getParameterValues(String key) 获取客户端传来的多个同名参数
-
void setCharacterEncoding(String charset) 指定每个请求的编码
3. response常用方法
-
sendRedirect(String path) 重定向,页面之间的跳转
转发和重定向的区别:
- 转发:将同一个请求传给下一个页面,同一个请求再服务器之间传递,地址栏不变,也叫服务器跳转
- 重定向:创建一个新的请求传给下一个页面,有客户端发生一次新的请求来访问跳转后的目标资源,地址栏改变,也叫客户端跳转
- 如果两个页面之间需要通过request来传递数据,则必须用转发
4. Session 用户会话
-
服务器无法识别每一次GTTP请求的出处(不知道来自哪一个终端),他只会接受一个请求信号,所以就会存在问题:将用户的响应发送给其他人
-
会话:就是客户端和服务器之间发生的一系列连续的请求和响应的过程,打开浏览器到关闭浏览器的过程
-
会话状态:指服务器和浏览器再会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次的会话的一系列请求和响应关联起来
-
实现会话的两种方式:
- Session
- cookie
常用方法
-
String getId() 获取seessionID
-
viod setMaxInactiveInterval(int interval) 设置session的失效时间,单位为秒
-
int getMaxInactiveInterval() 获取当前session的失效时间
-
void invalidate() 设置session立即失效
-
void setAttribute() 通过键值对的形式保存数据
-
Object getAttribute() 通过键来获取数据
-
void removeAttribute() 通过键来删除数据
-
在java类里面 通过HttpSession session = req.getSession() 得到session
1
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/6 0006 Time: 17:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/login" method="post"> <table> <tr> <td>用户名</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password"></td> </tr> <tr> <td><input type="submit" value="登录"></td> <td><input type="reset" value="重置"></td> </tr> </table> </form> </body> </html>
2
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/6 0006 Time: 17:55 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% final Object name = session.getAttribute("name"); %> <h1>欢迎<%=name%></h1> <a href="/back">退出登录</a> </body> </html>
3
package com.example.demo1; import com.sun.org.apache.xml.internal.security.Init; import com.sun.xml.internal.bind.v2.model.core.ID; import javax.servlet.ServletConfig; 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 Session extends HttpServlet { String myusername,mypassword; @Override public void init(ServletConfig config) throws ServletException { myusername = config.getInitParameter("username"); mypassword = config.getInitParameter("password"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final String username = req.getParameter("username"); final String password = req.getParameter("password"); // 得到session HttpSession session = req.getSession(); if (username.equals(myusername) && password.equals(mypassword)){ session.setAttribute("name", username); req.getRequestDispatcher("wecome.jsp").forward(req, resp); }else { resp.sendRedirect("login.jsp"); } } }
4
package com.example.demo1; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/back") public class Back extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.invalidate(); resp.sendRedirect("sessionLogin.jsp"); } }
5
<?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>login</servlet-name> <servlet-class>com.example.demo1.Session</servlet-class> <init-param> <param-name>username</param-name> <param-value>a</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
5.Cookie
Cookie是服务端在http响应中附带传给浏览器的一个小文本文件,一旦浏览器保存了某个Cookie,在之后的请求和响应过程中。会将此Cookie来回传递,这样就可以通过Cookie这个载体完成客户端和服务器的数据交互
-
Cookie
-
创建Cookie
//创建Cookie对象 final Cookie cookie = new Cookie("name","Tom" ); //在响应的时候把cookie传给客户端 response.addCookie(cookie);
-
-
读取Cookie
-
Cookie[] cookies = request.getCookies(); for (Cookie str : cookies){ response.getWriter().write(str.getName()+"="+str.getValue()+"<br>"); }
-
-
常用的方法
- int getMaxAge() 获取Cookie的有效时间 -1为关闭浏览器就失效
- void setMaxAge(int age) 设置Cookie的有效时间 单位为秒
- String getName() 获取Cookie的key
- String getValue() 获取Cookie的value
- void setMaxAge(0) 清除Cookie
Seeion 和Cookie的区别
-
session:保存在服务器
数据类型Object
会随着会话结束而销毁
保存重要信息
-
cookie:保存在浏览器
数据类型String
可以长期保存在浏览器,与会话无光
保存不至于信息
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/6 0006
Time: 20:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="登录"></td>
<td><input type="reset" name="重置"></td>
</tr>
</table>
</form>
</body>
</html>
package com.example.demo2;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class Login extends HttpServlet {
private String name = "a";
private String password = "123456";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String n = req.getParameter("name");
final String p = req.getParameter("password");
if (n.equals(name) && p.equals(password)){
Cookie cookie = new Cookie("name", n);
resp.addCookie(cookie);
resp.sendRedirect("welcome.jsp");
}else {
resp.sendRedirect("CookieLogin.jsp");
}
}
}
<%@ page import="java.security.PublicKey" %><%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/6 0006
Time: 20:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
String a = null;
Cookie[] cookies = request.getCookies();
for (Cookie s : cookies){
if (s.getName().equals("name")){
a = s.getValue();
}
}
%>
<h1><%=a%></h1>
<a href="/back">退出</a>
</body>
</html>
package com.example.demo2;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/back")
public class Back extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final Cookie[] cookies = req.getCookies();
for (Cookie s : cookies){
if (s.getName().equals("name")){
s.setMaxAge(0);
resp.addCookie(s);
}
}
}
}
8.2 JSP内置对象的作用域
就讨论4个
1. 四大作用域
- page作用域:对应的内置对象是pageContext
- request作用域:对应的内置对象是request
- session作用域:对应的内置对象是session
- application作用域:对应的内置对象是application
2. 大小
page<request<session<application
- page只在当前页面有效
- request只在一次请求内有效
- session只在一次会话有效
- application在整个WEB用于有效
#访客流量统计
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/6 0006
Time: 23:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Integer count = (Integer) application.getAttribute("count");
if (count == null){
count = 1;
application.setAttribute("count", count);
}else {
count++;
application.setAttribute("count", count);
}
%>
<h1>你是第<%=count%>位访客</h1>
</body>
</html>
8.3.EL表达式
Expression Languge表达式。替代JSP页面中访问数据的复制编码,可以非常便捷的取出域(四大作用域)对象中保存的数据,前提是一定要set进去,EL就是简化get
${变量名} –>变量名就是key值
EL对于四种域对象的查找顺序
pageConetext–>request–>session–>application
按照上述顺序查找,有就立即返回,没有就返回null
指定作用域进行查找
pageContext:${pageScope.变量名}
request:${requestScope.变量名}
session:${sessionScope.变量名}
application:${applicationScope.变量名}
<%
User user =new User("Tom", 4,1 );
pageContext.setAttribute("name", user);
%>
<h1>${name.name}</h1><br>
<h1>${name.a}</h1><br>
<h1>${name.age}</h1>
EL是跟get方法绑定
EL执行逻辑表达式
&& || !< > <= >= ==
${num1<num2}
empty判断是否为空 变量为null 长度为0的String Size为0的集合
8.4 JSTL
JSP Standard Tag Library:JSP标准标签库
JSP为开发者提供的一系列的标签,使用这些标签可以完成一些逻辑处理,比如循环遍历,让代码国家简洁,不再出现JSP脚本穿插的情况。
- 实际开发者EL和JSTL结合起来使用,JSTL侧重于逻辑处理,EL负责注释处理
JSTL的使用
核心标签库
-
需要导入jar包或依赖
<!-- https://mvnrepository.com/artifact/taglibs/standard --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency>
-
在页面上引入 prefix=“c” 代表标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
在需要的地方使用标签
<%-- ${list}为存入时的key var=”user为把值放到这个里面--%> <c:forEach items="${list}" var="user"> <tr> <td> ${user.name} </td> </c:forEach>
package com.example.demo2; public class User { private String name; private int age,a; public User(String name, int age, int a) { this.name = name; this.age = age; this.a = a; } 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 int getA() { return a; } public void setA(int a) { this.a = a; } @Override public String toString() { return getName()+getA()+getAge(); } }
package com.example.demo2; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; @WebServlet("/user") public class JSTL extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<User> list = new ArrayList<>(); list.add(new User("Tom", 4, 1)); list.add(new User("Cat", 5, 7)); list.add(new User("TIMI", 8, 4)); req.setAttribute("list", list); req.getRequestDispatcher("user.jsp").forward(req, resp); } }
JSTL优点:
- 提供了一系列标签
- 可以用于编写各种动态功能
- 常用标签:set out remove catch
set:向域对象中添加数据
<c:set target="${user}" property="name" value="44"></c:set> target存入时的key property 集合里面的key value 要修改的值
<%request.setAttribute(key,value)%>
<%--var == key value == value scope 为存入哪一个域--%> <c:set var="name" value="Tome" scope="request"></c:set> ${name}
out:输出域对象的数据
<c:out value="${name}" default="未定义"></c:out>
value 为key
没有值时默认
remove:删除域对象的数据
<c:remove var="name" scope="request"></c:remove>
var == key
scope要删除哪一个域
catch:捕获异常
<c:catch var="err">
<%
int a = 10 /0 ;
%>
</c:catch>
${err}
捕获并输出
- 条件标签:if choose
<c:set var="name" value="5"></c:set>
<c:if test="${name>4}">hao</c:if>
<c:if test="${name<4}">huai</c:if>
<hr>
<c:choose>
<c:when test="${name>5}">hao</c:when>
<c:otherwise>huai</c:otherwise>
</c:choose>
- 迭代标签:forEach
<%-- ${list}为存入时的key var=”user为把值放到这个里面--%>
<c:forEach items="${list}" var="user">
<tr>
<td>
${user.name}
</td>
</c:forEach>
<%
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
request.setAttribute("name", list);
%>
<%--begin起始位置 end结束位置 step步数 varStatus状态 类似微信小程序的item-index--%>
<c:forEach items="${name}" var="name" begin="1" end="2" step="1" varStatus="sta">
${name}${sta.count}
</c:forEach>
格式化标签库
<%@ taglib prefix="fmt"
uri="http://java.sun.com/jsp/jstl/fmt" %>
<%--对时间格式化 pattern格式--%>
<fmt:formatDate value="${time}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>
对数值格式化
<fmt:formatNumber value="454554.87" maxIntegerDigits="2" maxFractionDigits="1"></fmt:formatNumber>
函数标签库
<%@ taglib prefix="fn"
uri="http://java.sun.com/jsp/jstl/functions" %>
常用标签:
<%
request.setAttribute("test", "Java,CSS");
%>
${fn:contains(test, "sss")}<br>
${fn:startsWith(test, "Java")}<br>
${fn:endsWith(test, "CSS")}<br>
${fn:indexOf(test, "a")}<br>
${fn:replace(test, "Java","JSP" )}<br>
${fn:substring(test, 2,3 )}<br>
${fn:split(test, ",")}[0]-${fn:split(test, ",")}[1]
9. 过滤器Filter
9.1 使用
-
功能:
- 用来连接传入的请求和传出的响应
- 修改以某种方式处理正在客户端和服务器之间交换的数据流
-
如何使用:
与使用Servlet类似,Filter是Java WEB提供的一个接口,开发者只要自定义一个类并且实现改接口即可。
引用javax.servlet.Filte接口
- 要在WEB.xml配置
package com.example.filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class Filter implements javax.servlet.Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); // 传给下一个页面,没加下一个页面不会接收到数据就会空白 filterChain.doFilter(servletRequest, servletResponse); } }
<?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"> <filter> <filter-name>Filter</filter-name> <filter-class>com.example.filter.Filter</filter-class> </filter> <filter-mapping> <filter-name>Filter</filter-name> <!-- 要拦截的页面路径--> <url-pattern>/a</url-pattern> <url-pattern>/a</url-pattern> <url-pattern>/a</url-pattern> </filter-mapping> </web-app>
注意:doFliter方法处理完业务逻辑后,必须添加filterChain.doFileter方法,否则请求/响应无法向后传递,宇宙停留在过滤器中
9.2 Filter的生命周期
当Tomcat启动时,提供反射机制调用Filter的无参构造函数创建实例化对象,同时调用init方法实现初始化,doFilter方法调用多次,当Tomcat服务关闭时,调用destory来销毁Filter对象。
- 无参构造函数:只调用一次,当Tomcat启动时调用(Filter一定要在xml进行配置)
- init方法:只调用一次,当Filter的实例化对象创建之后调用
- doFilter:调用多次,访问Filter的业务逻辑都写在Filter中
- destory:只调用一次,Tomcat关闭时调用
同时配置多个Filter,Filter的调用顺序是有wbe.xml中的配置顺序来决定的,写在上面的配置先调用,因为xml是从上到下顺序读取
<?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">
<filter>
<filter-name>Filter</filter-name>
<filter-class>com.example.filter.Filters</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter</filter-name>
<!-- 要拦截的页面路径-->
<url-pattern>/a</url-pattern>
</filter-mapping>
<filter>
<filter-name>a</filter-name>
<filter-class>com.example.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>a</filter-name>
<!-- 要拦截的页面路径-->
<url-pattern>/a</url-pattern>
</filter-mapping>
</web-app>
-
也可以提供注解的方式来简化web.xml中的配置
<filter> <filter-name>a</filter-name> <filter-class>com.example.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>a</filter-name> <!-- 要拦截的页面路径--> <url-pattern>/a</url-pattern> </filter-mapping>
等于
@WebFilter("/a") public class MyFilter implements Filter {}
实际开发中的Filter的使用场景:
-
统一处理中文乱码
-
屏蔽敏感词
package com.example.filter; import javax.servlet.*; import javax.servlet.Filter; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/a") public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); String name = servletRequest.getParameter("name"); name = name.replaceAll("敏感词", "***"); servletRequest.setAttribute("name", name); filterChain.doFilter(servletRequest, servletResponse); } }
package com.example.filter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/a") public class Test extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = (String) req.getAttribute("name"); req.setAttribute("name", name); req.getRequestDispatcher("a.jsp").forward(req, resp); } }
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/8 0008 Time: 20:05 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/a" method="post"> <input type="text" name="name"> <input type="submit" value="提交"> </form> </body> </html>
-
控制资源的访问权限
package com.example.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/download.jsp")
public class Download implements Filter
{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
final String name = (String) session.getAttribute("name");
if (name == null){
response.sendRedirect("/loginfilter.jsp");
}else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
package com.example.filter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/ll")
public class LoginTest extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String name = req.getParameter("name");
final String password = req.getParameter("password");
if (name.equals("a") && password.equals("123")){
HttpSession session = (HttpSession) req.getSession();
session.setAttribute("name", name);
resp.sendRedirect("/download.jsp");
}
}
}
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/8 0008
Time: 23:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="">资源1</a>
<a href="">资源2</a>
<a href="">资源3</a>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/8 0008
Time: 23:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/ll" method="post">
<input type="text" name="name">
<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
10. 监听器
- 是一个实现了特定接口的Java类;
- 用来监听另一个 Java类的方法调用或者属性的改变;
- 当被监听对象发生了上述事件后,监听器某个方法将会立即被执行。
<!-- 注册监听器-->
<listener>
<listener-class>com.example.jtq.Test</listener-class>
</listener>
package com.example.jtq;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class Test implements HttpSessionListener {
// 创建
@Override
public void sessionCreated(HttpSessionEvent se) {
HttpSessionListener.super.sessionCreated(se);
}
// 销毁
@Override
public void sessionDestroyed(HttpSessionEvent se) {
HttpSessionListener.super.sessionDestroyed(se);
}
}
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/8 0008
Time: 20:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1><%=session.getAttribute("name")%></h1>
</body>
</html>
11. 文件上传下载
11.1 文件上传
-
JSP
- input的type设置为file
- form表单的method为post,get请求会将文件名传给服务端,而不是文件本身
- form表单的entype设置multipart/form-data,以二进制的形式传输数据
-
Servlet
-
普通方法实现
package com.example.demo3; import java.io.*; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.*; import javax.servlet.annotation.*; @WebServlet("/upload") public class UpLoadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 输入流获取上传文件 // 调用字节输入流 ServletInputStream inputStream = req.getInputStream(); // 使用转换流转为字符流 Reader reader = new InputStreamReader(inputStream); // 存入缓冲输入流 BufferedReader bufferedReader = new BufferedReader(reader); // 通过输出流将数据流 输出到本地硬盘 // 获取文件夹的绝对路径 String path = req.getServletContext().getRealPath("file/copy.txt"); // 字节输出流 OutputStream outputStream = new FileOutputStream(path); // 转换为字符流 Writer writer = new OutputStreamWriter(outputStream); // 存入缓冲输出流 BufferedWriter bufferedWriter = new BufferedWriter(writer); String str = ""; // 循环存入 while ((str=bufferedReader.readLine()) != null){ bufferedWriter.write(str); } bufferedWriter.close(); writer.close(); outputStream.close(); bufferedReader.close(); reader.close(); inputStream.close(); // } } }
-
导入jar包的方式
commons-fileupload-1.4.jar
commons-io-2.9.0.jar
导入依赖的方式
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.9.0</version> </dependency>
fileupload组件可以将所有请求信息都解析成Fileltem对象,可以通过对Fileltem对象的操作完成上传,面向对象的思想。
try { // 创建FileItem 对象的工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); // 负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem 对象 ServletFileUpload upload = new ServletFileUpload(factory); // 设置编码 upload.setHeaderEncoding("utf-8"); // 把请求得到的值进去 并且封装成数组 List<FileItem> items = upload.parseRequest(req); System.out.println(items); for (FileItem fileItem : items) { // 判断是文件还是input字符输入的,true为字符 if (fileItem.isFormField()) { // 获取input的name属性的值 System.out.println(fileItem.getFieldName()); // 获取input输入的值并且设置编码为utf-8 System.out.println(fileItem.getString("UTF-8")); } else { System.out.println(fileItem.getFieldName()); // 获取上传文件的名称 System.out.println(fileItem.getName()); // 获取文件的大小 System.out.println(fileItem.getSize()); InputStream inputStream = fileItem.getInputStream(); // 这个文件夹要存在 String str = req.getServletContext().getRealPath("file/"+fileItem.getName()); System.out.println(str); OutputStream outputStream = new FileOutputStream(str); int temp = 0; while ((temp = inputStream.read()) != -1){ outputStream.write(temp); } inputStream.close(); outputStream.close(); System.out.println("上传成功"); } } } catch (FileUploadException e) { e.printStackTrace(); }
-
11.2 文件下载
package com.example.demo3;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@WebServlet("/download")
public class Download extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String fileName = "";
switch (name){
case "img":
fileName="65.png";
break;
case "text":
fileName="test.txt";
break;
}
// 设置响应的方式 调用下载工具 application/x-msdownload固定的
resp.setContentType("application/x-msdownload");
// 设置下载之后的文件名
resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
// 获取输出流
OutputStream outputStream = resp.getOutputStream();
String path = req.getServletContext().getRealPath("file/"+fileName);
InputStream inputStream = new FileInputStream(path);
int temp = 0;
while ((temp = inputStream.read()) != -1) {
outputStream.write(temp);
}
inputStream.close();
outputStream.close();
}
}
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/10 0010
Time: 14:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="/download?name=img">下载</a>
<a href="/download?name=text">下载</a>
</body>
</html>
12. Ajax
Asynchronous JavaScript And XML:异步的JavaScript和XML
AJAX不是新的编程,指的是一种交互方式,异步加载,客户端和服务器的数据交互更新在局部页面的技术,不需要刷新整个页面(局部刷新)
-
优点:
- 局部刷新,效率更高
- 用户体验更好
-
使用基于JQuery的Aiax
-
引入js包
1.依赖
<!--jquery依赖--> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.6.0</version> </dependency>
- jquery-3.6.0.min.js
-
使用
表单发送请求的是同步,所以不能用表单
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/10 0010 Time: 15:28 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <script type="text/javascript" src="js/jquery-3.6.0-min.js"></script> <%-- 测试有没有生效--%> <script type="text/javascript"> $(function () { const btn = $("#btn"); btn.click(function (){ $.ajax({ url:"/test", type:"POST", data:"id=1", dataType:"text", success:function (data){ const text = $("#text"); text.before(data+"<br/>") text.attr("value",data) } }) }) }) </script> </head> <body> <input id="text" type="text" value=""><br> <input id="btn" type="button" value="提交"> </body> </html>
package com.example.demo3;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/test")public class Test extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = req.getParameter("id"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } String str = "Hello,World!"; resp.getWriter().write(str);// req.setAttribute("s", str);// req.getRequestDispatcher("index.jsp").forward(req, resp); }}
-
12.1 传统web数据交互 与 ajax数据交互的区别
- 客户端请求的发生不同:
- 传统:浏览器发送同步请求(form , a)
- ajax:异步引擎对象发送异步请求
- 服务器响应的方式不同:
- 传统:响应一个完整的jsp页面
- ajax:响应需要的数据
- 客户端处理方式不同:
- 传统:需要等待服务器完成响应并且加载整个页面后,用户才能进行后续的操作
- ajax:动态更新页面中的局部内容,不影响用户的其他操作
12.2 ajax的原理
12.2 基于JQuery的ajax语法
$.ajax({属性})
常用的属性参数
url:请求的后代服务地址
type:请求方式,默认get
data:请求参数
dataType:服务器返回的数据类型,text/json 传输对象用JSON
success:请求成功的回调函数
error:请求失败的回调函数
complete:请求完成的回调函数(无论成功失败都会调用)
JSON
Javascipt Object Notation,一种轻量级数据交互格式,完成js与java等后端开发语言对象数据之间的转换
客户端和服务器之间传递对象数据,需要用JSON格式
导入转换的jar包:有四种json的包,看情况用
commons-beanutils-1.8.0.jar
commons-collections-3.2.1.jar
commons-lang-2.4.jar
commons-logging.jar
ezmorph-1.0.6.jar
json-lib-2.4-jdk15.jar
或是导入依赖。。
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.3</version> <classifier>jdk15</classifier></dependency>
描述对象:
var 对象名 = { id = .., name = .. , .....}
使用
package com.example.entity;
public class User {
private Integer id;
private String name;
private Double score;
public User(Integer id, String name, Double score) {
this.id = id;
this.name = name;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
}
package com.example.demo3;
import com.example.entity.User;
import net.sf.json.JSONObject;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/test")
public class Test extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
User user = new User(1, "张三", 45.0);
resp.setCharacterEncoding("UTF-8");
// 需要将对象转成json
JSONObject jsonObject = JSONObject.fromObject(user);
resp.getWriter().write(String.valueOf(jsonObject));
}
}
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/10 0010 Time: 15:28 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title> <script src="js/jquery-3.6.0.min.js"></script> <%-- 测试有没有生效--%> <script> $(function () { const btn = $("#btn"); btn.click(function () { $.ajax({ url: "/test", type: "POST", dataType: "json", success: function (data) { const id = $("#id"); const name = $("#name"); const score = $("#score"); id.attr("value",data.id) name.attr("value",data.name) score.attr("value",data.score) }, error: function () { alert("服务器维护。。。") }, complete: function () { alert("请求成功") } }) }) }) </script></head><body>编号:<input id="id" type="text"><br>姓名:<input id="name" type="text"><br>成绩:<input id="score" type="text"><br><%--<input id="text" type="text" value=""><br>--%><input id="btn" type="button" value="提交"></body></html>
12.3代码
package com.example.demo3;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;@WebServlet("/location")public class LocationServlet extends HttpServlet { private static final Map<String, List<String>> cityMap; private static final Map<String,List<String>> provinceMap; static { cityMap = new HashMap<>(); List<String> areas = new ArrayList<>(); //⻄安 areas.add("雁塔区"); areas.add("莲湖区"); areas.add("新城区"); cityMap.put("⻄安市",areas); //宝鸡 areas = new ArrayList<>(); areas.add("陈仓区"); areas.add("渭宾区"); areas.add("新城区"); cityMap.put("宝鸡市",areas); //渭南 areas = new ArrayList<>(); areas.add("临渭区"); areas.add("⾼新区"); cityMap.put("渭南市",areas); //郑州 areas = new ArrayList<>(); areas.add("郑州A区"); areas.add("郑州B区"); cityMap.put("郑州市",areas); //洛阳 areas = new ArrayList<>(); areas.add("洛阳A区"); areas.add("洛阳B区"); cityMap.put("洛阳市",areas); provinceMap = new HashMap<>(); List<String> cities = new ArrayList<>(); cities.add("⻄安市"); cities.add("宝鸡市"); cities.add("渭南市"); provinceMap.put("陕⻄省",cities); cities = new ArrayList<>(); cities.add("郑州市"); cities.add("洛阳市"); cities.add("开封市"); provinceMap.put("河南省",cities); cities = new ArrayList<>(); cities.add("南京市"); cities.add("苏州市"); cities.add("南通市"); provinceMap.put("江苏省",cities); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { String type = req.getParameter("type"); resp.setCharacterEncoding("UTF-8"); String id = req.getParameter("id"); switch (type){ case "city": List<String> areas = cityMap.get(id); JSONArray jsonArray = JSONArray.fromObject(areas); resp.getWriter().write(jsonArray.toString()); break; case "province": List<String> cities = provinceMap.get(id); String city = cities.get(0); List<String> cityAreas = cityMap.get(city); Location location = new Location(); location.setCities(cities); location.setAreas(cityAreas); JSONObject jsonObject = JSONObject.fromObject(location); resp.getWriter().write(jsonObject.toString()); break; } }}
package com.example.demo3;import java.util.List;public class Location { private List<String> cities; private List<String> areas; public List<String> getCities() { return cities; } public void setCities(List<String> cities) { this.cities = cities; } public List<String> getAreas() { return areas; } public void setAreas(List<String> areas) { this.areas = areas; }}
<%-- Created by IntelliJ IDEA. User: 童泽沼 Date: 2021/6/11 0011 Time: 9:58 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" %><html><head> <title>Title</title> <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script> <script type="text/javascript"> $(function(){ //修改省份 $("#province").change(function () { const id = $(this).val(); $.ajax({ url:"/location", type:"POST", data:"id="+id+"&type=province", dataType:"JSON", success:function(data){ let i; let content = ""; const cities = data.cities; for(i = 0; i<cities.length; i++){ content += "<option>"+cities[i]+"</option>"; } $("#city").html(content); content = ""; var areas = data.areas; for(i = 0; i<areas.length; i++){ content += "<option>"+areas[i]+"</option>"; } $("#area").html(content); } }); }); //修改城市 $("#city").change(function(){ var id = $(this).val(); $.ajax({ url:"/location", type:"POST", data:"id="+id+"&type=city", dataType:"JSON", success:function(data){ var content = ""; for(var i=0;i<data.length;i++){ content += "<option>"+data[i]+"</option>"; } $("#area").html(content); } }); }); }); </script></head><body>省:<select id="province"> <option value="陕⻄省">陕⻄省</option> <option value="河南省">河南省</option> <option value="江苏省">江苏省</option></select>市:<select id="city"> <option value="⻄安市">⻄安市</option> <option value="宝鸡市">宝鸡市</option> <option value="渭南市">渭南市</option></select>区:<select id="area"> <option>雁塔区</option> <option>莲湖区</option> <option>新城区</option></select></body></html>
13. JDBC
java DataBase Connectivity 是一个独立于特定数据库的管理系统,通用的SQL数据库存取和操作的公共接口。
定义了一组标准,为访问不同数据库提供了统一的途径
13.1 JDBC体系结构
JDBC接口包括两个层面:
- 面向应用的API,供程序员调用
- 面向数据库的API,供厂商开发数据库的驱动程序
13.2 JDBC的使用
- 加载数据库驱动
- 获取Connection,java程序与数据库的一次连接
- 创建Statement对象,由Connection产生。执行SQL语句
- 接收返回值,创建ResultSet对象,接收查询的结果
package com.southwid.test;import java.sql.*;import java.text.SimpleDateFormat;import java.util.Date;public class Test { public static void main(String[] args) throws InterruptedException { try { // 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver");// 获取连接 String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";// 用户名 密码 String user = "root"; String password = "123456";// 管理驱动DriverManager Connection constant = DriverManager.getConnection(url, user, password); String sql = "insert into table_name(name,score) value('张三',52.5)"; Statement statement = constant.createStatement(); int i = statement.executeUpdate(sql); String select = "select * from table_name"; Statement tat = constant.createStatement(); ResultSet resultSet = tat.executeQuery(select); while (resultSet.next()){ final int id = resultSet.getInt("id"); final String name = resultSet.getString("name"); final double score = resultSet.getDouble("score"); System.out.println(id+name+score); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } }}
13.3 preparedStatement
Statement的子类,提供占位符功能
使用Statement进行开发有两个问题:
- 需要频繁拼接String字符串,出错率高
- 存在SQL注入风险
package com.southwid.test;import java.sql.*;public class login { public static void main(String[] args) { try {// Class.forName("com.mysql.cj.jdbc.Driver"); // 获取连接 String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";// 用户名 密码 String user = "root"; String password = "123456";// 管理驱动DriverManager Connection constant = DriverManager.getConnection(url, user, password); String select = "select * from table_name where name=?"; PreparedStatement statement = constant.prepareStatement(select); statement.setString(1, "张三74"); final ResultSet resultSet = statement.executeQuery(); if (resultSet.next()){ System.out.println("成功"); }else { System.out.println("失败"); } } catch (SQLException e) { e.printStackTrace(); } }}
13.4 JDBC+JSP+Servlet 结合使用
package com.example.entity;public class Student { private Integer id; private String name; private Double score; public Student(Integer id, String name, Double score) { this.id = id; this.name = name; this.score = score; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getScore() { return score; } public void setScore(Double score) { this.score = score; } @Override public String toString() { return getId()+getName()+getScore(); }}
package com.example.filter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import java.io.IOException;@WebFilter("/jdbc")public class Filter implements javax.servlet.Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); filterChain.doFilter(servletRequest, servletResponse); }}
package com.example.repository;import com.example.entity.Student;import com.example.utli.JDBCUtil;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;public class StudentRepository { public List<Student> findAll() { PreparedStatement statement = null; ResultSet resultSet = null; Connection connection = null; List<Student> list = new ArrayList<>(); try { String sql = "select * from table_name"; connection = JDBCUtil.getConnection(); statement = connection.prepareStatement(sql); resultSet = statement.executeQuery(); while (resultSet.next()) { Integer id = resultSet.getInt(1); String name = resultSet.getString(2); Double score = resultSet.getDouble(3); Student student = new Student(id, name, score); list.add(student); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.close(resultSet, statement, connection); } return list; } public void add(String name, Double score) { Connection connection = null; PreparedStatement statement = null; try { String sql = "insert into table_name(name,score) value(?,?)"; connection = JDBCUtil.getConnection(); statement = connection.prepareStatement(sql); statement.setString(1, name); statement.setDouble(2, score); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.close(null, statement, connection); } } public void delete(Integer id) { Connection connection = null; PreparedStatement statement = null; try { String sql = "delete from table_name where id = ?"; connection = JDBCUtil.getConnection(); statement = connection.prepareStatement(sql); statement.setInt(1, id); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.close(null, statement, connection); } } public Student updateId(Integer id) { PreparedStatement statement = null; ResultSet resultSet = null; Connection connection = null; Student student = null; try { String sql = "select * from table_name where id = ?"; connection = JDBCUtil.getConnection(); statement = connection.prepareStatement(sql); statement.setInt(1, id); resultSet = statement.executeQuery(); while (resultSet.next()) { Integer iad = resultSet.getInt(1); String name = resultSet.getString(2); Double score = resultSet.getDouble(3); student = new Student(iad, name, score); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.close(resultSet, statement, connection); } return student; } public void update(Integer id , String name , Double score){ Connection connection = null; PreparedStatement statement = null; try { String sql = "update table_name set name = ? ,score = ? where id = ?"; connection = JDBCUtil.getConnection(); statement = connection.prepareStatement(sql); statement.setInt(3, id); statement.setString(1, name); statement.setDouble(2, score); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.close(null, statement, connection); } }}
package com.example.servlet;
import com.example.entity.Student;
import com.example.repository.StudentRepository;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/jdbc")
public class StudentServlet extends HttpServlet {
StudentRepository repository = new StudentRepository();;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method == null){
method = "findAll";
}
switch (method){
case "delete":
String id = req.getParameter("id");
Integer i = Integer.parseInt(id);
repository.delete(i);
resp.sendRedirect("/jdbc");
break;
case "updateId":
String d = req.getParameter("id");
Integer ir = Integer.parseInt(d);
final Student student = repository.updateId(ir);
req.setAttribute("student", student);
req.getRequestDispatcher("update.jsp").forward(req, resp);
break;
case "findAll":
// 返回视图加数据
List<Student> list = repository.findAll();
req.setAttribute("list", list);
req.getRequestDispatcher("index.jsp").forward(req, resp);
break;
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String method = req.getParameter("method");
switch (method){
case "add":
String name = req.getParameter("name");
String score = req.getParameter("score");
Double a = Double.parseDouble(score);
repository.add(name, a);
break;
case "update":
final String id = req.getParameter("id");
Integer i = Integer.parseInt(id);
final String name1 = req.getParameter("name");
final String score1 = req.getParameter("score");
Double d = Double.parseDouble(score1);
repository.update(i, name1, d);
break;
}
resp.sendRedirect("/jdbc");
}
}
package com.example.utli;
import java.sql.*;
public class JDBCUtil {
static Connection connection = null;
static String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
static String user = "root";
static String password = "123456";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
public static void close(ResultSet resultSet , Statement statement,Connection connection){
if (resultSet !=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/13 0013
Time: 20:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/jdbc" method="post">
姓名:<input type="text" name="name"><br>
成绩:<input type="text" name="score"><br>
<input type="hidden" name="method" value="add">
<input type="submit" value="添加">
</form>
</body>
</html>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1>学生管理系统</h1>
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>成绩</th>
<th colspan="2">操作</th>
</tr>
<c:forEach items="${list}" var="student">
<tr>
<td>${student.id}</td>
<td>${student.name}</td>
<td>${student.score}</td>
<td><a href="/jdbc?method=delete&id=${student.id}">删除</a></td>
<td><a href="/jdbc?method=updateId&id=${student.id}">修改</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: 童泽沼
Date: 2021/6/13 0013
Time: 20:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/jdbc" method="post">
编号:<input type="text" name="id" value="${student.id}" readonly><br>
姓名:<input type="text" name="name" value="${student.name}"><br>
成绩:<input type="text" name="score" value="${student.score}"><br>
<input type="hidden" name="method" value="update">
<input type="submit" value="修改">
</form>
</body>
</html>
13.5 数据库连接池
数据库连接池的基本思想:为数据库创建一个缓冲池,预先向缓冲池中放入一定数量的连接对象,当需要获取数据库连接对象的时候,只需要从缓冲池中取出一个对象,用完再还回去,供下一次使用,做到了资源的重复利用,允许程序重复使用一个现有的数据库连接对象,而不需要重复创建。
当数据库连接池中没有空闲的连接时,其他请求就会加入等待队列
13.5.1 数据库连接池的实现
记得放在这个文件夹,切记切记
14. DBUtil
依赖:
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
也可以导入jar包
DBUtil可以帮助开发者完成数据的封装(结果集到java对象的映射)
ResultHandler接口用来处理结果集,可以将查询的结果集转成java对象,提供了4种实现类。
- BeanHandler 将结果集映射成java对象
- BeanListHandler 将结果集映射成List集合list
- MapHandler 将结果集映射成Map对象
- MsplistHandler 将结果集映射成MapList集合
- 注意:模板类里面一定要加无参构造,因为是提供反射创建对象的
public static Student findDB(){
Student student = null;
Connection connection = null;
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
connection = dataSource.getConnection();
String sql = "select * from table_name";
// 实例化
QueryRunner queryRunner = new QueryRunner();
// 参数:连接对象 sql语句 接创建一个系统给的类接收结果集.类里面传模板类 如果要使用占位符,只需要把在再加一个传进来的参数就行,按顺序写
student = queryRunner.query(connection,sql, new BeanHandler<>(Student.class));
System.out.println(student);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
return student;
}
package com.example.entity;public class Student { private Integer id; private String name; private Double score; public Student(Integer id, String name, Double score) { this.id = id; this.name = name; this.score = score; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getScore() { return score; } public void setScore(Double score) { this.score = score; } @Override public String toString() { return getId()+getName()+getScore(); } public Student() { }}
15. MVC结构
是一种开发模式,将程序分层的一种思想
M:Model 业务数据(servcie(业务),repository(数据库交互),entity(结果))
V:View 视图(JSP,HTML,APP客户端)
C:Controller 控制(Servlet,Handler,Action)