JavaWeb

HTML

HTML介绍

名词解释:

HTML是Hyper Text Markup Language的缩写。意思是『超文本标记语言
在这里插入图片描述

HTML结构

<html>
	<head>
		<title>这是我的第一个网页</title>
		<meta charset="UTF-8">
	</head>
	<body>
		HELLO WORLD!
	</body>
</html>

①文档类型声明
HTML文件中第一行的内容,用来告诉浏览器当前HTML文档的基本信息,其中最重要的就是当前HTML文档遵循的语法标准。这里我们只需要知道HTML有4和5这两个大的版本,HTML4版本的文档类型声明是

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

HTML5版本的文档类型声明是:

<!DOCTYPE html>

②根标签
html标签是整个文档的根标签,所有其他标签都必须放在html标签里面。

<html></html>

④主体
body标签定义网页的主体内容,在浏览器窗口内显示的内容都定义到body标签内。
⑤注释
HTML注释的写法是:

<!-- 注释内容 -->

HTML语法规则

  • 根标签有且只能有一个
  • 无论是双标签还是单标签都必须正确关闭
  • 标签可以嵌套但不能交叉嵌套
  • 注释不能嵌套
  • 属性必须有值,值必须加引号,单引号或双引号均可
  • 标签名不区分大小写但建议使用小写

HTML标签

标题标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h1>这是一级标题</h1>
    <h2>这是二级标题</h2>
    <h3>这是三级标题</h3>
    <h4>这是四级标题</h4>
    <h5>这是五级标题</h5>
    <h6>这是六级标题</h6>

</body>
</html>

页面效果展示
在这里插入图片描述

超链接标签

<a href="page02-anchor-target.html">点我跳转到下一个页面</a>

在这里插入图片描述

  • href 连接的地址

  • target:
    self:在本窗口打开
    blank:在一个新窗口打开
    parent:在父窗口打开
    top:在顶层窗口打开
    在这里插入图片描述

换行标签

<br/>

比段落标签换行的两行间隔小

图片标签

<img src="/aaa/pro01-HTML/./images/mi.jpg" />
  1. src属性用来指定图片文件的路径
  2. width和height表示图片的大小
  3. alt表示图片的提示

列表标签

有序列表
武林高手排行榜
<body>
	<ol>
		<li>扫地僧</li>
		<li>萧远山</li>
		<li>慕容博</li>
		<li>虚竹</li>
		<li></li>
</body>

武林高手排行榜

  1. 扫地僧
  2. 萧远山
  3. 慕容博
  4. 虚竹
无序列表
<body>
    <ul>
        <li>Apple</li>
        <li>Banana</li>
        <li>Grape</li>
    </ul>
</body>
  • Apple
  • Banana
  • Grape

块标签

并不是为了显示文章内容的,而是为了方便结合CSS对页面进行布局。块有两种,div是前后有换行的块,span是前后没有换行的块。

<div style="border: 1px solid black;width: 100px;height: 100px;">This is a div block</div>
<span style="border: 1px solid black;width: 100px;height: 100px;">This is a span block</span>

在这里插入图片描述

HTML中的实体标签

在HTML文件中,<、>等等这样的符号已经被赋予了特定含义,不会作为符号本身显示到页面上,此时如果我们想使用符号本身怎么办呢?那就是使用HTML实体来转义。
在这里插入图片描述

表格标签

<html>
<head>
	<title>表格标签的学习</title>
	<meta charset="UTF-8">
</head>
<body>
	<table border="1" width="600" cellspacing="0" cellpadding="4">
		<tr align="center">
			<th>姓名</th>
			<th>门派</th>
			<th>成名绝技</th>
			<th>内功值</th>
		</tr>
		<tr align="center">
			<td>乔峰</td>
			<td>丐帮</td>
			<td>少林长拳</td>
			<td>5000</td>
		</tr>
		<tr align="center">
			<td>虚竹</td>
			<td>少林寺</td>
			<td>七十二绝技</td>
			<td>3000</td>
		</tr>
	</table>
</body>

