bingmous

欢迎交流,不吝赐教~

导航

JavaWeb学习笔记


站得高,看得远,从设计框架的角度出发去思考问题。

源码不能只看,一定要上手。

HTML

  • html语言是解释型语言,不是编译型,浏览器是容错的,写错了浏览器也会解析。
  • html页面中由一对标签组成:<html>开始标签,</html>结束标签
  • html中有<head>标签和<body>标签
  • head标签中的title表示网页的主体(浏览器的标签上显示),可以在meta标签中设置编码方式

  • 表示换行 。br标签是一个单标签。单标签:开始标签和结束标签是同一个,斜杠放在单词后面
  • p 表示段落标签
  • img 标签图片标签
  • h1~h6 : 标题标签
  • 列表标签:
    • ol 有序列表(start 表示从第几开始,type 显示的类型:A a I i 1(deafult))
    • ul 无序列表(type disc(default) , circle , square)
  • u 下划线 b 粗体 i 斜体
  • 上标 sup 下标 sub
  • HTML中的实体: 小于号 < 大于等于号 ≥ 版权 ©
  • span 不换行的块标记
  • a 表示超链接
    • href 链接的地址
    • target:
      -_self 在本窗口打开
      -_blank 在一个新窗口打开
      -_parent 在父窗口打开
      -_top 在顶层窗口打开
  • div 层
  • 表格 table
    • 行 tr(table row)
    • 列 td(table data,行中的一个小格)
    • 表头列 th(table head)
    • table中有如下属性(虽然已经淘汰,但是最好了解一下)
      • border:表格边框的粗细
      • width:表格的宽度
      • cellspacing:单元格间距
      • cellpadding:单元格填充
      • rowspan : 行合并(tr)
      • colspan : 列合并(td)
      • tr中有一个属性: align -> center , left , right,居中、居左、居右
  • 表单 form
input type="text" 表示文本框 , 其中 name属性必须要指定,否则这个文本框的数据将来是不会发送给服务器的
input type="password" 表示密码框
input type="radio" 表示单选按钮。需要注意的是,name属性值保持一致,这样才会有互斥的效果;可以通过checked属性设置默认选中的项
input type="checkbox" 表示复选框。name属性值建议保持一致,这样将来我们服务器端获取值的时候获取的是一个数组
select 表示下拉列表。每一个选项是option,其中value属性是发送给服务器的值 , selected表示默认选中的项
textarea 表示多行文本框(或者称之为文本域),它的value值就是开始结束标签之间的内容
input type="submit" 表示提交按钮
input type="reset" 表示重置按钮
input type="button" 表示普通按钮
input type="text" 表示文本框 , 其中 name属性必须要指定,否则这个文本框的数据将来是不会发送给服务器的
input type="password" 表示密码框
  • frame,表示框架中的具体页面引用
frameset 表示页面框架,这个标签已经淘汰,了解,把页面划分为多个页面,不能有body标签
iframe,页面上嵌入其他页面,放在body里
# html中页面显示效果相关的标签、属性基本都淘汰了,使用css替代(层叠式样式表)

CSS

  • html决定页面上显示哪些内容,CSS决定显示的样式、风格
  • css代码可以完全脱离html
  • 基础语法:标签样式表,类样式表,ID样式表,组合样式。
    • 从位置上:嵌入式样式表(在标签的内部写),内部样式表(style标签内),外部样式表(.css)
  • 盒子模型:border(边框),margin(间距),padding(填充)
  • 定位和浮动:position,float,div+css布局

JavaScript

  • 客户端(浏览器端)运行的一个脚本语言,语法风格与java比较类似,是一门弱类型的语言,变量的数据类型由后面赋的值的类型决定。
  • 有一些内置对象:window,document
  • 函数 function hello(){},调用时参数可任意传
  • js代码可以完全脱离html,标签绑定事件可以在页面加载时window.onload使用js绑定

Servlet

