JavaWeb
【完成周期23-5-5-------23-5-22】
Web服务器
1. 技术讲解
1.1ASP
- 属于微软的,在html中嵌入VB脚本,常用c#,代码过于混乱
1.2PHP
- 开发速度快,功能强大,跨平台,代码简单
- 无法承载访问量大的情况(局限)
1.3JSP/Servlet
- 使用B/S架构,浏览器服务器,可以承担三高问题(高可靠,高并发,高性能)
2.WEB服务器
概念:处理用户请求并给用户相应的响应
静态web:资源 不变,无法与数据库交互
动态web:显示资源因人而异,可以与数据库交互
2.1Tomcat
-
安装包下的文件夹含义
tomcat系统各个文件夹目录是什么意义: bin:放置的是Tomcat一些相关的命令,启动的命令(startup)和关闭的命令(shutdown)等等 conf:(configure)配置文件 lib:(library)库,依赖的 jar包 logs:Tomcat 的日志文件 temp:Tomcat的临时文件夹 webapps:可执行的项目。默认作为存放开发项目的目录 work:存放由 jsp翻译成的 .java源文件以及编译的 .class字节码文件(jsp -->java -->class)
-
Tomcat 配置环境变量:点击startup.bat启动tomcat服务器【需要配置环境变量】
·
- IIS
3. HTTP
3.1 什么是超文本
使用超链接将不同空间位置的文本信息链接到一起
3.2 两个版本
- 1.0 浏览器请求服务器单个资源,服务器返回资源完 便断开连接
- 2.0 浏览器可请求服务器多个资源,服务器返回资源后 不会断开连接,需主动断开,或者双方都空余一段时间后自己断开连接
3.3HTTP请求
-
请求行
-
POST /examples/servlets/servlet/RequestParamExample HTTP/1.1
- Get :高效,有大小限制,会在地址栏显示,不安全
- POST:不高效,没有大小限制,不会在地址栏显示,安全
-
请求头
Accept:客户端向服务器端表示,我能支持什么类型的数据。
Referer:真正请求的地址路径,全路径
Accept-Language:支持语言格式
User-Agent:用户代理向服务器表明,当前来访的客户端信息。
Content-Type:提交的数据类型。经过urlencoding编码的form表单的数据
Accept-Encoding:压缩算法 。
Connection:保持连接
Cache-Control:对缓存的操作 -
请求体
- name=“abc”&password=“123”
3.4HTTP响应
-
响应行
-
响应状态码
- 2xx 成功
- 3xx 重定向
- 4xx网页不存在
- 5xx 服务器错误 502网关错误
-
HTTP/1.1 200 OK
-
-
响应头
Server:服务器是哪一种类型。Tomcat
Content-Type:服务器返回给客户端你的内容类型
Content-Length:返回的数据长度
Date:通讯的日期,响应的时间 -
响应体
- 就是接口返回的数据的类型,一般是json串
4.Maven
4.1 Maven是什么?
Maven是一个项目管理的工具,可以对项目进行构建、依赖的管理。我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率
4.1.1 Maven与IDEA版本对应表
注意:针对一些老项目 还是尽量采用 3.6.3版本,针对idea各个版本的兼容性就很兼容
0.IDEA 2022 兼容maven 3.8.1及之前的所用版本
1.IDEA 2021 兼容maven 3.8.1及之前的所用版本
2.IDEA 2020 兼容Maven 3.6.3及之前所有版本
3.IDEA 2018 兼容Maven3.6.1及之前所有版本
4.2 Maven安装
-
下载地址:https://maven.apache.org/download.cgi
-
环境变量配置
-
添加MAVEN_HOME ,其对应的值为
-
将MAVEN_HOME 添加到PATH中去
-
环境变量配置完测试
-
4.3 添加阿里云镜像
mirrors:加速下载
<mirror>
<id>central</id>
<name>central</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
添加到conf–>settings.xml中去
4.4 本地仓库
<localRepository>E:\JavaWeb\Maven\apache-maven-3.9.1\maven-repo </localRepository>
建立一个本地仓库 localRepository
4.5 在IDEA中使用MAVEN
- 创建maven项目
-
观察maven仓库中多了什么?
-
在idea中配置maven【idea项目创建时需要注意这个位置】
-
4.6 问题
-
解决Maven 在pom.xml的build中配置resources,来防止我们资源导出失败的问题
<build> <resources> <resource> <!-- 设定主资源目录 --> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
5.servlet
5.1 servlet 简介
servlet 是sun 公司开发动态web的一项技术。
servlet有两个实现类:HttpServlet,GenericServlet
sun在API【应用程序接口】上提供了一个接口sevlet,开发servlet程序的步骤。
- 编写一个实现了servlet接口的java程序。
- 把开发好的java类部署到web 服务器上。
servlet:实现了servlet接口的java程序。
5.2 HelloServlet
操作流程:创建一个普通的maven项目-----删除src目录------在父项目中创建一个带有web的maven项目
在子项目中的操作
- 创建java类实现servlet接口
package com.lumos.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter(); // 相应流
writer.write("Welcome To Servlet!");
writer.print("HHHHHHHH----HHHHHH");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 编写Servlet映射
为什么需要映射:我们所写的是java程序,需要通过浏览器来访问程序,而浏览器需要连接web服务器,所以需要在web服务器中注册我们所写的servlet,还需要给一个浏览器访问的路径
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <!-- 注册servlet --> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.lumos.servlet.HelloServlet</servlet-class> </servlet> <!-- servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
- 配置Tomcat
-
启动与测试
启动Tomcat即可—自动打开网站
问题
问题1:子项目中没有出现src目录
解决方法:添加 -Darchetype=Internal 这条语句,然后重新创建子项目
- 问题2:解决tomcat控制台是乱码的问题
将UTF-8 设置为GBK就可以了
5.3 Servlet原理
5.4 映射Mapping 注意事项
优先级问题:有特定的匹配则优先匹配,没有则默认匹配【按照通配符】
-
一个servlet对应一个映射路径
<!-- servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
一个servlet对应多个映射路径
<!-- servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <!-- servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <!-- servlet的请求路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping>
-
一个servlet对应通用映射路径
<!-- servlet的请求路径 【一个servlet对应通配 映射路径】 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
一个servlet对应默认的映射路径【不管输入什么都会映射到hello】
<!-- servlet的请求路径 【一个servlet对应一个映射路径】 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 一个servlet对应指定前缀或指定后缀 映射路径
<!-- servlet的请求路径 【一个servlet对应特定结尾映射路径】 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<!-- *.linxiaojun 表示必须以.linxiaojun结尾 -->
<url-pattern>*.linxiaojun</url-pattern>
</servlet-mapping>
-
定义错误网址所导向类
<!-- servlet的请求路径 【错误路径导向ErrorServlet类中】 --> <servlet> <servlet-name>Error</servlet-name> <servlet-class>com.lumos.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
package com.lumos.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class ErrorServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); PrintWriter writer = resp.getWriter(); writer.write("<h1>This is 404 Error From ErrorServlet!</h1>"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
5.5 ServletContext
-
什么是ServletContext
是基于Web容器和Servlet之间的中间件,可以对下面的Servlet进行管理;Web容器在启动的时候,会为每个应用程序创建一个相对应的ServletContext对象,其代表了当前的应用
-
作用
数据共享:不同servlet之间可以通信【getServletContext】
HelloServlet类
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("hello"); ServletContext context = this.getServletContext(); String username = (String) context.getAttribute("username"); resp.setContentType("text/html;charset=utf-8"); //这句话相当于下面两条语句;用于设置编码格式 // resp.setContentType("text/html"); // resp.setCharacterEncoding("utf-8"); resp.getWriter().write("name : "+username); } }
GetContext类
public class GetContext extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); //获取对象ServletContext context.setAttribute("username","林小军"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
**web.xml**
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.lumos.servlet.HelloServlet</servlet-class> <!-->对应数据类HelloServlet<--> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello00</url-pattern> </servlet-mapping> <!-->向serverletContext中存储数据<--> <servlet> <servlet-name>gc</servlet-name> <servlet-class>com.lumos.servlet.GetContext</servlet-class> <!-->对应数据类GetContext<--> </servlet> <servlet-mapping> <servlet-name>gc</servlet-name> <url-pattern>/getname</url-pattern> </servlet-mapping> </web-app>
测试结果:
- 获取初始化参数【getInitParameter】
GetServletParameters类
public class GetServletParameters extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().write(url); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
Web.xml
<!-- 自定义参数 --> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/test</param-value> </context-param> <!-- ServletContext获取参数 --> <servlet> <servlet-name>getPars</servlet-name> <servlet-class>com.lumos.servlet.GetServletParameters</servlet-class> </servlet> <servlet-mapping> <servlet-name>getPars</servlet-name> <url-pattern>/gp</url-pattern> </servlet-mapping>
测试结果
- 请求转发与重定向【getRequestDispatcher】
RequestDispatcher类
public class RequestDispatcher extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); //获取对象ServletContext // 将请求转发到/gp下,也就是GetServletParameters; javax.servlet.RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); requestDispatcher.forward(req,resp); System.out.println("进入了请求转发类。。。"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
web.xml
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>com.lumos.servlet.RequestDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/dispatcher</url-pattern> </servlet-mapping>
测试结果
-
获取配置文件
【resources和java 目录下的配置文件都是在classess目录下 getResouceAsStream()】
db.properties文件
username=root password=123 driver=jdbc:mysql://localhost:3306/test
public class GetServletProperties extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Properties prop = new Properties(); //下面这条语句是重点-----主要是获取流对象 ----从生成的target中进行获取! InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); prop.load(resourceAsStream); String name = prop.getProperty("username"); String pwd = prop.getProperty("password"); resp.getWriter().write("username: "+name+"\tpwd: "+pwd); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
web.xml
<servlet> <servlet-name>prop</servlet-name> <servlet-class>com.lumos.servlet.GetServletProperties</servlet-class> </servlet> <servlet-mapping> <servlet-name>prop</servlet-name> <url-pattern>/prop</url-pattern> </servlet-mapping>
测试结果
5.6 HttpServletResponse
Web服务器接受来自浏览器或客户端的HTTP请求,针对这个请求,服务器分别创建了代表请求的HttpServletRequest,以及代表响应的HttpServletResponse;
-
response 向浏览器发送响应的方式
ServletOutputStream out = resp.getOutputStream(); //图片,文件,视频用这个 PrintWriter writer = resp.getWriter(); //写中文,或文本用这个
-
HttpServletResponse中方法
void setDateHeader(java.lang.String s, long l); void addDateHeader(java.lang.String s, long l); void setHeader(java.lang.String s, java.lang.String s1); void addHeader(java.lang.String s, java.lang.String s1); void setIntHeader(java.lang.String s, int i); void addIntHeader(java.lang.String s, int i); void setStatus(int i);
3.HttpServletResponse中状态码
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
- 常见应用
-
- 下载文件功能
> * //核心代码
> //3.设置浏览器能支持 Content-Disposition 来下载我们所需要的东西
> *resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));*
package com.lumos.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.net.URLEncoder;
/**
* @Date : 2023-05-15 18:08
* @Author : linxiaojun
* @Desc : response-----文件下载【Content-Disposition,attachment;filename=】
* @En :
* @Att : 与底层的java输入输出流息息相关
*/
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.文件下载的路径
String filepath = "F:\\学科\\程序课程\\java\\Project\\JavaWeb\\javaweb-02-HelloServlet\\response\\src\\main\\resources\\code.txt";
System.out.println("下载的路径:" + filepath);
//2.获取文件的文件名
String filename = filepath.substring(filepath.lastIndexOf("\\") + 1);
//3.设置浏览器能支持 Content-Disposition 来下载我们所需要的东西,URLEncoder.encode(filename, "utf-8")可将汉字转化为UTF-8格式
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
// 4.创建输入流
FileInputStream fis = new FileInputStream(filepath);
//5.创建输出流
ServletOutputStream out = resp.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
//6.将读取的数据信息写入到response中去
while ((len = fis.read(buffer)) > 0)
out.write(buffer, 0, len);
fis.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
结果验证:
- **验证码功能 **
//清除浏览器的缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
package com.lumos.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Random;
/**
* @Date : 2023-05-15 20:11
* @Author : linxiaojun
* @Desc : response实现验证码功能
* @En :
* @Att :
*/
public class ImageServlet extends HttpServlet {
static String[] strs={"a","b","c","d","e","f","g","h","i","j","k","m","n",
"o","p","q","r","s","t","u","v","w","x","y","z","2","3","4","5","6","7","8","9"};
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器3s自动刷新一次
resp.setHeader("refresh","3");
//设置浏览器打开页面的格式
resp.setContentType("image/png");
//不让浏览器存在缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
int wid=150;//定义图片宽度
int hei=50;//定义图片高度
int x=25,y=35;
Random random=new Random();
//1.画板
BufferedImage image=new BufferedImage(wid,hei,BufferedImage.TYPE_INT_RGB);
//2.获取画笔的对象
Graphics g=image.getGraphics();
//3.设置画笔参数
g.setColor(Color.white);//设置填充颜色
g.fillRect(0,0,wid,hei);//填充矩形,覆盖原矩形
g.setColor(Color.red);//重新填充
g.setFont(new Font("楷体",Font.BOLD,25));
//4.画数字
for (int i = 0; i <4; i++) {
int num=random.nextInt(strs.length);
g.drawString(strs[num],x,y);
x+=30;
}
//5.画干扰线
for (int i = 0; i <3 ; i++) {
int x1=random.nextInt(30);
int y1=random.nextInt(50);
int x2=random.nextInt(30)+100;
int y2=random.nextInt(50);
g.drawLine(x1,y1,x2,y2);
}
//直接将验证码输出到浏览器
ImageIO.write(image,"png", resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
结果验证:
-
重定向功能
URL路径会发生改变
关键代码
resp.sendRedirect("./IdentifyingCode");
实现代码
package com.lumos.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @Date : 2023-05-17 10:05 * @Author : linxiaojun * @Desc : 实现重定向 * @En : * @Att : 区别重定向与请求转发的区别 */ public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("./IdentifyingCode"); //需要用.表示当前项目下 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
结果验证:
5.7 HttpServletRequest
-
重定向和转发的区别?
-
相同点:都能跳转页面
-
不同点:请求转发的时候,URL不会发生变化 307
重定向的时候,URL会发生变化 302
-
package com.lumos.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
/**
* @Date : 2023-05-18 10:31
* @Author : linxiaojun
* @Desc :request 实现用户登录,登录成功后跳转到成功的页面
* @En :
* @Att :
*/
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println(username+":"+password+"\n"+ Arrays.toString(hobbies));
//请求转发到另一个界面
req.getRequestDispatcher("./success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
6. Cookie && Session
6.1 什么是会话?
会话:用户打开一个浏览器,在浏览器中点开n多超链接,然后关闭浏览器,这个过程可以称之为会话
有状态会话:来过一次后续就知道该同学来过
6.2 实现会话的两种技术
- Cookie:应用于客户端
- Session:应用于服务端
6.3 Cookie
Tip
- 服务器响应客户端cookie
- 一般保存在本地用户appdata目录下
- 一个cookie最多保存一个信息,最多发送20个cookie
- 每一个cookie大小限制为4kb
- 300个cookie浏览器上限
删除cookie
- 不设置cookie有效期 【关闭浏览器时cookie自动删掉】
- 设置cookie有效期为0【cookie.setMaxAge(0)】
编码和解码的问题
URLEncoder.encode("abc","utf-8") URLDecoder.decode("abc","utf-8")
package com.lumos.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.util.Date;
/**
* @Date : 2023-05-18 11:54
* @Author : linxiaojun
* @Desc : cookie的使用
* @En :
* @Att : 1.编码和解码的问题
* URLEncoder.encode("abc","utf-8")
* URLDecoder.decode("abc","utf-8")
* 2. cookie是键值对
* 3.解决中文乱码:req.setCharacterEncoding("utf-8")
resp.setCharacterEncoding("UTf-8");
*/
public class cookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取cookie对象
Cookie[] cookies = req.getCookies();
for (int i = 0; i < cookies.length; i++) {
System.out.println(cookies[i]);
if (cookies != null) {
if (cookies[i].getName().equals("lastLoginTime")) {
//输出时间
Long time = Long.parseLong(cookies[i].getValue());
Date date = new Date(time);
resp.getWriter().write("\nLast Login Time:" + date.toLocaleString());
}
} else {
resp.getWriter().write("This is your first time come here!\n");
}
Cookie ck = new Cookie("lastLoginTime", "" + System.currentTimeMillis());
ck.setMaxAge(1000); // 设置有效时间【保存在浏览器的时间】
resp.addCookie(ck);//添加cookie
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
6.4 Session
- 什么是session?
- 服务器会为每个浏览器创建一个session对象,存在周期为只要浏览器未关闭即存在,且一个session独占一个浏览器
- 配置session失效时间
<!-- 使用配置文件来配置session失效时间 -->
<session-config>
<!-- 配置默认失效时间,以分钟为单位 -->
<session-timeout>1</session-timeout>
</session-config>
- 手动注销session
package com.lumos.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;
/**
* @Date : 2023-05-18 20:56
* @Author : linxiaojun
* @Desc : 手动注销session
* @En :
* @Att :
*/
public class SessionDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//防止编码错误
req.setCharacterEncoding("utf-8");
resp.setContentType("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取session
HttpSession session = req.getSession();
//手动配置session失效
session.removeAttribute("name");
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
6.5 session 与 cookie的区别?
- cookie是把数据存储到用户的浏览器中,浏览器可以同时保存多个
- session 是把数据存储到用户独占的session中,服务器端保存
7.JSP
7.1 什么是JSP
JSP:JAVA Server Pages java服务器端页面,与servlet一样,用于动态web技术
特点:可以在jsp中嵌套java语言,与写HTML类似
7.2 JSP原理
7.3 环境搭建【添加依赖】
<?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>org.example</groupId>
<artifactId>javaweb-04-jsp</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<!-- servlet依赖-->
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- servlet.jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- jstl表达式的依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库依赖 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
</project>
7.4 JSP语法
-
JSP表达式
<%-- jsp表达式,作用: 程序的输出,输出到客户端 --%> <%=new Date()%>
-
JSP代码片段
<%-- 2.jsp脚本片段 --%> <% int sum=0; for (int i = 0; i < 10; i++) { sum+=i; } out.print("和为:"+sum); %>
-
JAVA代码中嵌入HTML
<%-- 3.在java代码中嵌入html --%> <% for (int i = 0; i < 10; i++) { %> <h1 align="center">hello , world <%=i%> </h1> <%}%>
-
JSP 的声明:jsp声明会被编译到java类中,而其他的都被编译到service方法中
<%--4.jsp声明--%> <%! static { System.out.println("进入了静态块中"); } private int count=0; public void test(){} %>
7.5 JSP指令
使用<%@include file=args %> 是把引入的文件合成一个
<%@include file="header.jsp"%>
<h1>这是网站主题</h1>
<%@include file="footer.jsp"%>
采用jsp的方式是将引入的文件作为一个独立的文件处理的
<jsp:include page="header.jsp"></jsp:include>
<h1>This is the body of webside</h1>
<jsp:include page="footer.jsp"></jsp:include>
7.6 九大内置对象
- PageContext 【可存东西】
- Request 【可存东西】
- Response
- Session 【可存东西】
- Application 【可存东西】
- Config
- out
- Page
- Exception
<%
pageContext.setAttribute("name1","李学年1"); //请求的数据在当前页面有效
request.setAttribute("name2","李学年2");//请求的数据在一次请求中有效,请求转发时会携带这个数据
session.setAttribute("name3","李学年3");//请求的数据在一次会话中有效,也就是打开浏览器到关闭
application.setAttribute("name4","李学年4");//请求的数据在整个服务器中有效,服务器的打开到关闭
System.out.println("----------------");
//可以按照下面的方法【利用最后一个参数的不同】来代替上面的方法
// pageContext.setAttribute("name4","abc",PageContext.APPLICATION_SCOPE);
%>
7.7 JSP标签,JSTL标签 ,EL表达式
-
EL标签【${}】作用:
- 获取数据
- 执行运算
- 获取web开发对象
-
JSP 标签
<h1>This is jspTag pages</h1> <jsp:forward page="jspTag2.jsp"> <jsp:param name="name" value="lumos"></jsp:param> <jsp:param name="age" value="18"></jsp:param> </jsp:forward>
-
JSTL标签
JSTL标签库的组成部分
>核心标签库: core, 简称c
>格式化标签库: format, 简称fmt
>函数标签库: function, 简称fn
核心标签
核心标签库导入的语句为: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
-
TIP:在tomacat的lib目录下也需要导入standard和jstl的jar包
-
c_foreach
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% ArrayList<String> list = new ArrayList<>(); list.add("李四"); list.add("张三"); list.add("王五"); list.add("赵六"); list.add("六七"); request.setAttribute("lis",list); %> <%--********* --%> <c:forEach var="abc" items="${lis}" begin="1" step="2"> <c:out value="${abc}"/><br> </c:forEach> </body> </html>
-
c_if
<%@ 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> <h3>This is jstlCore test pages</h3> <form action="jstlCore.jsp" method="get"> <input name="username" value="${param.username}"> <input type="submit" value="submit"> </form> <c:if test="${param.username=='admin'}" var="isAdmin"> <c:out value="YES,admin 欢迎你 "/> </c:if> <%--自闭合标签--%> <c:out value="${isAdmin}"/> </body> </html>
-
-
7.8 servlet 与JSP的异同点
序号 | servlet | JSP |
---|---|---|
1 | 是在java中嵌套html代码,支持html标签 | 在html中嵌套java代码,支持java语言 |
2 | 用于业务层处理逻辑 | 用于展示层显示数据 |
3 | 修改后需重新编译部署 | 修改后不需重新编译以及运行 |
8.MVC三层架构
8.1 什么是MVC
model【包含entity,dao,service,操作】 view【展示】 controller【中间件】
9.Filter过滤器
9.1 什么是过滤器?
用来过滤网站中的数据
- 处理字符的乱码
- 登录验证
- 处理垃圾请求
开发步骤
-
导包
-
实现接口
package com.lumos.filter; import javax.servlet.*; import java.io.IOException; /** * @Date : 2023-05-21 18:38 * @Author : linxiaojun * @Desc : filter实现请求自动编码 */ public class CharEncodingFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { System.out.println("filter 初始化"); } 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("filter执行前"); filterChain.doFilter(servletRequest,servletResponse); //*****这句话是关键 System.out.println("filter执行后"); } public void destroy() { System.out.println("filter销毁"); } }
web.xml注册filter <filter> <filter-name>charEncodingFilter</filter-name> <filter-class>com.lumos.filter.CharEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>charEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
10.监听器
实现步骤
-
实现接口
package com.lumos.listener; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * @Date : 2023-05-21 19:35 * @Author : linxiaojun * @Desc :使用HTTPSessionListener监听器在网站中统计在线人数 * @En : * @Att : */ public class OnlinePeopleCount implements HttpSessionListener { public void sessionCreated(HttpSessionEvent hse) { ServletContext sc = hse.getSession().getServletContext(); System.out.println(hse.getSession().getId()); Integer count = (Integer) sc.getAttribute("OnlinePeopleCount"); if(count==null){ count=new Integer(1); }else{ int i = count.intValue(); count=new Integer(i+1); } sc.setAttribute("OnlinePeopleCount",count); } public void sessionDestroyed(HttpSessionEvent hse) { ServletContext sc = hse.getSession().getServletContext(); System.out.println("销毁:"+hse.getSession().getId()); Integer count = (Integer) sc.getAttribute("OnlinePeopleCount"); if(count==null){ count=new Integer(0); }else{ int i = count.intValue(); count=new Integer(i-1); } hse.getSession().invalidate(); sc.setAttribute("OnlinePeopleCount",count); } }
-
web.xml中配置
<listener> <listener-class>com.lumos.listener.OnlinePeopleCount</listener-class> </listener>
-