在这里插入图片描述

  • 表格 table
  • 行 tr
  • 列 td
  • 表头列th

table中有如下属性(虽然淘汰)

  • border:表格边框的粗细
  • width:表格的宽度
  • cellspacing:单元格间距
  • cellpadding:单元格内填充

tr中有一个属性:align:center,left,right
td属性:
rowspan:合并行(跨几行合并)
colspan:合并列(跨几列合并)

表单标签

<html>
<head>
	<title>表单标签的学习</title>
	<meta charset="UTF-8">
</head>
<body>
	<form action="demo02.html" method="post">
		昵称:<input type="text" name="nickName" value="请输入用户名"/><br/>
		密码:<input type="password" name="pwd"/><br/>
		性别:<input type="radio" name="gender" value="male" checked="checked"/><input type="radio" name="gender" value="female"/><br/>
		爱好:<input type="checkbox" name="hobby" value="basketball"/>篮球
		     <input type="checkbox" name="hobby" value="football"/>足球
			 <input type="checkbox" name="hobby" value="earth"/>地球<br/>
		星座:<select name="star">
			 <option value="1">白羊座</option>
			 <option value="2" selected="selected">天枰座</option>
			 <option value="3">金牛座</option>
			 <option value="4">双鱼座</option>
			 <option value="5">水瓶座</option>
		    </select><br/>
		备注:<textarea name="remark" row="4" cols="5"></textarea><br/>
		<input type="submit" value="注册"/>
		<input type="reset" value="重置"/>
		<input type="button" value="这是一个普通按钮"/>
	</form>
</body>

在这里插入图片描述
在这里插入图片描述

frameset和iframe(淘汰)

<html>
<head>
	<title>frameset学习</title>
	<meta charset="UTF-8">
</head>
<!-- 一个页面分割成上下两行,上面占百分之二十的行长,下面百分之八十 -->
	<frameset  rows="20%,*">
		<frame src="frames/top/.html"/>
		<frameset cols="15%,*">
			<frame src="frames/left.html"/>
		    <frameset rows="80%,*">
				<frame src="frames/main.html"/>
				<frame src="frams/bottom.html"/>
			</frameset>
		</frameset>
	</frameset>
</html>

在这里插入图片描述
在一个页面嵌入一个子页面可以用iframe

<html>
<head>
	<title>iframe学习</title>
	<meta charset="UTF-8">
</head>
<body>
	这里是demo06页面的内容!!
	<iframe src="frames/top.html"/>
</body>
</html>

在这里插入图片描述

CSS

CSS的语法

<html>
<head>
	<meta charset="UTF-8">
	<!-- 内部样式 -->
	<style type="text/css">
		/* 标签样式 */
		p {
			color: red;
		}
		/* 类样式 */
		.f20{
			font-size: 20px;
		}
		/* id样式 */
		#p4{
			background-color: pink;
			font-size: 24px;
			font-weight: bolder;
			font-style: italic;
			font-family: "华文彩云";
		}
		/* 组合样式 */
		div p{
			color:blue;
		}
		div .f32{
			font-size: 32px;
			font-family: "黑体";
		}
	</style>
</head>
<body>
	<p>这是段落一</p>
	<p>这是段落二</p>
	<p class="f20">这是段落三</p>
	<!-- id属性尽量唯一 -->
     <p id="p4">这是段落四</p> 
	 <div>
		<p><span>Hello</span></p>
		<span class="f32">World</span>
		<p class="f32">!!!</p>
	 </div>
	 <!-- 嵌入样式表 -->
	 <p style="border: ;"></p>
</body>
</html>

在这里插入图片描述

CSS最基本的分类:标签样式表,类样式表,ID样式表,组合样式表

CSS从位置上的分类:内部样式表(style在本页面head标签内部),嵌入样式表(syle在某个标签属性上),外部样式表(单独一个文件写css,通过引入该页面)
外部样式表的引入

<link rel="stylesheet" href="css文件地址">

CSS盒子模型(div)