tomcat安装使用

  • 下载:https://mirrors.cnnic.cn/apache/tomcat/ ,解压即可,版本选择参考官网
  • 需要配置好JAVA_HOME环境变量
  • idea配置
    • 启动项中配置tomcat启动,在模板中配置好tomcat的home目录
    • 创建一个启动项,选择tomcat,deployment配置自己的工程,如果没有artifact选项,需要在Project Structure -> Artifacts中添加Web Applicatoin,选择From Modules,选择项目
    • Application context配置为/
    • 返回server界面,配置On Update action为Redeploy,配置On frame deactivation为Update classes and resources。
    • tomcat输出乱码问题:在idea Help -> Edit custom VM options,增加-Dfile.encoding=UTF-8
    • 代码没有编译到WEB-INF下:在Artifacts下,Output LayoutAvailable Elements右键Put into Output Root,然后重启idea,或者删除idea的配置文件,重写加载项目,后加的依赖也需要使用这种方式将依赖加到部署项目的WEB-INFO下的lib目录
    • 中文在output显示异常(不是乱码),需要增加tomcat启动配置-Dfile.encoding=UTF-8
  • 在web下写一个html文件,写一个表单,发送post请求,server端web.xml配置servlet和servlet-mapping,在HttpServlet子类中重写doPost方法,这个方法就用来处理web.xml中配置的mapping请求路径。web.xml是web工程的入口配置文件(注册Servlet、Listener、Filter,Spring有注解方式可以代替配置文件)

pom需要添加javax.servlet-api依赖:

<!--javaee servlet api-->
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

配置web.xml:

    <servlet>
        <servlet-name>addServlet</servlet-name>
        <servlet-class>org.example.servlet.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>addServlet</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

Servlet继承关系

抽象类HttpServLet,继承抽象类GenericServlet,实现接口Servlet

接口Servlet中有三个核心方法(init(),service(),destroy()),请求进来后会调用service()方法,里面会根据调用请求方法分别调用doXxx()方法,在HttpServlet里有对doXxx的默认实现,返回都是405。

Servlet生命周期

在第一次调用时,容器通过反射创建对应的Servlet,调用init()方法,调用service()方法响应,之后的调用都会调用service()方法,在容器关闭时,调用destroy()方法。

因此,Servlet实例tomcat只会创建一个,所有请求都是这个实例去响应。只有第一次请求时,才会实例化,初始化,好处是提高系统启动速度,坏处是第一次调用较耗时。

Servlet初始化时机:可以通过<load-on-startup>设置Servlet的启动顺序(随着tomcat容器的启动而启动),数字越小,优先级越高,最小值0。

Servlet是单例的、线程不安全的:单例指所有请求都由一个Servlet对象处理。

Http协议

Http协议称为超文本传输协议,是无状态的,Http包含请求和响应

  • 请求:包含请求行、请求消息头、请求体。
    • 请求行包含:请求方式,请求的url,请求的协议(Http1.1)
    • 请求消息头:包含了很多客户端需要告诉服务器的信息,比如浏览器版本号、版本、能接受的媒体类型、发送内容的长度等
    • 请求体:get方式没有请求体(有queryString),post方式有请求体(form data),json格式有请求体(request payload)
  • 响应:包含响应行,响应头,响应体
    • 响应行包含:协议,响应状态码(200),响应状态(OK)
    • 响应头:包含了服务器的信息;服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)
    • 响应体:响应的实际内容(比如html文本内容)
200:正常响应
404:找不到资源
405:请求方式不支持
500:服务器内部错误

会话跟踪技术

客户端第一次发送请求给服务器,服务器获取session,获取不到创建新的,将session响应给客户端,下次客户端给服务器发请求时,会把sessionId带给服务器,那么服务器可以判断这一次请求和上一次请求时同一个客户端

常用api:

  • request.getSession(),获取当前会话,没有则创建一个新的会话
  • request.getSession(true),与不带参数相同
  • request.getSession(false),获取当前会话,没有则返回null
    • session.getId(),获取sessionId
    • session.isNew(),判断当前会话是不是新的
    • session.getMaxInactiveInterval(),session的非激活时间间隔时长,默认1800秒
    • session.invalidate(),让会话立即失效
    • ...

session保存作用域:向session中setAttribute(k,v),在别的Servlet中可以在同一个会话(同一个浏览器访问)中获取到该数据

其他作用域:

  • request作用域:单个请求内有效
  • application作用域:整个应用内有效,通过获取ServletContext获取到Application作用域

服务器转发和重定向

  • 服务器转发是内部转发,客户端无感,客户端发送一次
  • 客户端重定向:服务器响应302,客户端重写发送请求,客户端发送两次,请求url会变

Thymeleaf

