1,基本概念
1.1,web应用程序
一个web应用有多部分组成(静态web,动态web)
- html,css,js
- jsp,servlet
- java程序
- jar包
- 配置文件(Properties)
web应用程序编写完毕后,若想提供给外界访问,需要一个服务器来统一管理
1.2,静态web
*.htm,
*.html,这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取,通络
存在缺点:
web无法动态更新,所有用户看到的都是统一个页面
- 轮播图,点击特效:伪动态
- js[实际开发中,他用的最多]
- vbscript
他无法与数据库交互(数据无法持久化,用户无法交互)
1.3,动态web
页面会动态展示:“web页面的展示效果会因人而异”
缺点:
假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,冲洗年发布
停机维护
优点:
- web页面可以动态更新,所有用户看到都不是同一个页面
- 它可以与数据库交互(数据持久化:注册,商品信息。。。。)
2,WEB服务器
2.1,技术详解
ASP:
- 微软:国内最早流行的就是ASP
- 在HTML中嵌入了VB脚本,ASP+COM
- 在ASP开发中,基本一个页面都有几千行的业务代码,页面及其混乱
- 维护成本高
- C#
- IIS
php:
- PHP开发速度很快,功能强大,跨平台,代码简单(70,WP)
- 无法承载大访问量的情况(局限性)
JSP/Servlet
B/S
C/S
- sun公司主推的B/S架构
- 机遇java语言的(所有的大公司,或者一些开源的组件,都是用java写的)
- 可以承载三高问题带来的影响
- 语法像ASP
2.2,web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些相应信息
IIS
微软的:ASP…windows中自带
Tomcat
3,Tomcat
3.1,下载
3.2,启动和配置
测试:http://localhost:8080/
可能遇到的问题:
1,java环境变量没配置
2,闪退问题:需要配置兼容性
3,乱码问题:配置文件中设置
3.3,配置
高级面试题:
请你谈谈网站是如何进行访问的!
1,输入一个域名,回车
2,检查本机的C:\Windows\System32\drivers\etc\hosts配置问价你有没有这个域名的映射;
1,有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
2,没有:去DNS服务器找,找到的话就返回,找不到就返回找不到
3.4,配置环境变量(可选)
3.5,发布一个web网站
将自己写的网站,放到服务器中指定的web应用的文件夹(webapps)下,就可以访问了
4,Http
4.1,什么是Http
超文本传输协议
- 文本:html,字符串。。。
- 超文本:图片,音乐,视频,定位,地图。。。
- 80
4.2,两个时代
- http1.0
- http1.0:客户端可以与web服务器连接后,值能获得一个web资源,断开连接
- http2.0
- http1.1:客户端可以与web服务器连接后,可以获得多个web资源
4.3,http请求
客户端–发请求(request)–服务器
1,请求行
- 请求行中的请求方:GET
- 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
get:请求能够携带的参数比较少,大小有限制,会在浏览器的url地址栏显示数据内容,不安全,但是高效
post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的url地址栏显示数据内容,安全,但是不高效
2,消息头
4.4,http响应
服务器–响应–客户端
1,响应体
2,响应状态码
5,Maven
为什么学习这个技术?
1,在javaweb开发中,需要使用大量的jar包,我们手动去导入;
2,如何能够让一个东西自动帮我们导入和配置这个jar包。
5.1,Maven项目价格管理工具
我们目前用来就是方便发乳jar包的!
Maven的核心思想:约定大于配置
有约束,不要去违反!
Maven会规定好你改如何取编写我们的java代码,必须要按照这个规范来
5.2,下载安装Maven
5.3,配置环境变量
5.4,阿里云镜像
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public </url>
</mirror>
将这段代码复制到里面
5.5,本地仓库
建立一个本地仓库
localRepository
<localRepository>C:\environment\apache-maven-3.6.3-bin\apache-maven-3.6.3\maven-repo</localRepository>
5.6,在IDEA中使用Maven(第一次创建)
1,启动idea
2,创建一个MavenWeb项目
3,等待项目初始化完毕
出现bulid success即创建成功
4,IDEA中的Maven设置
idea项目创建成功后,要看一眼maven的配置
5,在这里,maven在idea中的配置就OK了!
5.7,创建一个普通的Maven项目
这个只有在web应用下才会有!
5.8,标记文件夹功能
或者使用项目结构配置
5.9,在IDEA中配置Tomcat
启动Tomcat
5.10,pom文件
pom.xml是maven的核心配置文件
5.11,idea操作
6,Servlet
6.1,什么是servlet?
- servlet是sun公司开发动态web的一门技术
- sun在这些api中提供一个接口叫做:servlet,如果你想开发一个servlet程序只需要两个步骤:
- 编写一个类,实现servlet接口
- 把开发好的java类部署到web服务器中
把实现了servlet接口的java程序叫做servlet
6.2,helloServlet
1,构建一个普通的maven项目,删掉里面的src目录
2,在pom.xml配置dependencies
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
3,创建子module
package 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.print("hello");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
4,编写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"
metadata-complete="true">
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
5,配置Tomcat
6,启动测试
6.3,Servlet原理
Servlet是由web服务器调用,web服务器在收到浏览器请求之后,会:
6.4,mapping
1,一个servlet可以指定一个映射路径
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2,一个servlet可以指定多个映射路径
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
3,一个servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
4,默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
4,指定一些后缀或者前缀等等。。。
<!--注意点:*前面不能加项目映射路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.cdd</url-pattern>
</servlet-mapping>
5,优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
6.5,ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
1,共享数据
我在这个servlet中保存的数据,可以在另一个servlet中拿到。
package servlet;
import javax.servlet.ServletContext;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username="tom";//数据
//将一个数据保存在ServletContext中,名字为user,值为username
context.setAttribute("user",username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
package servlet;
import javax.servlet.ServletContext;
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 GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
Object user = context.getAttribute("user");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字"+user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<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-name>hello</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
</web-app>
测试:
2,获取初始化参数
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost3306</param-value>
</context-param>
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
package servlet;
import javax.servlet.ServletContext;
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 ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
测试:
3,请求转发
package servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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 ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//转发的请求路径
// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");
//
// requestDispatcher.forward(req,resp);//调用forward实现请求转发
System.out.println("进入了demo04");
context.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
转发,重定向
4,读取资源文件
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为类路径。
package servlet;
import javax.servlet.ServletContext;
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.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(username+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
测试
6.6,HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象。代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应的一些信息:HttpServletResponse
1,简单分类
负责向浏览器发送数据的方法
负责向留言器发送响应头的方法
响应的状态码
重点记这几个
2,常见应用
1,向浏览器输出消息
2,下载文件
1,获取下载文件的路径
2,下载的文件名?
3,设置想办法让浏览器能够支持下载我们需要的东西
4,获取下载文件的输入流
5,创建缓冲区
6,获取OutoutStream对象
7,将FileOutputStream流写入到buffer缓冲区
8,使用OutputStream将缓冲区中的数据输出到客户端!
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;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1,获取下载文件的路径
//
String realPath = "C:\\Users\\19484\\Desktop\\it\\suorcefiles\\javaweb\\javaweb-01-servlet\\response-maven-01\\target\\response-maven-01\\WEB-INF\\classes\\1.png";
System.out.println("下载文件的路径:"+realPath);
// 2,下载的文件名?
//
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3,设置想办法让浏览器能够支持下载我们需要的东西
//
resp.setHeader("Content-Disposition","attachment;filename="+fileName);
// 4,获取下载文件的输入流
//
FileInputStream in = new FileInputStream(realPath);
// 5,创建缓冲区
//
int len=0;
byte[] buffer = new byte[1024];
// 6,获取OutoutStream对象
//
ServletOutputStream out = resp.getOutputStream();
// 7,将FileOutputStream流写入到buffer缓冲区
//
while ((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
// 8,使用OutputStream将缓冲区中的数据输出到客户端!
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
<servlet>
<servlet-name>filedown</servlet-name>
<servlet-class>FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filedown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
如果图片名字中含有中文,如下图设置解决该问题。
3,验证码功能
- 前端实现
- 后端实现,需要用到java图片类,生产一个图片
import com.sun.net.httpserver.HttpServer;
import javax.imageio.ImageIO;
import javax.naming.ldap.Control;
import javax.servlet.ServletException;
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.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器3s刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();//笔
//设置图片背景颜色
g.setColor(Color.WHITE);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
String s = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
<servlet>
<servlet-name>Image</servlet-name>
<servlet-class>ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Image</servlet-name>
<url-pattern>/image</url-pattern>
</servlet-mapping>
结果:每3s刷新新的7个数字
4,实现重定向(掌握)
B一个web资源受到客户端A请求后,B他会通知客户端A去访问另一个web资源,这个过程叫重定向
常见场景:用户登录
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 RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/response_maven_02_yanzhengma_warimg");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>Redirect</servlet-name>
<servlet-class>RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Redirect</servlet-name>
<url-pattern>/redirect</url-pattern>
</servlet-mapping>
6.7,HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过http协议访问服务器,http请求中所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;
1,获取前端传递的参数
package 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;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
String[] hobbies = req.getParameterValues("hobby");
System.out.println("======================");
System.out.println(username);
System.out.println(pwd);
System.out.println(Arrays.toString(hobbies));
//请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
<%--
Created by IntelliJ IDEA.
User: 19484
Date: 2021/2/28
Time: 17:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>login</title>
</head>
<body>
<div style="text-align: center">
<h1>login</h1>
<%-- 这里表单表示的意思:以post方式提交到我们的login请求--%>
<form action="${pageContext.request.contextPath}/login" method="post">
用戶名:<input type="text" name="username"><br>
密码:<input type="password" name="pwd"><br>
爱好:
<input type="checkbox" name="hobby" value="代码">代码
<input type="checkbox" name="hobby" value="唱歌">唱歌
<input type="checkbox" name="hobby" value="电影">电影
<br>
<input type="submit">
</form>
</div>
</body>
</html>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
2,请求转发
7,Cookie、Session
7.1,会话
**会话:**用户打开一个浏览器,点击了很多超链接,访问多个超链接,关闭浏览器,这个过程可以称之为会话。
**有状态会话:**一个同学来过教师,下次再来教室,我们会知道这个同学,曾经来过
你怎么证明你是某大学的学生?
你 某大学
1,发票 某大学给你的发票
2,学校登记 学校标记你来过了
一个网站,怎么证明你来过?
客户端 服务端
1,服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了,cookie
2,服务器登记你来过,下次你来的时候我匹配你,session
7.2,保存会话的两种技术
cookie
客户端技术(响应,请求)
session
服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把信息或者数据放在session中
常见场景:网站登录之后,你下次登录就可以直接登陆了
7.3,Cookie
1,从请求中拿到cookie信息
2,服务器响应给客户端cookie
cookie:一般会保存在本地的用户目录下appdata:
测试:获取上次访问时间
package 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.util.Date;
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器告诉你,你来的时间,把这个时间封装成一个信件,你下次带来,我就知道你来了
//解决中文乱码
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
PrintWriter out = resp.getWriter();
//Coookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies!=null)
{
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (Cookie cookie:cookies) {
System.out.println(cookie);
//获取cookie的名字
if ( cookie.getName().equals("lastTime")){
//获取cookie中的值
long l = Long.parseLong(cookie.getValue());
Date date = new Date(l);
out.write(date.toLocaleString());
}
}
}
else{
out.write("这是你第一次访问本网站!");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastTime", System.currentTimeMillis()+"");
cookie.setMaxAge(24*60*60);//cookie有效期为一天
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>CookieDemo01</servlet-name>
<servlet-class>servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo01</servlet-name>
<url-pattern>/cookie</url-pattern>
</servlet-mapping>
一个网站cookie是否存在上限!
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- cookie大小有限制4kb
- 300个cookie,浏览器上限
删除cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效时间为0
中文数据传递:
package 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.util.Date;
//中文数据传递
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
PrintWriter out = resp.getWriter();
//Coookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies!=null)
{
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (Cookie cookie:cookies) {
//获取cookie的名字
if ( cookie.getName().equals("name")){
//获取cookie中的值
out.write(cookie.getValue());
}
}
}
else{
out.write("这是你第一次访问本网站!");
}
Cookie cookie = new Cookie("name","汤姆");
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
如果遇到乱码问题:
package 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 CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
PrintWriter out = resp.getWriter();
//Coookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies!=null)
{
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (Cookie cookie:cookies) {
//获取cookie的名字
if ( cookie.getName().equals("name")){
//获取cookie中的值
//解码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
}
else{
out.write("这是你第一次访问本网站!");
}
//编码
Cookie cookie = new Cookie("name", URLEncoder.encode("汤姆","utf-8"));
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
7.4,Session(重点!!)
什么是session?
- 服务器会给每一个用户或游览器创建一个session对象
- 一个session独占一个浏览器,只有浏览器没有关闭,这个session一直存在
- 用户登录之后,整个网站它都可以访问–》保存用户信息,保存购物车信息
session和cookie区别
- cookie是吧用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- session吧用户的数据写到用户独占的session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- session对象由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 整个网站中经常会使用的数据,我们将它保存在session中
使用session:
package servlet;
import entity.Persom;
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 SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//给session存东西
session.setAttribute("name",new Persom("湯姆",20));
//获得session的id
String id = session.getId();
//判断session是不是新创建的
if (session.isNew()){
resp.getWriter().write("session创建成功,id为:"+id);
}else {
resp.getWriter().write("session已经在服务器中个存在了,id为:"+id);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
package servlet;
import entity.Persom;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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 {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//给session存东西
Persom name = (Persom) session.getAttribute("name");
System.out.println(name.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
package servlet;
import entity.Persom;
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 SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
<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-name>SessionDemo01</servlet-name>
<servlet-class>servlet.SessionDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo01</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionDemo02</servlet-name>
<servlet-class>servlet.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo02</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionDemo03</servlet-name>
<servlet-class>servlet.SessionDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo03</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>
<!-- 设置session默认失效时间-->
<session-config>
<!-- 15min后session自动失效,以min为单位-->
<session-timeout>15</session-timeout>
</session-config>
</web-app>
8,JSP
8.1,什么是JSP?
java server page:java服务器端页面,也和servlet一样,用于动态web技术开发。
最大特点:
- 写jsp就像在写html
- 区别:
- html只给用户提供静态的数据
- JSP页面中可以嵌入java代码,为用户提供动态数据
8.2,JSP原理
思路:jsp到底怎么执行的?
- 代码层面没有任何问题
- 服务器内部工作
- Tomcat中有一个work目录,idea中使用Tomcat的会在idea的Tomcat中产生一个work目录
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问servlet
jsp最终也会被转化为java类
jsp本质上就是servlet(看源码)
在jsp中:
只要是java代码就会原封不动的输出
如果是html代码,就会转换为:
这样的格式输出到前端。
8.3,JSP基础语法
java所有语法都支持
jsp表达式
<%--jsp表达式:用来将程序的输出,输出到客户端
<%=变量或者表达式%>
--%>
<%= new java.util.Date() %>
jsp脚本片段
<%--jsp脚本片段--%>
<%
int sum=0;
for (int i=1;i<100;i++) {
sum+=i;
}
out.println("<h1>sum="+sum+"</h1>");
%>
8.4,JSP指令
8.5,JSP 9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application【ServletContext】 存东西
- config【ServletConfig】
- out
- page 不用了
- exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
pageContext.setAttribute("name1","num1");//保存的数据只在一个页面中有效
request.setAttribute("name2","num2");//保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","num3");//保存的数据只在一次会话中有效,从打开游览器到关闭浏览器
application.setAttribute("name4","num4");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%--从pageContext取出,通过寻找的方式来--%>
<% //从底层到高层(作用域):page->request->session->application
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
%>
<h1>取出的值:</h1>
${name1 }
${name2 }
${name3 }
${name4 }
${name5 }
</body>
</html>
8.6,JSP标签、JSTL标签、EL表达式
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${ }
- 获取数据
- 执行运算
- 获取web开发的常用对象
- 调用java方法
jsp标签:
<%--<jsp:include page=""></jsp:include>--%>
<%--http://localhost:8080/jsptag.jsp?name=cdd&sex=boy--%>
<jsp:forward page="jsptag2.jsp">
<jsp:param name="name" value="cdd"/>
<jsp:param name="sex" value="boy"/>
</jsp:forward>
获取值:
name:<%=request.getParameter("name") %>
sex:<%=request.getParameter("sex") %>
jstl标签:
jstl标签库的使用就是为了弥补html标签的不足;他自定义许多标签,可以供我们使用,标签的功能和java代码一样!
核心标签(掌握部分)
使用步骤:
- 引入对应的taglib
<%--引入jstl核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- 使用其中的方法
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入jstl核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>if测试</h1>
<form action="coreif.jsp" method="get">
<%-- el表达式获取表单中的数据--%>
<%-- ${param.参数名}--%>
<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>
<c:out value="${isAdmin}"></c:out>
</body>
</html>
格式化标签
sql标签
xml标签
9,JavaBean
实体类
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射 ORM:
ORM:对象关系映射
- 表->类
- 字段->属性
- 行记录->对象
10,MVC三层架构
MVC: model view controler
10.1,早些年
用户直接访问控制层,控制层就可以直接操作数据库
10.2,MVC
11,Filter过滤器
Filter:用来过滤网站的数据
- 处理乱码
- 登录验证
package Filter;
import javax.servlet.*;
import java.io.IOException;
public class CEF implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("字符初始化");
}
/**Chain 链
1,过滤中的所有代码,在过滤特定请求的时候都会执行
2,必须要让过滤器继续同行
filterChain.doFilter(servletRequest,servletResponse);
*/
@Override
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执行后。。。");
}
//web服务器关闭的时候销毁
@Override
public void destroy() {
System.out.println("字符销毁");
}
}
package 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 Show extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("你好!安安生生多");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>Show</servlet-name>
<servlet-class>servlet.Show</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Show</servlet-name>
<url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CEF</filter-name>
<filter-class>Filter.CEF</filter-class>
</filter>
<filter-mapping>
<filter-name>CEF</filter-name>
<!-- 只要是/servlet的任何请求,会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12,监听器
实现监听器的接口:(有n种)
1,编写一个监听器
package listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计在线人数
public class OnlineCountListener implements HttpSessionListener{
//创建session监听,看你的一举一动
//一旦创建session就会触发一次这个事件
@Override
public void sessionCreated(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);
}
//销毁session监听
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext ctx = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount=new Integer(0);
}else {
int count=onlineCount.intValue();
onlineCount=new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
}
2,注册监听器
<listener>
<listener-class>listener.OnlineCountListener</listener-class>
</listener>
3,前端显示
<%@ 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>
4,结果:
13,过滤器,监听器常见应用
用户登录后才能进入主页,用户注销后不能进入
14,JDBC
1,jdbc
1,创建数据库并建一张表填入数据
2,导入数据库依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>
3,idea连接数据库
4,java代码(JDBC六部曲)
package test;
import java.sql.*;
public class jdbctest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/javaweb-jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT";
String username="root";
String password="123456";
//1,加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2,连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url,username,password);
//3,向数据库发送sql的对象statement:CRUD
Statement statement = connection.createStatement();
//4,编写sql
String sql="select * from student";
//5,执行查询sql,返回写个resultSet 结果集
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("name"));
System.out.println("sex="+resultSet.getObject("sex"));
System.out.println("age="+resultSet.getObject("age"));
}
//6,关闭连接,释放资源 先开启的后关闭
resultSet.close();
connection.close();
statement.close();
}
}
结果:
2,预编译
package test;
import java.sql.*;
public class jdbctest2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/javaweb-jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT";
String username="root";
String password="123456";
//1,加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2,连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url,username,password);
//3,编写sql
String sql="insert into student(id,name,sex,age)values(?,?,?,?)";
//4,预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,5);//给第一个占位符?的值赋值为5
preparedStatement.setString(2,"小李");
preparedStatement.setString(3,"男");
preparedStatement.setInt(4,21);
//执行sql
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
//6,关闭连接,释放资源 先开启的后关闭
preparedStatement.close();
connection.close();
}
}
3,事务
要么都成功,要么都失败
ACID原则
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
处学习记录,仅供学习与参考