目录
EL输出Bean的普通属性,数组属性,List集合属性,Map集合属性
Servlet
web.xml配置
ServletContext
ServletConfig
HTTP请求
Get请求HTTP协议内容
POST请求HTTP协议内容
HttpServletRequest
请求转发
特点:
1.浏览器地址栏没有变化
2.他们是一次请求
3.他们共享Request域中的数据
4.可以转发到WEB-INF目录下
5.不可以访问工程以外的资源
请求重定向
特点:
1.浏览器地址栏有变化
2.他们是两次请求
3.他们不共享Request域中的数据
4.不可以转发到WEB-INF目录下(因为WEB-INF文件夹是被保护的,不能随意访问)
5.可以访问工程以外的资源
(1)第一种方法
//设置相应状态码302,表示重定向 (已搬迁)
response.setStatus(302);
//设置响应头,说明新的地址在哪里
response.setHeader("Location", "http://www.baidu.com");
(2)第二种方法(推荐)
//方法2 直接做转发。(因为状态码固定为302)
response.sendRedirect("http://www.baidu.com");
数据的封装和抽取BeanUtils的使用
BeanUtils工具类,它可以一次性的把所有的请求参数注入到JavaBean中。
BeanUtils.populate(new Object(),req.getParameterMap());
HTTP响应
HttpServletResponse
解决响应乱码
方式一:
方式二:(推荐)
MIME
Base标签
当 .html没有base标签,a标签进行跳转时候,参照浏览器地址栏中的地址
web 中/ 的不同意义
JavaEE三层架构
Listener监听器
ServletContextListener
ServletContextListener可以监听ServletContext对象的创建和销毁;
ServletContext对象在web工程启动的时候创建,在web工程停止的时候销毁;
监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法反馈;
两个方法分别是:
public interface ServletContextListener extends EventListener {
/**
** 在ServletContext对象创建之后马上调用,做初始化
*/
public void contextInitialized ( ServletContextEvent sce );
/**
** 在ServletContext对象销毁之后调用
*/
public void contextDestroyed ( ServletContextEvent sce );
}
如何使用ServletContextListener监听器监听ServletContext对象:
1.编写一个类去实现ServletContextListener
2.实现其两个回调方法
3.到web.xml中去配置监听器
<listener>
<listener-class></listener-class>
</listener>
JSP
jsp本质
HttpJspBase类,直接继承了HttpServlet类。所以jsp翻译出来的Java类,它间接继承了HttpServlet类。也就是说,翻译出来的是一个Servlet程序
jsp头部的page指令
<!-- errorPage 表示错误后自动跳转去的路径,这个路径一般以斜杠打头,他表示请求地址为http://ip:port/工程路径/ 映射到代码的web目录-->
JSP脚本
声明脚本![](https://i-blog.csdnimg.cn/blog_migrate/add267846ec8ec91f8dc3a359255244c.png)
表达式脚本
表达式脚本的格式是:<%=表达式%>
作用:在jsp页面上输入数据
代码脚本
//代码脚本格式:
<%
java语句
%>
//作用:可以在jsp页面中,编写我们自己需要的功能(写的是Java语句)
JSP的九大内置对象 ![](https://i-blog.csdnimg.cn/blog_migrate/be34c9bbcb17d50c037c949d7ec5f8e7.png)
JSP四个域对象
JSP常用标签
静态包含![](https://i-blog.csdnimg.cn/blog_migrate/b851943410138547f3de4c9e48cae6e0.png)
动态包含![](https://i-blog.csdnimg.cn/blog_migrate/39bede1adb6759788c01ea97b1812ca9.png)
标签-转发![](https://i-blog.csdnimg.cn/blog_migrate/6c3ef2ab6e89acb519b95d654e2af459.png)
EL表达式
作用、格式
<body>
<%
request.setAttribute("key","值");
%>
表达式脚本输出key的值:<%=request.getAttribute("key")%>
EL表达式 输出key的值:${key}
</body>
域数据搜素顺序
EL输出Bean的普通属性,数组属性,List集合属性,Map集合属性
Person实例已经设置各个属性值
EL运算
语法:${运算表达式}
关系运算![](https://i-blog.csdnimg.cn/blog_migrate/a29837845a59075bde3c6e4eea989912.png)
逻辑运算![](https://i-blog.csdnimg.cn/blog_migrate/4fd55306e12aa95a5c13f45d501b699a.png)
算术运算![](https://i-blog.csdnimg.cn/blog_migrate/b3b3e279cf834f763ca3e3cd935d217d.png)
empty运算
语法:${empty 引用值} ;empty可以判断一个数据是否为空,如果为空,输出true,反之输出false。
以下几种为空情况:
1.值为空 2.值为空串 3.值是Object类型数组,长度为零
4.list集合,元素个数为零 5.map集合,元素个数为零
三元运算
语法:${布尔?是,返回值 :否,返回值}
[]和 .号运算
.点运算,可以输出Bean对象中某个属性
[]括号运算,可以输出有序集合中某个元素的值
并且[]中括号运算,还可以输出map集合中key里含有特殊字符的key的值
<%
Map<String,Object> map = new HashMap();
map.put("A","AValue");
map.put("a.a.a","aaaValue");
map.put("b+b+b","bbbValue");
map.put("c-c-c","cccValue");
request.setAttribute("map",map);
%>
${map.A}
<%--特殊字符的key的值--%>
${map['a.a.a']}
${map['b+b+b']}
${map['c-c-c']}
El表达式的11个隐含对象
EL表达式自己定义的,可以直接试用
JSTL标签库
JSTL标签库 全称是指JSP Standard Tag Library JSP标签库。是一个不断完善的开放源代码的JSP标签库。
El表达式主要是为了替换JSP中的表达式脚本,而标签库则是为了替换代码脚本。这样使得真个JSP页面变得更加简洁。
!!!详细使用暂时不记
数据库
数据库连接池
druid
数据库驱动
mysql-connector-java
操作数据库
commons-dbutils
文件的上传和下载
上传文件
1.要有一个form标签,method=post请求(post没有长度限制,get有限制)
2.form标签的encType属性值必须为multipart/form-data值
encType=multipart/form-data表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
3.在form标签中使用 input type=file添加上传的文件
4.编写服务器代码接收,处理上传文件数据
前端用流的方式传送,后端也要用流的方式接收
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletInputStream inputStream = req.getInputStream();
byte[] buffer = new byte[1024000];
int read = inputStream.read(buffer);
System.out.println(new String(buffer,0,read));
}
可以用commons-fileupload.jar对收到的数据进行处理
commons-fileupload.jar和commons-io.jar包中,我们常用的类
ServletFileUpload类,用于解析上传的数据。 FileItem类,表示每一个表单项。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (ServletFileUpload.isMultipartContent(req)){
//创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
//创建用于解析上传数据的工具类ServletFileUpload
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
//解析上传数据,得到每一个表单项
List<FileItem> list = servletFileUpload.parseRequest(req);
for (FileItem fileItem : list) {
if (fileItem.isFormField()){
//普通表单项
System.out.println("表单项的name属性值:"+fileItem.getFieldName());
//参数UTF-8解决乱码问题
System.out.println("表单项的value属性值"+fileItem.getString("UTF-8"));
}else {
//上传的文件
System.out.println("表单项的name属性值:"+fileItem.getFieldName());
//上传文件名
System.out.println("上传文件名:"+fileItem.getName());
//写入硬盘
fileItem.write(new File("E:\\"+fileItem.getName()));
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
下载文件![](https://i-blog.csdnimg.cn/blog_migrate/da52a0aacfbde7b92c1c20178da491a9.png)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 文件位置:web/file/cc.jpg
//1.获取文件名
String downloadFileName = "cc.jpg";
//2.读取要下载的文件内容
ServletContext servletContext = getServletContext();
//获取要下载文件的类型
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
//4.在回传前,通过响应头告诉客户端返回的数据类型
resp.setContentType(mimeType);
//5.告诉客户端收到的数据是用于下载使用(通过响应头)
/**
* Content-Disposition响应头,表示收到的数据怎么处理
* attachment表示附件,表示下载使用
* filename表示指定下载的文件名
*/
//处理文件名中文乱码
//URL编码
String fname = URLEncoder.encode("文件名", "UTF-8");
//Base64编码
BASE64Encoder base64Encoder = new BASE64Encoder();
String fnameB64 = base64Encoder.encode("文件名".getBytes("UTF-8"));
/**
* base64解码
* BASE64Decoder base64Decoder = new BASE64Decoder();
* byte[] bytes = base64Decoder.decodeBuffer(fnameB64);
* String s = new String(bytes, "UTF-8");
*/
if (req.getHeader("User-Agent").equals("Firefox")){
//如果是火狐浏览器使用Base64编码
resp.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+fnameB64+"?=");
}else {
// 如果不是火狐,是IE或谷歌,使用URL编码操作
resp.setHeader("Content-Disposition","attachment;filename="+fname);
}
/**
* /斜杆被服务器解析表示地址为http://ip:prot/工程名/ 映射 到代码的web目录
*/
InputStream inputStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
//获取响应的输出流
OutputStream outputStream = resp.getOutputStream();
//3.把下载的文件回传给客户端
//读取输入流中的全部数据,复制给输出流,输出给客户端
IOUtils.copy(inputStream,outputStream);
}
MVC概念
MVC全称:Model模型、View视图、Controller控制器
MVC最早出现在JavaEE三层中的web层,它可以有效的指导web层的代码如何有效分离,单独工作。
View视图:只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作——JSP/HTML。
Controller控制层:只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——servlet。转到某一个页面。或者是重新定向到某一个页面。
Model模型:将与业务逻辑相关的数据封装为具体的JavaBean类,其中不参与任何与数据处理相关的代码——JavaBean/domain/entity/pojo。
MVC是一种思想,理念是将代码拆分为组件,单独开发,组合使用(目的还是为了节耦合)
Cookie
Cookie是由服务器通知客服端保存键值对的一种技术,客户端有了Cookie后,每次请求都会带着Cookie,每个Cookie大小不能超过4KB
Cookie创建
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("key", "value");
Cookie cookie1 = new Cookie("key1", "value1");
//通知客户端保存Cookie
resp.addCookie(cookie);
resp.addCookie(cookie1);
}
服务器获取Cookie
Cookie[] cookies = req.getCookies();
Cookie值修改
//假设浏览器保存Cookie有 key=value
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//方式一:
//先创建一个要修改的同名的Cookie对象
//在构造器,同时赋予新的Cookie值
Cookie cookie1 = new Cookie("key", "upValue");
//通知客服端保存修改
resp.addCookie(cookie1);
//方式二:
//先找到需要修改的Cookie对象
Cookie cookie2=null;
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("key"))
cookie2=cookie;
}
//调用setValue()方法赋予新的Cookie值
cookie2.setValue("upValue");
//通知客服端保存修改
resp.addCookie(cookie2);
}
Cookie生命值控制
Cookie生命值控制是指如何管理Cookie什么时候被销毁
正数表示指定的数秒后过期。
负数表示浏览器一关,Cookie就会被删除(默认值是-1)
0表示马上删除Cookie
Cookie cookie1 = new Cookie("key", "upValue");
cookie1.setMaxAge(-1);
//通知客服端保存修改
resp.addCookie(cookie1);
Cookie有效路径Path的设置
Cookie的path属性可以有效的过滤哪些Cookie可以发送给服务器。哪些不发。
path属性是通过请求的地址来进行有效的过滤
Session
Session技术,底层其实是基于Cookie技术来实现的。
创建Session和获取(id号,是否为新)![](https://i-blog.csdnimg.cn/blog_migrate/80da520d4660e24276b4596d47c0767f.png)
HttpSession session = req.getSession();
boolean aNew = session.isNew();
//获取id
String id = session.getId();
Session域中数据存取
getAttribute()和setAttribute()
Session生命周期控制![](https://i-blog.csdnimg.cn/blog_migrate/62c94cda754e0ab6795d9c2ebf0e0e7e.png)
浏览器和Session之间关联的技术内幕![](https://i-blog.csdnimg.cn/blog_migrate/8042f57589fe4de0665aac8c6d031407.png)
重复提交![](https://i-blog.csdnimg.cn/blog_migrate/ff6322f03f1e8edced2cc4d27e4644d6.png)
表单重复提交问题
当用户提交完请求,浏览器会记录最后一次请求的全部信息。当用户按下F5键刷新页面,就会发起浏览器记录的最后一次请求。所以可以用重定向返回新的页面。
验证码解决网络延迟等导致表单重复提交
谷歌kaptcha图片验证码的使用
需要导入谷歌验证码jar包 kaptcha
Filter过滤器
Filter过滤器是JavaEE的规范,也是接口;作用是拦截请求,过滤响应。
拦截请求常见的应用场景:1.权限检查 2.日记操作 3.事务管理
Filter使用
package com.atguigu.filter;
import javax.servlet.*;
import java.io.IOException;
public class ManagerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
filterConfig.getFilterName();
filterConfig.getInitParameter("key");
ServletContext servletContext = filterConfig.getServletContext();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//前置代码。。。。。
//让程序继续往下执行
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
Filter生命周期
Filter的生命周期包含几个方法
1.构造器方法
2.init初始化方法
3.doFilter过滤方法
4.destroy销毁方法
第1,2步,在web工程启动的时候执行(Filter已经创建)
第3步,每次拦截到请求就会执行
第4步,停止web工程的时候,就会执行(停止web工程,也会销毁Filter过滤器)
FilterConfig类
是Filter过滤器配置文件类。Tomcat每次创建Filter的时候,也会同时创建一个FilterConfig类。这里包含了Filter配置文件的配置信息
作用是获取Filter过滤器的配置内容
1.获取Filter的名称filter-name的内容
2.获取web.xml在Filter中配置的init-param初始化参数
3.获取ServletContext对象
多个过滤器执行流程
Filter的拦截路径
精确匹配![](https://i-blog.csdnimg.cn/blog_migrate/cf2399c8122a19bc201fdd7ffc6dc434.png)
目录匹配![](https://i-blog.csdnimg.cn/blog_migrate/9da38cee798e53d794bd496418664914.png)
后缀名匹配![](https://i-blog.csdnimg.cn/blog_migrate/ff52e721c2d24345718d6acb7932a1c4.png)
ThreadLocal
ThreadLocal的作用,可以解决多线程的数据安全问题
ThreadLocal它可以给当前线程关联数据(可以是普通变量,对象,数组,集合)
特点:
1.为当前线程关联一个数据(像Map一样存取数据,key为当前线程)
2.每一个ThreadLocal对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个ThreadLocal对象实例
3.每一个ThreadLocal对象实例定义的时候,一般都是static类型
4.ThreadLocal中保存数据,在线程销毁后,会由JVM虚拟机自动释放
ThreadLocal+Filter处理事务
JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,而且很多语言都提供了对json的支持。这样就是的JSON成为理想的数据交换格式。
数据交换指的是客户端和服务器之间业务数据的传递。
轻量级是相较于xml。
JS中的JSON使用
json的定义
json是由键值对组成,并由花括号{}包围。每个键由引号引起来,键和值之间使用冒号进行分隔,多组键值对之间进行逗号进行分隔。
json的两个常用方法
json存在两种形式:
一种是:对象的形式存在,我们叫它json对象。
一种是:字符串的形式存在,我们叫它json字符串。
一般要操作json中的数据的时候,需要json对象的格式。
一般我们要在客户端和服务器之间进行数据交换的时候,使用json字符串。
JSON.stringify() 把json对象转换成为json字符串
JSON.parse()把json字符串转换成为json对象
Java中的json
需要导入操作json的jar包,这里用谷歌gosn学习
javaBean和json的互转
Xiaomi xiaomi = new Xiaomi();
//创建gson对象实例
Gson gson = new Gson();
//toJson方法可以把Java对象转换成为json字符串
String xiaomiJsonString = gson.toJson(xiaomi);
//fromJson把json字符串转换回Java对象
/**
* 第一个参数是json字符串
* 第二个参数是转换回去的Java对象类型
*/
gson.fromJson(xiaomiJsonString,Xiaomi.class);
List和json的互转
Gson gson = new Gson();
ArrayList<Xiaomi> strings = new ArrayList<>();
strings.add(new Xiaomi("1"));
strings.add(new Xiaomi("2"));
//转json字符串
String s = gson.toJson(strings);
System.out.println(s);
//转成Java对象
ArrayList<Xiaomi> arrayList = gson.fromJson(s,
new TypeToken<ArrayList<Xiaomi>>(){}.getType());
System.out.println(arrayList);
Xiaomi xiaomi = arrayList.get(0);
System.out.println(xiaomi);
map和json的互转
Gson gson = new Gson();
HashMap<String, Integer> shMap = new HashMap<>();
shMap.put("1",1);
shMap.put("2",2);
String s = gson.toJson(shMap);
shMap = gson.fromJson(s, new TypeToken<HashMap<String, Integer>>() {
}.getType());
System.out.println(s);
System.out.println(shMap.get("1"));
AJAX
AJAX即“Aysnchronous Javascript And Xml”(异步Javascript和Xml),是指一种创建交互式网页应用的网页开发技术。https://www.w3school.com.cn/js/js_ajax_intro.asp
ajax是一种浏览器通过js异步发起请求。局部更新页面的技术。
原生js的AJAX请求![](https://i-blog.csdnimg.cn/blog_migrate/c0b1e91a1a00f12ee0ba4a89d8369ab0.png)
JQUERY的AJAX请求
$.ajax
$get和$.post![](https://i-blog.csdnimg.cn/blog_migrate/1902a8d4a7877f8037e4cf16d9fa9d09.png)
$.getJSON
通过HTTP GET 请求载入JSON数据
表单序列化serialize()![](https://i-blog.csdnimg.cn/blog_migrate/4bec485909a2223777e545d2b9ff4b47.png)
发送
服务器接收