该博文只会对每个技术点知识点做最宽泛的总结,想要熟练掌握还需自己用功学习
Java web中最核心的思想就是B/S的交互,即浏览器与服务器的交互
html称为超文本标记语言(HyperText Mark-up Language),浏览器是HTML文件的解释器,对大小写不敏感
- 在web服务器中,html文件将直接返回给浏览器执行
- 而jsp文件是由web服务器执行,将执行生成的结果返回给浏览器
<p>p>
<a href="" name="">a>
<h1>h1>
<br>
<img src="" alt=""/>
<table>表格table> <tr>行tr> <td>表元td> <th>表头(标题)th>等等
<form action="表单提交的位置" method="发送请求的方式(get/post)"
enctype="文件上传(有默认表单提交方式的取值,当我们要文件上传时要用multipart/form-data)">
表单
<input type=""/>
<select multiple>
<option value="">选项option>
select>
<textarea>textarea>
form>
<script>写脚本的地方sctipt>
<link>引入css样式link>
<style>编写样式style>
当标签遗忘用法时,记得去什么地方查文档就好
css是“层叠样式表单”,是一种标记性语言
语法实例:
选择器:{
样式名:样式值;
样式名:样式值;
样式名:样式值;
}
#subBtn{
color:red;
}......
同样知道去那里查询就好。
JS是一个脚本语言。
var 关键字 = "asdasd";
var关键字无类型之分
var obj = {
username:"xxx",
name:"xxx",
age:xxx
};
//输出
alert(obj.username);
//往里面添属性
obj.email="[email protected]";
//第一种声明
function 方法名(){
方法体;
};
//第二种声明
var 方法名 = function(){
方法体;
};
//调用
方法名.();
用户和浏览器交互的行为
//调用慢,但保险
//当调用两次时,第二次里面的内容有效,相当于值覆盖的操作
window.onload = function(){
文档加载完成(页面里面的所有内容全部显示成功);
};
//调用快
$(function(){
也称之为文档加载完成(dom准备就绪);
});
常用事件:如何给一个事件绑定标签
<a href="hello" id="aaa">你好a>
var aaa = document.getElementById("aaa");
aaa.onclick(function(){
alert("你好");
//这是取消默认行为(例如取消点击a标签的跳转页面行为)
return false;
};)
其他事件,每个对象的属性同样去查询文档就好
JQuery(第三方js库)就是为了简化JavaScript的开发
在掌握选择器时建议把文档里面的所有选择器都做一遍
这里只演示几个最重要的选择器
//基本选择器
#id: $("#btn01") //找到一个id为btn01的元素
element: $("a") //找到所有a标签
.class: $(".big") //找到所有class为big的元素
*: $("*") //找到所有元素
selector1.selector2.selectorN: $("#btn01","a",".big"......)
//找到id为btn01的元素和class为big元素和所有a标签
//层级选择器
ancestor descendant: //找后代
parent > child: //找子元素
$("a > #btn01") //找到a标签下id为btn01的子元素
prev + next: //找下一个兄弟
$("#btn01 + .big") //找到id为btn01的下一个class为big的同级元素
prev ~ siblings: //找到所有同辈兄弟
$("#deleBtn01 ~ a") //找到id为deleBtn01元素的所有兄弟元素,但是必须是a标签
//比较重要的选择器
:first :last :eq(index)
$("a:first") //找到第一个a标签
$(":first") //找到文档第一个标签即为
$("a :first") //找到a的第一个后代元素
$("a > :first") //找到a的第一个子元素
$("#btn01 > a:eq(1)") //找到btn01下的第二个a标签
:empty [attribute] [attribute=value]
$("a:empty") //找到所有没有标签体的标签 即标签里面没有任何内容
$("a[id]") //有id属性的所有a标签
$("a[id=btn01]") //找到id为btn01的a 等同于$("btn01")
:checked //找到所有选中的(复选框、单选框等,不包括select中的option)
:selected //匹配所有选中的option元素
//比较重要的方法选择器
//子元素和后代元素的区别请大家留心注意
find(expr|obj|ele): $("div").find(".big") //找到div后代所有class为big的标签
children([expr]): $("div").children(".big") //找到div下所有class为big的子元素
parent([expr]): $("#div01").parent(".big") //找到id为div01的父元素,而且父元素的class为big
parents([expr]): $("#div01").parent(".big") //找到class为big的祖先元素
append() //在被选元素的标签体结尾插入内容 可以链式添加
a.append(b) //a里面加b
<p id="p01">张三</p> $("#p01').append("<a href='hello'>Hello</a>")
结果:<p id="p01">张三<a href='hello'>Hello</a></p>
appendTo() //将前面的添加到后面的元素里面去
$("Hello").apppendTo($("#p01"))
prepend() - 在被选元素的开头插入内容
只要这些选择器或方法返回的还是jQuery对象(返回最开始调用者本身的jQuery)就是能使用链式调用,没有讲到的看文档就好
获取一个元素的属性值,文本内容等等
<form>
<input id="01" name="username">
</form>
<a href="hello"><h1>Hello</h1></a>
attr() 设置或返回被选元素的属性/值 自定义属性的获取和设置推荐用attr
$("#01").attr("username"); //返回username的值
$("#01").attr("username","张三") //设置username的值
$("a:first").attr("lalala")
prop() 设置或返回被选元素的属性/值 prop获取也设置不了自定义的值,获取标签原本自己的属性推荐用prop 比如获取checked的属性,返回是true\false 更加直观一点
$("#01").prop("username"); //返回username的值
html() 设置或返回被选元素的内容
$("a").html() //获取标签体内的值 结果为:Hello
$("a").html("... ") //结果会根据标签的具体功能来显示,加粗就是加粗效果
text() 设置或返回被选元素的文本内容
$("a").text() //获取标签体内的值 结果为:hello
$("a").text("... ") //结果会是...
val() 设置或返回被选元素的属性值(针对表单元素)
jQuery 是为事件处理特别设计的。
$:
作用:
var btn01 = document.getElementById("btn01");//这是dom对象
将dom对象转为jQuery对象:
$(btn01).append()
将jQuery对象转为dom对象:
$(btn01)[0];
xml为可扩展标记语言,一般用于配置文件
<p>This is a paragraphp>
<p>This is another paragraphp>
<Message>这是错误的。message>
<message>这是正确的。message>
<b><i>This text is bold and italicb>i>
<b><i>This text is bold and italici>b>
<root>
<child>
<subchild>.....subchild>
child>
root>
<note date=08/08/2008>
<to>Georgeto>
<from>Johnfrom>
note>
<note date="08/08/2008">
<to>Georgeto>
<from>Johnfrom>
note>
<message>if salary < 1000 thenmessage>
<message>if salary < 1000 thenmessage>
HTML: Hello my name is David.
输出: Hello my name is David.
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。因此,对 XPath 的理解是很多高级 XML 应用的基础。
当你创建一个新的web项目时,需要配置一个新的tomcat服务器
报文的格式:
报文头部
空行
报文主题
请求报文格式:
请求首行
请求头
空行
请求体
响应报文格式:
响应首行
响应头
空行
响应体
用来接收请求,处理请求,完成响应的一段小程序
是Javaweb的三大组件(Servlet、Filter、Listener)之一
Servlet:接口
HttpServlet:一般我们继承这个类
doGet();
doPost();
<servlet>
<servlet-name>类名servlet-name>
<servlet-class>要配置定义类servlet的全限定类名servlet-class>
servlet>
<servlet-mapping>
<servlet-name>类名servlet-name>
<url-pattern>/类名首字母小写url-pattern>
servlet-mapping>
一个servlet对应一个ServletConfig封装当前servlet的配置信息
ServletContext:
作用:
代表请求,每一次发送请求,请求的详细信息会被tomcat自动封装成一个request对象,以后要获取当前请求的一些信息,使用request对象即可
作用:
代表响应
作用:
servlet(index.jsp)-->index jsp.class-->servlet进行response.getWriter().write();
回归到底层,其实就是服务器给浏览器发送数据,都是写出字符流或字节流
Servlet的生命周期从Web服务器开始运行时开始,以后该对象会不断处理来自浏览器的访问请求,并将响应结果通过Web服务器返回给客户端,直到Web服务器停止运行,Servlet才会被清除。
GET/POST的分类:页面上除过method="POST"外剩下的都是GET请求
这里注意由于基本全是get请求,所以很多浏览器对于post请求支持的不是很到位,
所以需要我们使用postman来配合测试功能
//在调用request.getParameter("xxx")之前
//加上如下代码告诉服务器请求体中的数据使用utf-8
request.setCharacterEncoding("utf-8");
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
原因:直接写出去的数据,浏览器并不知道数据的内容类型以及编码格式等,所以浏览器会用默认格式打开
解决方法:给浏览器的数据一定要说清楚是什么
//文件
response.setContentType("text/html;charset=utf-8")
//图片则用别的
只要在html标签库中的标签里面写的路径都是浏览器解析,除此之外都是服务器解析。注意有一个例外就是:
response.sendRedirect(request.getContext()+"/xxx.jsp");
//重定向可不是服务器解析,这是浏览器要解析访问的
我推荐以后都不要使用相对路径,太不稳定了,当然具体情况具体分析
由于每次写绝对路径都要加项目名所以我们可以写一个统一项目路径的变量,建议不用base标签统一
<head>
<title>Title</title>
<%
pageContext.setAttribute("ctp",request.getContextPath());
%>
</head>
可以简单理解为在html标记中插入jsp标签和java代码
运行一个index.jsp的过程剖析:
重点介绍一下里面的四大域对象,共享数据的范围由小到大,其他未列出的对象的共享范围与pageContext一样
:会对被包含的动态页面生成单独的servlet类来进行处理并最后与包含文件的结果合并成一个响应,对于静态页面只是将其内容加载到jsp页面中
:该注释内容如果不通过查看html源代码是看不到的
<%-- --%>
:不参与jsp页面的编译,web端也会直接忽略,所以通过浏览器查看源代码也是无法查看的
单行:
//
多行:/**/
<%! int a = 0; %>
,注意此时声明的变量或方法是本页面内的全局变量
<%=符合java语法的表达式%>
,注意不能以;结尾哦
<%java code%>
scriptlet可以完成的事情:
- 声明将要用到的变量或方法
- 编写jsp表达式
- 编写Java语句
- 使用任何隐含的对象或任何用
(这是jsp中的动作标签后面会说)声明过得对象
<%@ 指令名 属性1="值1" 属性2="值2"....%>
举个例子:<%@ page="java" import="java.xxxx.xxx" pageEncoding="UTF-8"%>
由1.7中的jsp指令我们引出其中的三大指令
<%@ page attribute1="value1" attribute2="value2"......%>
说明:
- page指令通常放在jsp的开始位置,因为里面有两个属性分别是pageEncoding和contentType决定着jsp页面的字符编码,所以在web服务器开始解析的起始位置就告诉服务器
page指令中的几个常用属性:import、errorPage、isErrorPage、contentType、pageEncoding、language、session
- 除了import属性,其他属性都只能出现一次
- language:表示页面中使用的脚本语言,默认为java
- import:该属性导入jsp页面脚本环境中使用的java类
- session:指定该页面是否有http会话管理,默认为true
- contentType:可以指定返回浏览器的内容类型和字符编码格式,一般都为
<%@ page contentType="text/html";charset="UTF-8"%>
或为<%@ page contentType="application/msword";charset="UTF-8"%>
这个是能下载本页面,且权限为只读- pageEncoding:如果已经在contentType中设置了字符编码格式这里可以不设置
- errorPage:为当前页面指定错误处理页面,要与isErrorPage配合使用,也就是说错误处理页面中需要将isErrorPage设置为true
<%@ include file = "URL地址" %>
Java server pages standarded tag library,即JSP标准标签库
<c:forEach items="要遍历的集合" var="每次遍历出的元素的变量名">
$(每次遍历出的元素的变量名);
</c:forEach>
<c:if test="判断条件">
</c:if>
简化取值操作的
EL表达式只能取出11个对象中的值
四个域对象:
<form action="hello?username=张三"></form>
1. request.getParameter和request.getAttribute
在上面jsp代码块中要获取username的值使用request.getParameter来获取请求体中的参数
而request.getAttribute是获取request域中保存的一块数据
public void Request(){
//requestScope指的就是request域中存放数据一小块区域的map集合
Map<String, Object> requestScope = new HashMap<>();
public HttpSession getSession(){}
public String getParameter(String param)(){}
}
浏览器端保存少量数据的一种技术
//添加cookie
Cookie cookie = new Cookie("username","zhangsan");
//发给浏览器
response.addCooike(cookie);
//=====================================
//修改上一个cookie
responser.setCookie("Set-Cookie","username=lisi")
而此时响应头命令行会多出来一个命令
Set-Cookie:username=zhangsan
请求头中会有
Cookie:JSESSIONID=很长的一段值;username=lisi
setMaxAge(int expiry)
// 一个正数:表示多少秒后超时,超时后cookie自动删除
// 一个负数:表示cookie就是会话cookie,随着浏览器同生共死
// 0:代表cookie立即失效
//添加cookie
Cookie cookie = new Cookie("username","zhangsan");
//设置有效时间,立即失效
cookie.setMaxAge(0);
//发给浏览器
response.addCooike(cookie);
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie cookie: cookies){
String key = cookie.getName();
String value = cookie.getValue();
if(key.equals("username")){
System.out.println(value);
}
}
}
服务器端保存当前会话大量数据的一种技术
我们在与服务器进行交互期间,可能需要保存一些数据,服务器就为每个会话专门创建一个map,这个map就是session
Session保存的数据是可以在同一个会话期间共享
为什么在别的地方给session中保存的数据,在另外一个地方可以获取出来
利用浏览器每次访问会带上它所有的cookie
服务器只需要创建一块能保存数据的map,给这个map一个唯一标识(JESSIONID);创建号以后命令浏览器保存这个map标识
以后浏览器访问就会带上这个map的标识,服务器就会按照标识找到这个map,取出这个map中的数据
令牌机制的出现是为了解决表单重复提交、验证码(用户F5将之前的请求再次发出去)
第一次访问页面生成一个令牌,只要不刷新页面,F5重新发送上一次请求,令牌不会变化
servlet第一次收到令牌进行比对,比对完毕,更换或者删除令牌
下一次直接去刷新发送上次的请求,由于带来的令牌还是上次的,而这个令牌已经失效了
在访问页面的时候,生成一个令牌,
<%
String token = UUID.randomUUID().toString();
//分为两处保存
//一处给服务器保存,可以拿到
session.setAttribute("token", "token");
//一处页面保存,每次发请求带上
%>
<form>
<input name"token" value="<%=token%>"/>
</form>
SubmitServlet(){
//1.拿到服务器保存的令牌
String token01 = session.getAttribute("token");
//2.拿到页面带来的令牌
String token02 = request.getParameter("token");
if(token01.equals(token02)){
//处理请求
session.setAttribute("token","a");
}else{
//拒接处理
}
}
再复习一波三大组件,三大组件基本都需要在web.xml中进行注册,除了Listener中的两个(活化钝化监听器、绑定解绑监听器需要在Javabean中配置)
过滤器使用步骤:
<filter>
<filter-name>自定义过滤器类名filter-name>
<filter-class>全限定类名filter-class>
filter>
<filter-mapping>
<filter-name>自定义过滤器类名filter-name>
<url-pattern>/*url-pattern>
filter-mapping>
doFilter(){
//放行请求:
chain.doFilter(request, response)
}
在这么多监听器中我们只需要掌握ServletContext中的生命周期监听器(ServletContextListener)
它是监听ServletContext的创建和销毁即监听服务器的启动和停止
当服务器启动会为当前项目创建ServletContext对象,当服务器关闭销毁创建的ServletContext
JSON(JavaScript Object Notation, JS 对象表示法) 是一种轻量级的数据交换格式(与xml相比很轻量)
JS对象,属性操作特别方便
<script type="text/javascript">
var student = {name:"张三", age:18, car:{kind:"大奔", price:"¥500000"}, }
//获取car的类型
alert(student.car.kind);//大奔
</script>
如果服务器返回给浏览器的数据使js对象这种的,浏览器使用js解析就会方便很多
这时我们就用到了JSON:就是将js对象全部转成字符串来表示
在定义要将js转成json的对象代码中可以将key的值用双引号引起来(选做)
<script type="text/javascript">
//格式
{key:value, key:value}
//value的分类
//1.基本数据类型
//2.数组
{name:"李四", books:["猜火车", "追风筝的人"], 18}
//3.对象{}
//JSON用法实例
var student{name: "李四", age: 18}
var strJson = JSON.stringify(student);
alert(strJson);
//此时输出的结构类型就是字符串
</script>
<script type="text/javascript">
var student{name: "李四", age: 18}
//将js对象转为json字符串,但此时我们引用不了里面的某个变量
var strJson = JSON.stringify(student);
alert(strJson.name);//此时输出为null
//当要引用某个变量时,我们就需要把json字符串转为js对象
var studeng02 = JSON.parse(strJson);
alert(student02.name);//正常输出为李四
</script>
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)
是一种无刷新页面与服务器的交互技术,页面不刷新就可以收到服务器响应的数据。
以前的:
现在AJAX(XMLHttpRequest时AJAX的基础,而现在所有的浏览器都支持XMLHttpRequest对象):
首先先来明确一下异步和同步的区别
我们可以举一个生动的例子:当你跟你朋友在大街上面玩,突然你朋友要去上厕所对你说
回到标题我们为什么需要AJAX:
因为当我们仅需要改变页面的一小部分信息时,如果采用原来的方式,浏览器会刷新整个页面造成大量的资源浪费,这时我们采用异步无刷新页面技术,利用dom增删改的方式改变页面效果,而不是刷新整个页面
两个对底层Ajax方法的简单封装,当你只需要实现简单的Ajax时这两个方法就能满足你
方法参数列表(get与post的参数列表一模一样):
注意:
在这里我们只演示get的请求
<!--引入jQuery库-->
<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<%
pageContext.setAttribute("ctp",request.getContextPath());
%>
<div>
<button id="getBtn">$.get请求</button>
</div>
<script type="text/javascript">
//给按钮绑定单机时间
$("#getBtn").click(function(){
$.get("${ctp}/ajaxAetStu",
//第一种传入数据的方式
{name:"lisi", age:20},
//第二种传入数据的方式
"name='lisi'&age=20",
function(data){},
//第一种、在参数列表中添加指定返回值类型为json
"json"
);
//此时返回为空串,因为返回类型时string,没有调用属性之说,所以我们提供两种方式来获取
//alert(data.name);
//第二种、所以我们可以转成json对象后在获取,直接将data转为json对象
var obj = JSON.parse(date);
//此时就可以了
alert(obj.name);
//禁用默认行为
return false;
});
</script>
而get和post的请求的区别:前文我们在乱码问题那边提到过
使用底层ajax来完成
<!--引入jQuery库-->
<script type="text/javascript" src="script/jquery-1.7.2.js"></script>
<%
pageContext.setAttribute("ctp",request.getContextPath());
%>
<div>
<button id="ajaxBtn">$.ajax请求</button>
</div>
<script type="text/javascript">
//给按钮绑定单机时间
$("#ajaxBtn").click(function(){
//发送ajax请求
//所有请求的属性参数都是可以通过这个js对象定义,或者直接在$.ajax()的括号内定义
url:"{ctp }/ajax",//地址
data:"action=ajaxJquery",//表示发送给服务器的参数和数据
//这样也可以:date:{action:ajaxJquery},
type:"get",//请求类型
success:function (data){//成功访问的回调函数
// alert("服务器返回的数据是:" + data);
//var jsonObj = JSON.parse(data);
//$("#msg").html("id为:"+jsonObj.id + ",姓名为:" + jsonObj.name);
//采用第一种方式返回,就不用我们自己转换了,直接写成下面的就好
$("#msg").html("id为:"+data.id + ",姓名为:" + data.name);
},
dataType:"json"//响应的数据类型 text、xml、json
//禁用默认行为
return false;
}
注意:在jQuery-AJAX对象中,还有很多的参数没有演示:
就比如开启异步请求的开关参数(async:true),默认是true开启的状态
还有当请求失败返回错误信息的参数(error:function(这里有三个显示错误信息的参数,需用时直接定义){回调函数体})
还是那句话,具体了解查文档就好
原生的国际化步骤(十分复杂):
ResourceBundle bundle = ResourceBundle.getBundle("基础名",区域信息)
String xxx = bundle.getString("xxx");
国际化资源文件的格式:基础名(可根据不同页面的国际化来取)_语言代码_国家代码.properties
大致有这么些方法:
//获取区域信息,然后就获取配置文件的值
Locale locale = request.getLocale();
<!--记得先引用js标签库-->
<%--使用标签设置locale信息--%>
<fmt:setLocale value="${param.locale}"/>
<%--设置basename--%>
<fmt:bundle basename="i18n"/>
<!--这样根据配置文件内信息,在相对应的位置替换成标签的形式就好-->
<td><fmt:message key="username"/></td>
<form method="post" enctype="mutipart/form-date">
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.3version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
把文件流交给浏览器,一定要告诉浏览器,这个流不要打开请下载:
response.setHeader("Content-Disposition","attachment:filename=xxx.xxx");