<html>
<head>
	<meta charset="UTF-8">
	<!-- 内部样式 -->
	<style type="text/css">
		#div1{
			width: 400px;
			height: 400px;
			background-color: greenyellow;
			/* 边框样式 */
		    border-width: 4px;   /* 边框粗细 */
			border-style: solid; /* 边框样式 */
			border-color: blue;/* 边框颜色 */
/* 
			border: 4px solid blue;
			border-top: 4px solid blue; */

		}
		#div2{
			width: 200px;
			height: 200px;
			background-color: darkorange;

			/* margin-top: 100px;
			margin-left: 100px; */
			/* 外部填充 第一个上下,第二个左右*/
			margin: 100px 100px;
			padding-left: 50px;
			padding-top: 50px;
		}
		#div3{
			width: 100px;
			height: 100px;
			background-color: aquamarine;
			
		}
	</style>
</head>
<body>
	<!-- &nbsp空格 -->
	<div id="div1">
		<div id="div2">
			<div id="div3">&nbsp;</div>
		</div>
	</div>
	
</body>
</html>

在这里插入图片描述

CSS布局

position:absolute -->绝对定位,需要配合left,top
relative -->相对定位,一般和float,magin,padding…配合使用

JavaScript

定义:客户端的一个脚本语言

WEB

Tomcat

CS和BS区别

CS:客户端服务器架构(lol)
优点:充分利用客户端机器的资源,减轻服务器的负荷(一部分安全要求不高的计算任务存放在客户端执行,不需要把所有的计算和存储都在服务器端执行,从而减轻服务器的压力,也能够减轻网络负荷)
缺点需要安装;升级维护成本较高
BS:浏览器服务器架构模式
优点:客户端不需要安装;维护成本较低
缺点:所有的计算和存储任务都在服务端的,服务端的负荷较重;在服务端计算完成之后把结果在传输给客户端,客户端和服务器端会进行频繁的数据通信。从而网络负荷较重

参考https://heavy_code_industry.gitee.io/code_heavy_industry/pro001-javaweb/lecture/

###Tomcat部署和启动
在tomcat的webapps目录下部署项目
在这里插入图片描述
启动:在tomcat的bin目录点击start
访问部署好的web资源:浏览器输入http://ip地址:8080/web项目名/资源名

IDEA部署Tomcat项目

1,创建artifacts(webapp目录下的web工程)
artifacts是部署包(webapps下的工程项目包,源码必须要打成artifact部署包才能部署在tomcat上),exploded的是解压之后的包,archive是压缩包war包(tomcat启动会自动压缩)
在这里插入图片描述
2,把该artifacts部署在tomcat上
在这里插入图片描述

在这里插入图片描述

Servlet

Servlet入门-获取参数

业务目的:客户端发送访问javaweb项目里的add.html页面(一个表单),服务器返回给客户端add.html,用户填写表单,然后点击提交,action=add,发送给服务器,服务器调用addServlet处理请求并返回。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
要实现AddServlet需要继承HttpServlet(导入Servlet-api依赖)
在这里插入图片描述
服务器处理提交表单请求的servlet过程:
1,用户发送请求action=add
2,项目中,web.xml中找到url-pattern=/add --》第12行
3,找到11行的servlet-name=AddServlet
4,找到和servlet-mapping中servlet-name一致的servlet,找到第七行
5,找到第八行的servlet-class-》com.atiguigu.servlets.AddServlet
6,用户发送的post请求(method=post),因此tomcat执行AddServlet的doPost()方法

Servlet-处理请求乱码

在这里插入图片描述

Servlet的继承关系

1,继承关系
javax.servlet.Servlet接口
	javax.servlet.GenericServlet抽象类
		javax.servlet.http.HttpServlet
2.相关方法(service()重点)
javax.servlet.Servlet接口:
	void initi(config) -- 初始化方法
	void service(request,response) --服务方法
	void destroy() -销毁方法
javax.servlet.GenericServlet抽象类
	void service(request,response) -仍然是抽象的