视图模板技术,将Servlet里获取到的数据渲染到html上,并将html返回给客户端。这样在前端就可以显示html页面了(直接访问的话是静态页面,数据都是固定的,可以使用thymeleaf语法进行渲染,并且不让客户端直接访问静态页面)

需要用到javax里面的dom技术解析xml文件,xml文件中配置thymeleaf配置前缀后缀的配置

Servlet优化(DispatcherServlet思想)

页面上每一个请求,对应一个Servlet处理,该结构过于简单,Servlet太多了。

优化思想1:把一系列请求都对应一个Servlet,通过一个请求参数确定不同的操作,使用switch-case分别调用不同方法(这是的方法都是原来的Servlet,参数都是一样的)。

优化思想2:在Servlet中处理的时候根据这个参数利用反射调用不同的方法(不用switch-case),用多个方法替代多个Servlet,用参数区分调那个方法,要求参数值与方法名相同,才能通过反射找到(或者写Map对应关系)。

然而,在每个方法内,都会有转发、重定向不同页面、获取request作用域的参数等操作,这些操作过程都是相同的。同时,当有很多业务时,每个Serv都要利用反射调用不同方法,这样的处理方式有更多,而且处理过程类似。

优化思想2:考虑一个业务为一个Controller(也就是上面的一个Servlet,后面优化后不在是Servlet),对于不同业务的不同url,都使用同一个Servlet处理(DispatcherServlet),根据url的地址分别让不同的Controller处理,该映射关系可以通过一个xml文件配置,如<bean id="hello" class="HelloController">(Spring IOC思想),首先将该配置文件处理为Map<String, Class>,在这个Servlet内,通过url在Map中查找指定的class,并通过反射创建该对象。

同时,将原来所以Servlet中的利用反射调用方法的逻辑放入DispatcherServlet处理,原来Servlet方法中的转发、重定向、获取request参数,都在DispatcherServlet中利用反射获取、调用(Controller功能主要有三个:获取参数、业务处理、视图处理,将获取参数和视图处理放在DispatcherServlet中)。

其中,request作用域的参数需要根据原来Servlet方法中的参数名称获取,可以在File | Settings | Build, Execution, Deployment | Compiler | Java Compiler增加命令行参数-parameters,就可以通过反射获取到参数名称了,否则编译的都是arg0,arg1...

Servlet api

Servlet生命周期:实例化(无参构造)、初始化(init方法)、服务(service方法)、销毁(destroy方法)

init有两个,一个是带参数的(ServletConfig),一个是不带参数的,带参数的会调用不带参数的,因此,不带参数的是留给开发人员重写做一些初始化操作的。

ServletCongfig里面的参数可以在web.xml配置Servlet时通过<init-param>配置,并在代码中获取。也可以在@WebServlet注解中配置(单个Servlet的初始化参数)

也可以在web.xml中配置上下文参数<context-param>,这些值可以在代码获取的上下文中获取(应用级别的初始化参数,需要先获取ServletContext)

获取post请求体的数据需要使用req.getInputStream()获取输入流

MVC

Model(模型):pojo(Plain Ordinary Java Object)、vo(Value Object),dao(Data Access Object),包括保存数据和处理数据,像实体类就是保存数据的,DAO类和Service类都是处理数据的

View(视图层):用于做数据展示以及和用户交互的一个界面,比如html/jsp页面

Controller(控制层):用于接收用户的请求并响应,具体的业务需要借助模型层的模型完成,比如Service和DAO

控制反转(IOC):一个实现的例子,多层之间的对象耦合通过配置xml文件实现,在程序启动时,将依赖的属性注入。自定义容器实现MVC解耦(根据xml文件,实现Controller层、Service层、DAO层的IOC、DI)

DAO中都是单精度的方法,一个Service方法会调用多个单精度方法,Controller中就可以调Service层的方法,而不是调用多个DAO方法。因为,Controller直接调用业务方法,业务有多复杂都封装到Service层

Filter

也属于Servlet规范,需要实现Filter接口,实现其中的三个方法(init,doFilter,destroy),配置@WebFilter("/filter/url")(也可以通过配置文件,类似Servlet的xml配置)。放行是执行filterChain.doFilter(req, res)

如果使用注解形式配置,按照全类名的先后顺序,如果是xml配置文件形式,按照配置先后顺序执行

