JavaWeb
1、基本概念
web开发:
- web:网页
- 静态web
- `html,css
- 提供给所有人看的数据始终不会发生变化
- 动态web
- 举例:淘宝
- 信息随时发生变化
在java中,动态web资源开发的计数统称未javaWeb
1.2、web应用程序
web应用程序:可以提供浏览器访问的程序
- 一个web应用由多部分组成(静态web,动态web)
- html,css,js
- jsp,servlet
- java程序
- jar包
- 配置文件(properties)
1.3、静态web
- *.htm, *.html,如果服务器上存在,我们就可以读取
- 静态web存在的缺点
- web页面无法动态更新,所有用户看到都是同一页面
- 无法和数据库交互(数据无法持久化,用户无法交互)
1.4、动态web
页面会动态展示:“每个人看到的Web的页面都不一样”
缺点:
- 假如服务器的动态web资源出现了错误,需要重新编写后台程序,重新发布;
优点:
- Web页面可以动态更新
- 它可以与数据库交互
2、web服务器
2.1、技术讲解
ASP:
- 微软:国内最早流行的
- 在HTML中嵌入了VB的脚本,ASP+COM
- 维护成本高
- 基本C#语言
PHP:
- PHP开发速度很快,功能强大,跨平台,代码简单
- 无法承载大访问量情况(局限性)
JSP/Servlet:
B/S:浏览器和服务器
C/S:客户端和服务器
- SUN公司主推的B/S架构
- 基于java语言
- 高并发高可用,高性能
2.2、web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些相应信息;
Tomcat
IIS
微软的;ASP,window中自带的
3、发布一个网站
-
将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问
-
--webapps:Tomcat服务器的web目录 -ROOT -vekzjj:网站的目录名 -WEB-INF -classes:java程序 -lib:web应用所依赖的jar包 -web.xml:网站配置文件 -index.xml默认的首页 -static -css -style.css -js -img -....
4、HTTP
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
- 文本:html,字符串
- 超文本:图片,音乐,视频,定位,地图
- 端口:80
Https:安全的
- 端口:443
4.1、两个时代
- http1.0
- http/1.0:客户端可以与web服务器连接后,只能获得一个web次元,然后断开链接
- http20
- http/1.1:客户端可以与web服务器连接后,可以获得多个web资源
4.2、Http请求
- 客户端–>发请求–>服务器
百度:
请求 URL: https://www.baidu.com/
请求方法: GET
状态代码: 200 OK
远程地址: 220.181.38.149:443
引用站点策略: strict-origin-when-cross-origin
Accept:text/html
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 语言
Cache-Control: max-age=0
Connection: keep-alive
请求行:
- 请求行中的请求方式:GET
- 请求方式:Get,Post,Head,Delete
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址显示数据内容,不安全,但高效
- post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址显示数据内容,安全,但不高效
消息头:
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持的编码格式 GBK UTF-8 GB2312
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:链接情况
HOST:主机
4.3、Http响应
- 服务器–>响应–>客户端
百度:
Cache-Control: private 缓存控制
Connection: keep-alive 链接
Content-Encoding: gzip 编码
Content-Type: text/html 类型
相应体:
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持的编码格式 GBK UTF-8 GB2312
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:链接情况
HOST:主机
REFLRESH:告诉浏览器,多久可以刷新一次
Location:让网页重新定位
相应状态码:
200:请求相应成功
3xx:请求重定向
- 重定向:重新转向新的地址
404:找不到资源
5xx:服务器代码错误 500 502(网关错误)
常见面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
5、Maven
为什么要学这个技术?
1.在java项目中,要导入大量的jar包,
Maven可以帮我们导入和配置这个jar包
5.1、Maven项目架构管理工具
方便我们导入jar包
Maven的核心思想:约定大于配置
- 有约束,不要去违反
Maven会规定好你改如何去编写我们的java代码,必须要按照这个规范来1
5.2、配置环境变量
系统变量:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 去path里面配置:%MAVEN_HOME%\bin
测试maven安装是否成功:dos测试mvn -v
5.3、阿里云镜像
接下来我们需要配置maven镜像,如果我们不配置,我们下载jar包是从国外下载的,下载速度很慢,所以我们配置一下国内的阿里云镜像
配置方法:找到未在注释标签内的mirrors,大约在145行左右,接着我们往mirrors标签内添加阿里云镜像,然后保存
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
5.4、配置maven本地仓库
maven本地仓库也可以不配置,如果不配置,默认本地仓库地址为C:\Users\Administrator.m2\repository
配置方法:我们直接找到52行,然后复制第53行代码,粘贴到注释外面(必须粘贴到注释外面,不然是无效代码),最后把中间的路径修改成你自己创建的本地仓库路径就好了
<localRepository>/path/to/local/repo</localRepository>
<localRepository>D:\Maven\repository</localRepository>
5.5、IDEA中使用Maven
等待项目于自动导入包
5.5、在IDEA中配置Tomcat
5.5 、pom文件
pom.xml
6、Servlet
6.1、Servlet简介
- Servlet就是sun公司开发动态web的一门技术
- Sun在这些API中提供了一个接口叫:Servletrg 如果开发一个Servlet程序,只需要完成两个步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器
6.2、HelloServlet项目
- 构建一个普通的Maven项目,删掉里面的src目录,以后在这个项目里面建立Moudel
- 关于Maven父子工程的理解
父项目pom中会有
<modules>
<module>ServletDemo</module>
</modules>
父项目中的java子项目可以全部使用
web.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"
metadata-complete="true">
</web-app >
Maven环境优化
1. 修改web.xml为最新的
1. 将maven的结构编写完整 (java、resource)
编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口,直接继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.print("hello Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
编写Servlet的映射(因为我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给它一个浏览器能够访问的路径)
<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.vekzjj.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>hello</url-pattern>
</servlet-mapping>
配置Tomcat
6.3、Servlet原理
Servlet是由Web服务器调用,web服务器在收到浏览器请求之后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VdDzF9Lu-1648633735619)(C:\Users\周俊杰\Desktop\JavaWeb\image-20220316220959069.png)]
6.3、Mapping
- 一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/hello</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定多个个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/hello2</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
- 指定一些后缀或者前缀等
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.vekzjj</url-pattern>
</servlet-mapping>
- 优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
6.5、ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
1.共享数据
我在这个Servlet中保存的数据,可以在另外一个servket中拿到;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qMZhO82L-1648633735620)(C:\Users\周俊杰\Desktop\JavaWeb\image-20220316225750641.png)]
首先需要一个放置内容的类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter() 初始化参数
// this.getServletConfig() Servlet配置
// this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String username = "zjj";
context.setAttribute("username",username);//将一个数据保存在了ServletContext中
}
}
还需要一个读取它的类
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("姓名:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
还需要配置一个xml
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.vekzjj.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>com.vekzjj.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>context</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
2.获得初始化参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
3.请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了");
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forward实现请求转发
}
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.vekzjj.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
4.读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath;
思路:需要一个文件流
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 password = prop.getProperty("password");
resp.getWriter().print(username+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
username=root
password=123456
6.6、HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletResquset对象,代表响应的一个HttpServletResponse;
- 如果要获取客户端请求过来的参数:找HttpServletResquset
- 如果要给客户响应一些信息:找HttpServletResponse
1、简单分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向游览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
2、常见应用
- 向浏览器输出消息
- 下载文件
- 要获取下载文件的路径
- 下载的文件名是什么
- 设置想办法让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 要获取下载文件的路径
String realPath = "D:\\周壮壮\\Maven WEB\\maven01\\response\\src\\main\\resources\\1.png";
//2. 下载的文件名是什么
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3. 设置想办法让浏览器能够支持(Content-disposition)下载我们需要的东西
resp.setHeader("Content-disposition","attachment;filename"+fileName);
//resp.setHeader("Content-disposition","attachment;filename"+ URLEncoder.encode(fileName,"utf-8")); 解决文件名中文乱码问题
//4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while ((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
in.close();
out.close();
}
3、验证码功能
验证怎么来的?
-
前端实现
-
后端实现,需要用到java的图片类,生成一个图片
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如何让浏览器5秒自动刷新一次 resp.setHeader("refresh","3"); //在内存中创建一个图片 BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_3BYTE_BGR); //得到图片 Graphics2D g = (Graphics2D) image.getGraphics();//笔 //设置图片的背景颜色 g.setColor(Color.WHITE); g.fillRect(0,0,50,20); //给图片写数据 g.setColor(Color.pink); g.setFont(new Font(null,Font.BOLD,20)); g.drawString(makeNum(),0,20); //告诉浏览器吗,这个请求用图片的方式打开 resp.setContentType("image/png"); //网站存在缓存,我们需要不让浏览器缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //把图片写给浏览器 ImageIO.write(image, "png",resp.getOutputStream()); } //生成随机数 private String makeNum(){ Random random = new Random(); String num = random.nextInt(9999)+""; StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 4 - num.length(); i++) { stringBuffer.append("0"); }//强行四位数,不够的话就补0 num = stringBuffer.toString() + num; return num; }
4、实现重定向
一个Web资源收到客户端请求后,他会通知客户端去访问另外一个资源,这个过程叫重定向
常见场景:
用户登录
void sendRedirect(String var1) throws IOException;
测试:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
*
*resp.setHeader("Location","/r/img");
resp.setStatus(302);
*
*/
resp.sendRedirect("/r/img");//重定向
}
重定向和转发的区别?
相同点
- 页面都会实现跳转
不同点
- 请求转发的时候url不会产生变化,307
- 重定向的时候,url地址会发生变化,302
jsp maven
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入请求");
//处理请求
String username = req.getParameter("username");//处理参数
String password = req.getParameter("password");//处理参数
System.out.println(username+":"+password);
resp.sendRedirect("/r/success.jsp");//重定向注意:重定向的时候一定要注意路径问题,否则404
}
<html>
<body>
<h2>Hello World!</h2>
<%--这样提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}/login代表当前项目--%>
<form action="${pageContext.request.contextPath}/login">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
<html>
<head>
<title>Title</title>
<h1>Success</h1>
</head>
<body>
</body>
</html>
6.7、HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法,获得客户端的信息
1、获取前端传递的参数以及请求转发
req.getParameter()
req.getParameterValues()
body>
<h1>登录</h1>
<div style="text-align: center">
<%-- 这里表单的意思:以post方式提交表单,提交到我们的login请求--%>
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username" required><br>
密码:<input type="password" name="password" required><br>
爱好:
<input type="checkbox" name="hobbys"value="女孩">女孩
<input type="checkbox" name="hobbys"value="代码">代码
<input type="checkbox" name="hobbys"value="唱歌">唱歌
<input type="checkbox" name="hobbys"value="电影">电影
<br>
<input type="submit">
</form>
</div>
</body>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
//后台接收乱码问题
System.out.println("===============================");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("===============================");
//通过请求转发
//这里的/代表当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req,resp);!
}
7、Cookile、Session
7.1、会话
会话:用户打开一个浏览器,点击了很多超联集,访问了多个web资源,关闭浏览器,这个过程可以称为会话
7.2、保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用或这个技术,可以保存用户的会话信息,我们可以把信息或数据放在Session中
常见场景:网站登录之后,你下次不用再登录了,第二次就会有记忆了,不用在登陆。
7.3、Cookie
1.从请求中拿到cookie信息
2.服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//这是cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie
一个网站Cookie是否存在上限?
- 一个Cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最后存放20个cookie
- cookie大小有限制
- 300个cookie浏览器上限
删除Cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0
解决乱码问题:
URLEncoder.encode("奥特曼","utf-8");
URLDecoder.decode("奥特曼","utf-8");
7.4、Session
什么是Session:
- 服务器会给每一个用户创建一个Session
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登陆之后,整个网站它都可以访问----保存用户的信息
session会话过期:
web.XML注销
<!-- 设置Session默认的失效时间-->
<!-- <session-config>-->
<!-- 以分钟为单位-->
<!-- <session-timeout>1</session-timeout>-->
<!-- </session-config>-->
手动注销
session.invalidate();//手动注销
Session和cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存
- Session把用户的数据写到用户独占Session中,服务器保存
- Session对象是由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,放在Session中
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session种存东西
session.setAttribute("name",new Person("vekzjj",1));
//获取Session的ID
String id = session.getId();
//按段Session是不是新创建的
boolean aNew = session.isNew();
if (aNew){
resp.getWriter().print("Session创建成功,ID+"+session.getId());
}else{
resp.getWriter().print("Session已经在服务器中存在了,ID+"+session.getId());
}
//Session创建的时候做了什么事情
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();//手动注销
8、JSP
8.1、什么是JSP
java Server Pages:java服务器端页面,和Servlet一样,用于动态开发Web
特点:
- 和HTML一样
- 区别:
- HTML只给用户提供静态数据
- JSP页面中可以嵌入Java代码,为用户提供动态数据
8.2、JSP原理
JSP如何执行的:
- 服务器内部工作
- Tomcat中有一个work目录;
- IDEA中使用Tomcat的会在IDEA的Tomcat中生产一个work目录
- 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
- JSP最后也被转换为Java类
- JSP本质上就是Servlet
public void _jspinit(){
//初始化
}
public void _jspDestroy(){
//销毁
}
public void _jspService(){
//JSPService
}
- 判断请求
- 内置了一些对象
8.3、JSP基础语法
需要的依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- Servlet 依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- JSTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency
JSP表达式
<%--JSP表达式
作用:用来将程序的输出,给到客户端
<%=变量或者表达式%>
--%>
<%= new java.util.Date()%>
JSP脚本片段
<%--脚本片段--%>
<%
int sum= 0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"<h1>");
%>
脚本片段的再实现
<%--脚本片段--%>
<%
int sum= 0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"<h1>");
%>
<%
int x = 10;
out.println(x);
%>
<p>这是一个JSP文档</p>
<%
int y = 2;
out.println(y);
%>
<hr>
<%--在代码嵌入HTML元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>hello world <%=i%></h1>
<%
}
%>
JSP声明
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void vekzjj(){
System.out.println("成功进入");
}
%>
JSP声明:会被编译到JSP生成Java的类中,其他的,会被生成到_jspService中!
JPS的注释,不会在客户端显示,HTML的会
8.4、JSP指令
<%@ page ... %>
<%@include file=""%>
公共页面:
方法一
<%--@include本质 会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
方法二
<%--jsp标签--%>
<%--jsp:include本质 拼接页面,本质还是三个页面--%>
<jsp:include page="/common/header.jsp"/>
<jsp:include page="/common/footer.jsp"/>
8.5、九大内置对象
- PageContext 存东西
- Request 存东西
- Responce
- Session 存东西
- Application【ServletContext】 存东西
- Config【ServletConfig】
- Out
- Page
- Exception
pageContext.setAttribute("name1","vekzjj1");//保存的数据只在一个页面中有效
request.setAttribute("name2","vekzjj2");//保存的数据旨只在一次请求中有效,请求转发会携带整个数据
session.setAttribute("name3","vekzjj3");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","vekzjj4");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻
session:客户端向服务器发送请求,产生的数据,用户用完了可能还有用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可以用,比如:聊天记录
8.6、JSP标签、JSTL标签、EL表达式
<!-- JSTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency
EL表达式: ${}
-
获取数据
-
执行运算
-
获取web开发的常用对象
JSP标签
<%--jsp:include--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="name" value="vezkjj"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
JSTL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义了许多的标签供我们使用,标签的功能和Java的代码一样
格式化标签
SQL标签
XML标签
核心标签(部分掌握)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--引入JSTL核心标签库,我们才能使用JSTL标签--%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>if测试</h4>
<hr>
<form action="" 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>
<body>
<%--定义一个变量score,值为85--%>
<c:set var="score" value="85"/>
<c:choose>
<c:when test="${score>=90}">
你的成绩优秀
</c:when>
<c:when test="${score>=80}">
你的成绩一般
</c:when>
<c:when test="${score>=70}">
你的成绩良好
</c:when>
<c:when test="${score<=60}">
你的成绩有待提高
</c:when>
</c:choose>
</body>
<%@ 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> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
people.add(4,"田七");
request.setAttribute("list",people);
%>
<%--
var,每一次遍历出来的变量
items,要遍历的对象
begin,哪里开始
end,到哪里结束
step,步长
--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/><br>
</c:forEach>
<hr>
<c:forEach var="people" items="${list}" begin="1" end="3" step="2">
<c:out value="${people}"/>
</c:forEach>
</body>
</html>
9、JavaBean
实体类
JavaBean有特定的写法:
- 必须有一个无参构造
- 属性必须私有化
- 必须有对象的get/set方法
一般用于和数据库字段做映射 ORM;
ORM:对象关系映射
- 表---->类
- 字段---->属性
- 行记录---->对象
<% //People people = new People();%>
<jsp:useBean id="people" class="com.vekzjj.pojo.People" scope="page" />
<jsp:setProperty name="people" property="address" value="西安"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="3"/>
<jsp:setProperty name="people" property="name" value="vekzjj"/>
<jsp:getProperty name="people" property="address"/>
<jsp:getProperty name="people" property="id"/>
<jsp:getProperty name="people" property="age"/>
<jsp:getProperty name="people" property="name"/>
10、MVC三层架构
什么是MVC:Model view Controller 模型、视图、控制器
早 期:用户直接访问控制层,控制层就可以直接操作数据库;
servlet-->CRUD-->数据库
弊端:程序臃肿,不利于维护
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jIzz19pv-1648633735623)(C:\Users\周俊杰\Desktop\JavaWeb\image-20220320225225210-16477879473672.png)]
现在:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02abg7V7-1648633735624)(C:\Users\周俊杰\Desktop\JavaWeb\image-20220320230021383-16477884225903.png)]
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View
- 展示数据
- 提供连接发起Servlet请求(a,form,img…)
Controller(Servlet)
- 接收用户的请求:(req:请求参数、session信息…)
- 交给业务层处理对应的代码
- 控制试图的跳转
邓丽--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)--->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确--->数据库
11、Filter过滤器
Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登陆验证
11.1、Filter开发步骤
- 导包(java.servlet.*)
- 建立Filter过滤器
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动的时候,就已经初始化了
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
// 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("CharacterEncodingFilter执行前...");
filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就停止了
System.out.println("CharacterEncodingFilter执行后...");
}
//销毁:web服务器关闭的时候,过滤器会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
- 在web.xml中配置Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.vekzjj.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是servlet的任何请求都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12、过滤器应用
Filter实现权限拦截
用户登录之后才能进入主页!用户注销后就不能进入主页了!
- 用户登录之后,向Session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response =(HttpServletResponse)servletResponse;
Object user_session = request.getSession().getAttribute(constant.USER_SESSION);
if (user_session == null){
response.sendRedirect("/error.jsp");
System.out.println("执行成功");
}
filterChain.doFilter(servletRequest,servletResponse);
}
登录类:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute(constant.USER_SESSION);
if (user_session!=null){
req.getSession().removeAttribute(constant.USER_SESSION);
resp.sendRedirect("/Login.jsp");
}
}
登录jsp:
<body>
<form action="/servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
登陆成功jsp:
<body>
<h1>主页</h1>
<a href="/servlet/logout">注销</a>
</body>
登陆失败jsp:
<body>
<h1>错误</h1>
<h3>没有权限</h3>
<a href="Login.jsp">返回登陆界面</a>
</body>