javax.servlet.http.HttpServlet抽象子类:
	void service(request,response) -不是抽象的
	{
	1String method = req.getMethod(); //获取请求的方式
	2,各种if判断,根据请求方式不同,决定调用不同的do方法
	do get(){获取协议,http不支持get请求,返回405}
	若子类只实现了do post(),客户端发送method=get,则调用父类httpservlet 的do get(),返回msg信息405报错。
	3,httpServlet这个抽象类,do方法都差不多
	}

在这里插入图片描述
总结

  1. 继承关系,HttpServlet继承GenericServlet(抽象类),GenricServlet实现Servlet
  2. Servlet中的核心方法,init(),service(),destroy()
    service()
  3. 当有请求发送给服务器,service()会自动响应(其实是tomcat容器调用的),在HttpServlet中我们会去分析请求的方式:倒是是get,post,head还是delete等等,然后再决定调用那个do开头的方法,在HttpServlet中这些方法默认都是405的实现我们子类去实现对应的方法,否则返回405错误
  4. 因此,我们在新建Servlet时,才回去考虑请求方法,从而决定重写那个do方法

Servlet的生命周期

ServletContext对象早于Servlet对象创建,前者是该web应用启动创建,后者在第一次http请求创建并初始化
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.生命周期:从出生到死亡,对应Servlet的三个方法:init(),service(),destroy()
2.默认情况下:第一次接受请求时,这个Servlet会进行实例化(调用构造方法),初始化(init()),然后服务(service()),第二次请求开始,每一次都是服务,当容器关闭时,其中的所有的servlet实例会被销毁(destroy()),调用销毁方法
3.- Servlei实例tomcat只会创建一个,所有的请求都是这个实例去响应
-第一次请求,tomcat才会实例化,初始化,好处:提高系统启动速度,对第一次请求不友好
-因此如果需要提高系统的启动速度,默认情况就是这样。如果提高响应速度,要设置Servlet的初始化时机
4.Servlet的初始化时机:
-默认是第一次请求时,实例化,初始化
-我们可以通过来设置servlet启动的先后顺序,数字越小启动越靠前,最小值0
5,Servlet在容器中是
单例的: 所有的请求都是同一个实例去响应
线程不安全: 一个线程需要根据这个实例的某个成员变量去作逻辑判断,但是这个时候另外个线程改变了这个成员变量的值
启发: 尽量不要再servlet中定义成员变量,如果不得不定义成员变量,那么不要去根据成员变量作逻辑判断
在这里插入图片描述

servlet-Http协议

HTTP:Hyper Text Transfer Protocol超文本传输协议。
请求响应包含两个部分:请求和响应,Http是无状态的。
**无状态:**有两个http请求发给服务器,服务器无法判断这两次请求是同一个客户端发来的,还是不同客户端发来的
在这里插入图片描述

请求报文

1 请求行:
作用:展示当前请求的最基本信息

  • 请求方式
  • 访问地址
  • HTTP协议的版本

2 请求头
作用:通过具体的参数对本次请求进行详细的说明
格式:键值对,键和值之间使用冒号隔开
相对比较重要的请求消息头:
在这里插入图片描述
3 请求体
get方式没有请求体,但是有一个queryString
在这里插入图片描述

post方式,有请求体,form data
在这里插入图片描述

json格式,有请求体,request payload
在这里插入图片描述

响应报文

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

servle-session会话跟踪技术

1,Http是无状态的
无状态带来的问题:第一次请求是添加商品到购物车,第二次请求是结账。如果这两次请求无法区分是同一个用户,导致混乱,结账是别人的购物车。
解决会话跟踪技术
在这里插入图片描述

  1. 客户端第一次发请求给服务器,服务器获取session,获取不到,则创建新的,然后响应给客户端
  2. 下次客户端再次给服务器发送请求,会把sessionID带给服务器,服务器就能获取到了,服务器根据cookies判断和上次请求是否是同一个就能区分不同客户端的请求。
    常用的API:
    request.getSession() =>获取当前的会话,没有则创建新的会话
    request.getSession(true) =>效果和不带参数一样
    request.getSession(false) =>获取当前会话,没有返回null,则不会创建新的