应用:

  • 可以在编码过滤器中设置编码,后续DispatcherServlet就不用考虑编码了
  • 做事务,开启事务后放行,放行后提交事务
    • 难点是所有DAO都要用同一个connection

事务

事务管理不能以DAO单精度操作管理,而是应该以业务层的方法为单位

事务实现:使用ThreadLocal在Utils中处理连接,在TransactionManager中做事务管理,利用TransactionManager在Filter中对单个要处理的业务做事务管理(开启事务、提交事务、回滚事务),在底层的DAO里面也使用Utils(ThreadLocal)获取连接,因为这里Filter - DispatcherServlet - Controller - Service - DAO都是同一个线程的调用,所以获取到的是同一个连接。

DispatcherServlet里面init方法创建ClassPathXmlApplicationContext对象,该对象解析xml文件向beanFactory注入Controller、Service、DAO。DispatcherServlet通过反射解析url,根据url去beanFactory里面获取到Controller,然后根据url中的参数调用Controller中的指定方法(url中的参数配置与Controller中的方法是一样的)

Listener

主要有8个:
监听各自级别对象的创建和销毁的过程:ServletContext对象、HttpSession对象、Servlet对象,两个方法,xxxInitialized(),xxxDestroyed()

  • ServletContextListener
  • HttpSessionListener
  • ServletRequestListener

监听各自保存作用域的改动的过程:ServletContext、HttpSession、Servlet,三个方法,添加、删除、替换

  • ServletContextAttributeListener
  • HttpSessionAttributeListener
  • ServletContextAttributeListener

监听某个对象在session域中的创建和移除:

  • HttpSessionBindingListener

监听某个对象在session域中的序列化和反序列化:tomcat重新部署的时候会将内存中的对象序列化,然后再反序列化,保存原来的数据

  • HttpSessionActivationListener

应用:当上下文创建的时候希望ioc已经准备好了,而不是在DispatcherServlet的init方法里面初始化,使用上下文监听器,创建ioc容器,在DispatcherServlet的init中根据属性获取到ioc容器

Cookie

浏览器保存连接数据的地方,比如sessionId,服务器创建Cookie,添加到响应中,浏览器就会保存该Cookie,下次访问服务器时会携带

api:

  • 设置有效期
  • 设置Domain、Path

应用:

  • 浏览器记住用户名和密码
  • 免登陆

Kaptcha:验证码
正则表达式

vue

简单使用:

window.onload=function(){
	var vue = new Vue({
		el: "#div0",
		data: {
			k: "value"
		},
		methods: {//这里面要是引用vue的数据需要使用vue.k,而不是this.k
			myFunc: function(){
				//your function
			}
		}
		watch: { //监听属性变化
			k: function(newK){
				this.k=newK;
			}
		},
		//生命周期
		beforeCreate: function(){}, # 对象创建之前
		created: function(){}, # 创建之后
		beforeMount: function(){}, # 数据装载之前
		mounted: function(){}, # 数据装载之后
		beforeUpdate: function(){}, # 数据更新之前
		updated: function(){}, # 数据更新之后
	});
	
}

{{}},相当于.innerText
v-bind:value="k" 或者:value="k",绑定属性
v-model:value="k"或者v-model="k",双向绑定
	v-model.trim,去除输入的首位空格
v-if="num%2==0",v-else:"num%2==0",两个元素直接不能有其他元素
v-show="num%2==0",是通过修改样式display:none控制是否显示
v-for="a in as",{{a.xxx}},表示迭代
v-on:click="myFunc",或者@cliek,表示绑定点击事件

Axios

是ajax的一个框架,简化ajax操作。

axios({
	method:"POST",
	url:"/xxx",
	params: { //发送普通参数,可以使用data发送json数据
		k1: v1 
	}
}).then(function(value){ //成功时的回调,value.data可以拿到服务器响应数据,详细可调试前端输出
	//when success
}).catch(function(reason){ //reason.response.data可以获取到异常信息
	//when fail
})

# js中string与json格式转换
JSON.stringify(Object),Object -> String
JSON.parse(String),String -> Object

# 前端
alert(typeof xxx),查看xxx的类型
console.log(xxx),向前端的consul打印日志

项目

QQZone项目
书城项目

posted on 2022-06-29 21:50  Bingmous  阅读(58)  评论(0编辑  收藏  举报