JavaWeb
Java + Web
1.基本概念
1.1 前言
web开发:
-
web ,网页的意思, www.baidu.com
-
静态web
- html .css
- 提供给所有人看到的数据不会发生变化
-
动态web
-
淘宝,几乎所有网站
-
提供给所有人看的数据是会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同
-
技术栈:Servlet/ISP,ASP,PHP
在java中,动态web资源开发的技术统称为JavaWeb
-
1.2 Web应用程序
web应用程序:可以提供浏览器访问的程序
-
a.html,b.html 多个web资源,这些web资源可以被外界访问,对外界提供服务
-
你们能访问到的任何一个页面或者资源,都存在于世界上的某个角落的计算机上
-
URL
-
这个统一的web资源会被放在同一个文件下,web应用程序 ----->Tomcat:服务器
-
一个web应用由多部分组成(静态web,动态web)
- html,css,js
- jsp,servlet
- java程序
- jar包
- 配置文件(Properties)
web应用编程完成后,若想提供外界访问
1.3 静态web
- *.html. *.htm这些都是网页后缀,如果服务器上存在这些东西,我们就能直接读取,需要网络
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bgA7CjYB-1647825328436)(javaweb/20200506174751665.png)]
静态web存在的确定
- Web页面无法动态更新,所有的用户看到的都是同一个页面
- 轮播图,点击特效,伪动态
- JavaScript实际开发中,用的最多
- VBScript
- 他无法和数据库交互(数据无法持久化。用户无法交互)
1.4 动态web
页面会动态展示: “web的页面展示效果因人而异”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBcFcDmH-1647825328436)(javaweb/20200506175025436.png)]
缺点:
- 加入服务器的动态web资源出了错误,我们需要重新编辑后台程序,重新发布
- 停机维护
- Web页面可以动态更新,所有用户看到的是不同页面
- 他可以和数据库交互(数据持久化,注册,商品信息,用户信息…)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l5VPoIUx-1647825328437)(javaweb/20200506175041602.png)]
2.Web服务器
3.Tomcat
4.Http
4.1 什么是HTTP
4.2 两个时代
4.3 Http请求
4.4 Http响应
5.Maven
5.1 Maven项目架构管理工具
5.2 下载安装Maven
5.3 配置环境变量
5.4 阿里云镜像
5.5 本地仓库
5.6 在IDEA中使用Maven
5.7 创建一个普通的Maven项目
5.8 标记文件夹功能
5.9 在IDEA中配置Tomcat
5.10 pom文件
5.11 IDEA操作
5.12 解决遇到的问题
6 servlet
6.1 Servlet简介
-
Servlet就是sun公司开发动态web的一门技术
-
Sun这些API提供了一个接口叫Servlet,如果你想开发一个Servlet程序,只需要完成连个小步骤
- 编写一个雷,实现servlet接口
- 把开发好的java类部署到web服务器中
把实现了Servlet接口的java程序叫做Servlet
6.2 HelloServlet
-
构建一个普通的Maven项目。删除里面的src目录,我们学习就在这个项目里面建立Moudel,空的工程就是Maven
-
关于Maven父子工程的理解:
父项目会有:
<modules> <module>servlet-01</module> <module>servlet-02</module> </modules>
子项目会有
<parent> <groupId>com.barty</groupId> <artifactId>javaweb-01-servlet</artifactId> <version>1.0-SNAPSHOT</version> </parent>
父项目中的jar包子项目可以直接拿来使用
son extends father
-
Maven环境优化
- 修改web.xml为最新的
- 将maven的结构搭建完整
-
编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口,我们直接继承HttpServlet
public class HelloServlet extends HttpServlet { //由于get或者post只是请求实现的不同方式,可以互相调用,业务逻辑都一样 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); //响应流 writer.write("hello servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
编写Servlet映射
- 为什么需要映射:我们写的是java程序,但要通过浏览器访问,而浏览器需要链接web服务器,我们需要在web服务器中注册我们写的Servlet,还需要给他一个浏览器能访问的路径
<!--注册servelt--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.barty.servlet.HelloServlet</servlet-class> </servlet> <!--Servlet的请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
配置tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0uZCGWb-1647825328437)(https://gitee.com/pang-yuanyuan/java/raw/master/img/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16469678702059.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdUZDIAj-1647825328437)(javaweb/企业微信截图_16469678702059.png)]
-
启动测试,ok
6.3 Servlet原理
Servlet是由Web浏览器调用,web服务器在收到浏览器请求之后,会
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uFjnCh0e-1647825328438)(javaweb/20200506180639329.png)]
6.4 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-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</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>/*</url-pattern> </servlet-mapping>
-
指定一些前缀和后缀
<!--自动以后缀实现请求映射, 注意点, * 前面不能加项目映射的路径 hello/sad.qiao --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.qiao</url-pattern> </servlet-mapping>
-
优先级问题
-
制定了固有的映射路径优先级最高,如果找不到就走默认的处理请求
<!--404--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.barty.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
6.5 ServletContext
Web容器在启动的时候,他会为每个web应用程序都创建一个对应的ServletContext对象,代表了当时的web应用
1. 共享数据
在这个servelet保存的数据看,可以再另外一个Servlet中拿到
/*
this.getServletContext(); servlet上下文
this.getInitParameter(); 初始化参数
this.getServletConfig(); servlet配置
*/
ServletContext context = this.getServletContext();
String name = "巴蒂";
//将一个数据保存在了ServletContext中,名字为:username 。值 username存入
context.setAttribute("usename",name);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/thml");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.write("名字"+username);
}
测试访问结果
2.初始化参数
web.xml中配置
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3321/ssm</param-value>
</context-param>
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("=====进入ServletDemo04===");
// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gc");
// requestDispatcher.forward(req,resp);
context.getRequestDispatcher("gc").forward(req,resp);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjllYYHT-1647825328438)(javaweb/20200505153728272.png)]
4. 读取资源文件
Properties文件
- 在java目录下新建一个properties
- 在resources目录下新建一个properties
**发现都被打包到同一个路径下,classes,给我们一个俗称classpath
思路:
-
需要一个文件流
-
读写
-
测试
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/barty/servlet/db.properties"); Properties pro = new Properties(); pro.load(is); String username = pro.getProperty("username"); String pwd = pro.getProperty("password"); resp.getWriter().print(username + ":" + pwd); }
6.6 HttpServletResponse
- web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象
- 代表相应的一个HttpServletResponse
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
1.简单分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
void setCharacterEncoding(String charset);
void setContentLength(int len);
void setContentLengthLong(long len);
void setContentType(String type);
void setDateHeader(String name, long date);
void addDateHeader(String name, long date);
void setHeader(String name, String value);
void addHeader(String name, String value);
void setIntHeader(String name, int value);
void addIntHeader(String name, int value);
响应的状态码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWDAExcG-1647825328438)(javaweb/20200505155751598.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JB1wS6OA-1647825328439)(https://gitee.com/pang-yuanyuan/java/raw/master/img/20200505155751598.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkxyK4DC-1647825328439)(javaweb/20200505155821202.png)]
2.下载文件
- 向浏览器输出信息
- 下载文件
- 要获取下载文件的路径
- 下载文件名
- 设置想办法让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputSteam对象
- 将FileOutputStream流写入到bufer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取下载文件的路径
String realPath = "C:\\java\\2021workspace\\IDEA-workspace\\2022Work\\javaweb\\ksjavaweb\\javaweb-01-servlet\\servlet-02\\src\\main\\resources\\update.sql";
System.out.println("下载文件的路径: " + realPath);
//2.下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置浏览器支持(Content-Disposition)下载我们要的东西,。中文名称URLEncoder.encode编码,否则可能乱码
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 将FileInputStream写入到buffer,使用OutputStream将缓冲区的数据输出到客户端
while ((len = in.read(buffer)) >0) {
out.write(buffer,0,len);
}
in.close();
out.close();
}
3. 验证码功能
验证码怎么来的?
- 前端实现
- 后端实现,要用到java的图片类,生成一个图片
package com.barty.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
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 {
//让浏览器几分钟刷新一次
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);
//告诉浏览器用img方式打开
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");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T1zXtF73-1647825328440)(javaweb/20200505163538698.png)]
常见场景
-
用户登录
void sendRedirect(String location) throws IOException;
测试
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/s2/gc"); //重定向
// resp.setHeader("Location","/s2/gc");
// resp.setStatus(302);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YKjosYPS-1647825328440)(javaweb/20200505163946136.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2ttVziY-1647825328440)(javaweb/20200505163953854.png)]
index.jsp
<html>
<body>
<h2>Hel1o World!</h2>
<%--这里超交的路径,需要寻找到项目的路径--%>
<%--${pageContext. request, contextPath}代表当前的项目--%>
<form action="${pageContext. request.contextPath}/login" method="get">
用户名: <input type="text" name="username"> <br>
密码: <input type="password" name="password"> <br>
<input type="submit">
</form>
</body>
</html>
RequestTest.java
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理方式
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + ":" + password);
resp.sendRedirect("/s2/success.jsp");
}
重定向页面success.jsp
-
web配置
-
导入依赖的jar包.tomcat10之后引入的是jakarta
<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> </dependency> <dependency> <groupId>jakarta.servlet.jsp</groupId> <artifactId>jakarta.servlet.jsp-api</artifactId> <version>3.0.0</version> </dependency>
6.7 HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过http协议访问协议,HTTP请求中的所有信息会被封装到HttpServletRequest通过HttpServletRequest的方法,获取客户端的所有信息
// req.get获取很多数据,获取参数,请求转发
String getContextPath();
String getRemoteUser();
String getParameter(String name); //获取参数
String[] getParameterValues(String name);
自己创建类,且需要继承HttpServlet类
@Override
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("=======");
System.out.println(req.getContextPath());
//通过请求转发
//这里的/代表当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8661GGB-1647825328440)(javaweb/20200505170535748.png)]
7 Cookie session
7.1 会话
会话:打开一个浏览器,点击很多超链接,a访问了多个web资源,关闭浏览器,这个过程称之为会话
有状会话 :一个同学来过教师,下次还来教师,我们会知道这个学生,曾经来过
有状会话:
你怎么证明你是学生?
- 发票: 学校给你发票
- 学校登记 学校标记你来过了
一个网站,怎么证明你来过?
客户端 服务端
- 服务端给客户一个信件,客户端下次访问服务端带上信件就可以 cookie
- 服务器登记你过来了,下次你来的时候我来匹配你 session
7.2 保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以吧信息或者数据放在session中
常见:网站登录之后,你下次不用登录了,第二次访问直接上去
7.3 Cookie
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PvvzAy75-1647825328440)(https://gitee.com/pang-yuanyuan/java/raw/master/img/20200506182559338.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zipLAwyh-1647825328440)(javaweb/20200506182559338.png)]
-
从请求中拿到cookie信息
-
服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //从请求冲获取cookie String name = cookie.getName(); //获取cookie中的key String value = cookie.getValue(); //后去cookie中的value Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+""); //新建一个cookie cookie.setMaxAge(24*60); //设置cookie有效期 resp.addCookie(cookie); //响应给客户端一个cookie
cookie:一般会保存在本地的用户目录下appdata;:
一个网站cookie是否存在上限:
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多 放20个cookie
- cookie大小有限制4kb
- 300个cookie浏览器上限
删除cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期为0;
7.4 Session(重点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-10aSHKPD-1647825328442)(https://gitee.com/pang-yuanyuan/java/raw/master/img/2020050618262991.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XRkEUq2g-1647825328442)(javaweb/2020050618262991.png)]
什么是Session
- 服务器会给每个用户(浏览器)创建一个session对象
- 一个session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登陆之后,整个网站他都可以访问!—>保存用户的信息,保存购物车的信息。。。
Session和Cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以是多个)
- Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- Session对象由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在这个网站中经常会使用的数据,我们将它保存在Sessiioin中
使用Session
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到sessioin
HttpSession session = req.getSession();
//给session存东西
session.setAttribute("name",new Person("庞媛媛",18));
//获取session中的id
String sessionId = session.getId();
//判断sessionId是不是新建的
if (session.isNew()) {
resp.getWriter().write("session创建成功,id:" + sessionId);
} else {
resp.getWriter().write("session 已经在服务器中存在,ID: " +sessionId);
}
// HttpSession session = req.getSession();
}
//得到session
HttpSession session = req.getSession();
Person person = (Person)session.getAttribute("name");
System.out.println(person.toString());
HttpSession session1 = req.getSession();
session1.removeAttribute("name");
session1.invalidate();
会话自动过期:web.xml配置
<!--设置session默认的失效时间-->
<session-config>
<!--15min之后session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y755LNju-1647825328442)(javaweb/2020050618301064.png)]
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目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0tA5Du4-1647825328442)(javaweb/20200506184154282.png)]
我的电脑地址:
C:\Users\Administrator.IntelliJIdea2018.1\system\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\ROOT\org\apache\jsp
浏览器想服务器发送请求,不管访问什么资源,都是在访问Servlet
JSP最终也会被转换为JAVA类
JSP本质上就是一个Servlet
public void jspInit(); //初始化
public void jspDestroy();// 销毁
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException; //JSPService
-
判断请求
-
内置了一些对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文 javax.servlet.http.HttpSession session = null; //session final javax.servlet.ServletContext application; //applicationContext final javax.servlet.ServletConfig config; //config javax.servlet.jsp.JspWriter out = null; //out final java.lang.Object page = this; //page:当前 HttpServletRequest request //请求 HttpServletResponse response //响应
-
输出页面前增加的代码
response.setContentType("text/html"); //设置响应的页面类型 pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out;
-
以上的这些对象我们可以再jsp页面中直接使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHQvR5q7-1647825328443)(javaweb/20200506183804973.png)]
在JSP页面中;
只要是 JAVA代码就会原封不动的输出;
如果是HTML代码,就会被转换为:
out.write("<html>\r\n");
1
这样的格式,输出到前端!
8.3 JSP基础语法
任何语言都有自己的语法,java中有,jsp作为java的一种应用,他拥有一些自己扩充的方法,java所有语法都支持
<%--1.jsp表达式 作用L用来将程序的输出,输出到客户端--%>
<%--变量或者表达式--%>
<%=new java.util.Date()%>
<%--2.jsp脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.println("<h1> sum = " + sum + "</h1>");
%>
<%--3.jsp脚本片段再实现--%>
<%
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 word <%=i%></h1>
<%
}
%>
<%--4.jsp声明 jsp声明L会被编译到jsp生成java类中,其他的都会被生成_jspService方法中--%>
<%!
static {
System.out.println("Loading servlet !");
}
private int globalVar = 0;
public void barty() {
System.out.println("进入了barty方法");
}
%>
<%--jsp 注释不会在客户端显示--%>
<%--5 .jsp指令--%>
<%@page args.... %>
<%@include file=""%>
<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="/common/footer.jsp"%>
<hr>
<%--jSP标签
jsp:include:拼接页面,本质还是三个
--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>
8.5 9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application 【SerlvetContext】 存东西
- config 【SerlvetConfig】
- out
- page ,不用了解
- exception
pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","秦疆4号"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器
//从pageContext去除,我们通过寻找的方式来
//从底层到高层(作用域) page->request->session->application
// jvm:双亲委派机制
request:客户端想服务器发生请求,产生的数据,用户看完了就没有了,比如:新闻,用户看完就么用呢
session:客户端想服务器发生请求,产生的数据,用户用完一会还有用,比如:购物车
application: 客户端向服务器发生请求,产生的数据,一个用户用完了,其他用户还能使用,比如:聊天数据
9. JavaBean
10.MVC三层架构
- 什么是MVC: Model View Controller 模型,视图,控制器
10.1 以前的架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wxOkdqOD-1647825328443)(javaweb/20200508154442187.png)]
用户直接访问控制层,控制层就可以直接操作数据库
servlet---CRUD--->数据库
弊端:程序十分臃肿,不利于维护
servlet 代码中,处理请求,响应,视图跳转,处理JDBC,处理业务代码,处理逻辑代码
架构:没有什么事加一层解决不了的
程序员调用
↑
JDBC (实现该接口)
↑
Mysql Oracle SqlServer ....(不同厂商)
10.2 MVC三层架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQbCoiKF-1647825328443)(javaweb/20200508154512751.png)]
Model
- 业务处理:业务逻辑(service)
- 数据持久层: CRUD (Dao–数据持久化对象)
View
- 展示数据
- 提供链接发起Servlet请求(a. form.img…)
Controller (Servlet)
- 接收用户的请求:(req:请求参数,sessioin信息…)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录–>接收用户的登录请求—>处理用户的请求(获取用户登录的参数,username,password)
----> 交给业务层处理登录业务(判断用户名密码是否正确:事务)–>
Dao层查询用户名和密码是否正确—>数据库
11.Filter(重点)
比如Shiro安全框架技术就是用Filter来实现
Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登录验证
(比如用来过滤网上骂人的滑,我***我自己0-0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxdMLacI-1647825328443)(javaweb/20200508154536177.png)]
Filter开发步骤:
- 导包,
- 编写过滤器
- 导包不要错(注意)
实现过滤器,重写对应的方法即可
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就可以初始化了,随时等待过滤对象出现
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter 初始化");
}
//销毁
// web服务器关闭的时候,过滤器会销毁
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter 销毁");;
}
// chain:链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续通行
chain.doFilter(request,response);
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
System.out.println("CharacterEncodingFilter 执行前....");
chain.doFilter(request,response); //让我们的程序继续走,如果不写,程序到这里就停止了
System.out.println("CharacterEncodingFilter 执行后....");
}
}
3.在web.xml中配置 Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.barty.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12 监听器
**实现一个监听器的接口:(有n中监听器)
- 编写一个监听器
- 实现监听器的接口
- 依赖的jar包
//依赖的jar包
package com.barty.filter;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数:统计session
public class OnlineCountListener implements HttpSessionListener {
// 创建session监听,看你的一举一动
//底单创建创建Session 就会触发这个时间
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount == null) {
onlineCount = new Integer(1);
} else {
int count = onlineCount.intValue();
onlineCount = new Integer(count + 1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁监听
//一旦销毁session,就会触发这次时间
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.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);
}
/*
session销毁
1.手动销毁 getSession.invalidate()
2.自动销毁
*/
}
2.web.xml中注册监听器
<!--注册监听器-->
<listener>
<listener-class>com.barty.filter.OnlineCountListener</listener-class>
</listener>
3.看情况是否使用
13 过滤器,监听器常见应用
14 JDBC
**什么事JDBC:java链接数据库
- 需要jar包支持
mysql-connector-java...链接驱动(必须要导入) 导入数据库依赖 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> IDEA链接数据库
JDBC固定步骤:
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL对象Statement:CRUD
- 编写SQL(根据业务,不同的sql)
- 执行sql
- 关闭链接(先开的后关)
public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
//jdbc:mysql://localhost:3306/ssm
String url = "jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8"; //解决中文乱码
String username = "root";
String password = "cmsserverv6";
//1,加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2,连接数据库,代表数据库
Connection conn = DriverManager.getConnection(url, username, password);
//3, 想数据库发送sql对象,Statement,PreparedStatement:CRUD
Statement statement = conn.createStatement();
//4 编写sql
String sql = "select * from users";
//5,执行查询sql,返回一个resultSet:结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
System.out.println("id = " +rs.getObject("id"));
System.out.println("name = " + rs.getObject("name"));
System.out.println("password = " +rs.getObject("password"));
System.out.println("email = " +rs.getObject("email"));
System.out.println("birthday = " +rs.getObject("birthday"));
}
//6,关闭链接,释放资源(一定要做,先开后关)
rs.close();
statement.close();
conn.close();
}
}
预编译SQL
public class TestJdbc2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置jdbc
String url = "jdbc:mysql://localhost:3306/ssm?useUnicode=true&CharacterEncoding=utf-8";
String username = "root";
String password = "cmsserverv6";
//1,加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2 链接数据库
Connection conn = DriverManager.getConnection(url,username,password);
//3 编写SQL
String sql = "insert into ssm.users (id, NAME, PASSWORD, email, birthday)\n" +
"values (?,?,?,?,?);";
//4 预编译
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1,5);
preparedStatement.setString(2,"巴蒂学英语");
preparedStatement.setString(3,"123456");
preparedStatement.setString(4,"23525@qq.com");
preparedStatement.setString(5,"2001-01-09");
//5,执行sql
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("插入成功");
}
//6.关闭链接,释放资源(一定要做) 先开的后关闭
preparedStatement.close();
conn.close();
}
}
事务
- 要么都成功,要么都失败
- ACID原则:保证数据的安全
开启事务
事务提交
事务回滚
关闭事务
转账:
A:1000
B:1000
A(900)
Junit单元测试
依赖
@Test
public void test() throws ClassNotFoundException, SQLException {
//配置信息
String url = "jdbc:mysql://localhost:3306/ssm?userUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "cmsserverv6";
Connection conn = null;
try {
//1,加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2,链接数据库
conn = DriverManager.getConnection(url, username, password);
// 3,通知数据库开始事务,false 开启
conn.setAutoCommit(false);
// 4.编写sql
String sql = "update account set money = money + 100 where name = 'B'";
conn.prepareStatement(sql).executeUpdate();
String sql2 = "update account set money = money -100 where name = 'A'";
// 预处理
//执行sql语句
conn.prepareStatement(sql2).executeUpdate();
conn.commit();//以上两条sql都执行成功,就提交事务
System.out.println("success");
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
//关闭资源
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}