session.getId() =>获取sessionID
session.isNew() =>判断当前session是否是新的(session的有效时间半小时)
session.getMaxInactiveInterval() => session的不操作的间隔时间,半小时,半小时不操作断开
session.setMaxInavtiveInterval()
session.invalidate() =>强制性让会话立即失效

session保存作用域

在这里插入图片描述
同一个客户端(会话)有自己的作用域(容器),保存获取数据。

服务器内部转发和重定向

1 服务器内部转发
在这里插入图片描述
在这里插入图片描述

2 重定向
在这里插入图片描述
在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/593082cf0c7442c4b0ecfa3af

Thymeleaf -视图模板技术

在这里插入图片描述
**业务目的:**向index组件Servlet发送请求,tomcat处理service()从数据库查询得到的数据保存在session作用域,然后用thymeleaf将查询到的数据渲染到静态页面上
Service()方法如下:

@WebServlet("/index")//注册servlet
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        FruitMapper mapper = sqlSession.getMapper(FruitMapper.class);
        List<Fruit> list = mapper.getFruitList();
        //保存到session作用域
        HttpSession session = req.getSession();
        session.setAttribute("fruitList",list);
        //此处的index是视图名称
        //thymeleaf会将这个逻辑视图名称对应到物理视图 名称上去
        //逻辑视图名称:index
        //物理视图名称:view-prefix+逻辑视图名称+view-suffix
        //所以物理视图跳转的真实地址:/index.html
        super.processTemplate("index",req,resp);

    }
}

  1. 添加thymeleaf的jar包(maven 添加thymeleaf依赖)
    在这里插入图片描述
    2.新建一个Servlet类ViewBaseServlet
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

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 ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {

        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);

        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);

    }

    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

3.在web.xml添加配置
配置前缀 view-prefix
配置后缀vie-suffix
在这里插入图片描述
4.使得我们的Servlet继承ViewBaseServlet,使我们的Servlet拥有渲染数据到页面的功能,自动跳转到物理视图地址上。

public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        FruitMapper mapper = sqlSession.getMapper(FruitMapper.class);
        List<Fruit> list = mapper.getFruitList();
        //保存到session作用域
        HttpSession session = req.getSession();
        session.setAttribute("fruitList",list);
        //此处的index是视图名称
        //thymeleaf会将这个逻辑视图名称对应到物理视图 名称上去
        //逻辑视图名称:index
        //物理视图名称:view-prefix+逻辑视图名称+view-suffix
        //所以物理视图跳转的真实地址:/index.html
        super.processTemplate("index",req,resp);

    }

5.使用thymeleaf标签实现渲染数据(使用数据库获得的数据保存在servlet作用域,用thymeleaf从作用域中取数据用从而修改静态页面)
th:if , th:unless ,th:each ,th:text

渲染的标签代码
在这里插入图片描述
原始静态页面
在这里插入图片描述
从数据库获取数据然后通过themleaf渲染得到后的页面
在这里插入图片描述
获得的数据库数据
在这里插入图片描述

保存作用域

request对象
**一次请求响应范围。**request对象内数据的存活范围就是在request对象的存活范围内。当客户端向服务器端发送一个请求,服务器向客户端返回一个响应后,该请求对象就被销毁了;之后再向服务器端发送新的请求时,服务器会创建新的request对象,request对象与之前的request对象没有任何关系,因此也无法获得在之前的request对象中所存放的任何数据。
重定向:两次请求响应,request.getArribute()不同作用域
在这里插入图片描述

请求转发:一次请求响应同一个作用域

session对象
**一次会话范围有效。**session对象内数据的存活范围也就是session对象的存活范围(只要浏览器不关闭,session对象就会一直存在),因此在同一个浏览器窗口中,无论向服务器端发送多少个请求,session对象只有一个。
在这里插入图片描述
application对象
一次应用程序范围有效(tomcat不关闭之前,所有客户端都可以获取application的数据)
在这里插入图片描述

MVC

dispatcherServlet(核心控制器)

在这里插入图片描述

1.根据请求的url获取servletPath,根据servletPath解析出名字

2.解析xml文件application.xml,读取所有的bean标签,存入一个hashmap<id,class的实例对象>
在这里插入图片描述

 InputStream is = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(is);
            NodeList beanNodes = document.getElementsByTagName("bean");
            for (int i = 0;i < beanNodes.getLength();i++)
            {
                Node beanNode = beanNodes.item(i);
                if(beanNode.getNodeType()==Node.ELEMENT_NODE) {
                    Element element = (Element) beanNode;
                    String id = element.getAttribute("id");
                    String className = element.getAttribute("class");
                    Object beanObject = Class.forName(className).newInstance();
                    setServletContext.invoke(beanObject,this.getServletContext());
                    beanMap.put(id, beanObject);
                }

            }

3.根据servletPath从map集合中得到对应的处理该请求的servlet类(controller)的实例,然后调用,然后从它的对象中调用对应operate方法

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        //假设url是 http://localhost:8080/javaweb/hello.do
        //那么servletPath是    /hello.do
        String servletPath = req.getServletPath();
        // 第一步: servletPath /hello.do 改为 hello 或者fruit.do  fruit
        servletPath=servletPath.substring(1);
        int lastDotIndex=servletPath.lastIndexOf(".do");
        servletPath = servletPath.substring(0,lastDotIndex);
        //第二步:hello 和 HelloController对应上  或者fruit   FruitController
        Object beanObject = beanMap.get(servletPath);
        String operate = req.getParameter("operate");
        if(operate==null||"".equals(operate))
        {
            operate= "index";
        }
        //获取每个servle对应的方法
        Method[] methods = new Method[0];

        try {
            Method method = beanObject.getClass().getDeclaredMethod(operate,HttpServletRequest.class,HttpServletResponse.class);
            if(method!=null){
                method.setAccessible(true);
                method.invoke(beanObject,req,resp);
            }
            else{
                throw new RuntimeException("operate值错误");
            }
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }

提取视图通用代码

  if(method!=null){
                //controller组件中的方法调用
                method.setAccessible(true);
                Object  returnObj= method.invoke(beanObject,req);
                String methodReturnStr = (String)returnObj;
                //视图处理
                if(methodReturnStr.startsWith("redirect")){ //比如redirect:fruit.do
                    String redirectStr = methodReturnStr.substring("redirect".length());
                    resp.sendRedirect(redirectStr);
                }
                else {
                    super.processTemplate(methodReturnStr,req,resp);  //比如edit
                }
            }

在这里插入图片描述
在这里插入图片描述

在核心控制器中统一获取参数以及视图处理

  Method[] methods = beanObject.getClass().getDeclaredMethods();
            for(Method method:methods){
                if(operate.equals(method.getName()))
                {
                    //1 .统一获取参数组
                    Parameter[] parameters = method.getParameters();
                    Object[]parameterValues = new Object[parameters.length];
                    for(int i=0;i<parameters.length;i++)
                    {
                        Parameter parameter = parameters[i];
                        String parameterName= parameter.getName();
                        System.out.println(parameterName);
                        if("req".equals(parameterName))
                        {
                            parameterValues[i]=req;
                        }
                        else if("resp".equals(parameterName))
                        {
                            parameterValues[i]=resp;
                        }
                        else if("session".equals(parameterName))
                        {
                            parameterValues[i]=req.getSession();
                        }
                        else {
                            String parameterValue = req.getParameter(parameter.getName());
                            parameterValues[i] = parameterValue;
                        }
                    }
                    // 2. controller组件中的方法调用
                    method.setAccessible(true);
                    Object  returnObj= method.invoke(beanObject,parameterValues);
                    String methodReturnStr = (String)returnObj;
                    //3. 视图处理
                    if(methodReturnStr.startsWith("redirect")){ //比如redirect:fruit.do
                        String redirectStr = methodReturnStr.substring("redirect".length());
                        resp.sendRedirect(redirectStr);
                    }
                    else {
                        super.processTemplate(methodReturnStr,req,resp);  //比如edit
                    }
                }
            }

获取真正的参数名要在设置中添加–parameters,不然参数名为arg0,arg1…,不是真正的形参名(id,name)
在这里插入图片描述
总结:

在这里插入图片描述
在这里插入图片描述

servlet-API

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

业务层的引入

在这里插入图片描述

IOC的实现

在这里插入图片描述
1,property 的name是当前bean标签对应实例的属性名(依赖类型的引用变量),ref是依赖类的bean标签的id值。每一个bean标签代表每一个组件(controller,service,dao)
在这里插入图片描述
Ioc实现
1.根据id值获取对应类的实例,存放在map容器中

 InputStream is = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(is);
            NodeList beanNodes = document.getElementsByTagName("bean");
            for (int i = 0;i < beanNodes.getLength();i++)
            {
                Node beanNode = beanNodes.item(i);
                if(beanNode.getNodeType()==Node.ELEMENT_NODE) {
                    Element element = (Element) beanNode;
                    String id = element.getAttribute("id");
                    String className = element.getAttribute("class");
                    Object beanObject = Class.forName(className).newInstance();
                    beanMap.put(id, beanObject);
                }

            }

2.遍历所有bean元素结点的子元素property节点,将ref对应的实例赋值给该bean标签对应实例的name属性,完成解除该组件和依赖组件的耦合关系

在这里插入图片描述
在这里插入图片描述

Filter

在这里插入图片描述

  1. Filter也属于Servlet规范
  2. 使用Filter步骤:新建类实现Filter接口,然后重写其中的三个方法:init,doFilter,destroy,配置Filter,可以用@WebFilter(拦截的servlet的url-pattern)),也可以用,
    在这里插入图片描述
    在这里插入图片描述
    3.过滤器也可以拦截多个请求,和servlet一样,可以设置通配符,例如@WebFilter(“*.do”)表示拦截所有以.do结尾的请求
    4.过滤器链
    在这里插入图片描述
    如果采取的是注解的方式进行配置(@WebServlet),那么过滤器的拦截顺序是按照全类名的先后顺序
    如果采取的是xml的方式配置,那么按照配置的先后顺序进行排序
    5.将中央控制器的设置编码统一到过滤器完成
    在这里插入图片描述
    在这里插入图片描述

事务管理

在这里插入图片描述
假设该业务有三个DAO操作,有两个成功,一个失败回滚,那么该业务执行不成功。因此,事务管理不能在以DAO层的单精度方法为单位,应该以业务层的方法为单位

在这里插入图片描述

事务管理的实现

在这里插入图片描述

1.创建一个Filter实现类,实现事务管理,该事务中每一个DAO操作都成功则事务完成提交,有一个DAO操作失败就会回滚。
在这里插入图片描述

在这里插入图片描述
SqlSessionUtil类(获取连接,新建连接存入threadlocal,关闭连接设置threalocal为空)
使所有dao操作使用同一个链接(从threadlocal中获取)

public class SqlSessionUtil {
    private static  ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
    public  static SqlSession createSqlSession() throws IOException {
        SqlSession sqlSession=null;
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(is);
            sqlSession = factory.openSession(false);
        }catch(IOException e){
                e.printStackTrace();
        }
        return sqlSession;
    }
    public static SqlSession getSqlSession() throws IOException {
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession==null)
        {
           sqlSession =  createSqlSession();
           threadLocal.set(sqlSession);
        }
        return sqlSession;
    }
    public static void closeSqlSession() throws SQLException {
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession==null){
            return ;
        }
        if(sqlSession.getConnection()!=null)
        {
            sqlSession.close();
            threadLocal.set(null);
        }
    }

ThreadLocal

方法set(),get()(同一个线程内共享
set方法在当前线程存储数据,get从当前线程获取数据。
set方法源码:
在这里插入图片描述
get 方法源码:
在这里插入图片描述

Listener

参考https://heavy_code_industry.gitee.io/code_heavy_industry/pro001-javaweb/lecture/chapter11/verse02.html

总结

在这里插入图片描述

Cookie

https://heavy_code_industry.gitee.io/code_heavy_industry/pro001-javaweb/lecture/chapter09/verse02.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值