• 知识结构图

  • 文件下载

  默认情况下,如果浏览器可以处理Content-Type响应头中指定数据类型,浏览器就会直接处理,比如显示出HTML页面(text/html),或者显示出照片(image/png)等;如果浏览器不知道怎么处理,就会以文件的形式下载到本地电脑上

  要想强制让浏览器以文件的方式下载,可以设置Content-Disposition=attachment;filename=xxx

@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String filename = "人丑就要多读书.jpg";
//如果文件名由非西文字符,最好使用URL编码一遍
//文件下载时,各个浏览器对URL编码过的文件名处理不一样,也没法统一处理
filename = URLEncoder.encode(filename, "UTF-8"); //响应类型最后也设置
response.setContentType("image/jpeg");
response.setHeader("Content-Disposition", "attachment;filename=" + filename); InputStream input = getServletContext().getResourceAsStream("/人丑就要多读书.jpg");
OutputStream output = response.getOutputStream(); //把文件数据作为响应体内容输出到浏览器
byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = input.read(buff)) > -1) {
output.write(buff, 0, len);
} //关闭自己创建的input,output不用手动关闭,服务器会自动关闭
input.close();
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
  • 文件上传

  客户端表单中必须指定method=post,因为上传的文件可能很大,并且指定enctype=multipart/form-data使用上传文件专门的编码方式

  另外客户端还需要使用<input type="file"> 选择要上传的文件

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<span style="color: red">${ requestScope.message }</span>
<form action="/webDemo/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" /> <br/><br/>
<textarea rows="5" cols="50" name="comment" placeholder="文件说明"></textarea> <br/><br/>
<input type="submit" value="上传" />
</form>
</body>
</html>

  服务器端Servlet需要标注@MultipartConfig,否则会忽略文件内容

  普通请求参数处理方式不变,先request.setCharacterEncoding("UTF-8")设置post请求参数编码,然后request.getParameter()获取请求参数

  上传的文件内容会先被保存到服务器端的临时文件中,可以通过request.getPart(name)获得封装了上传文件信息的Part对象,从Part对象中可以获得临时文件读取流、原始文件名称、文件大小等有用信息

  直接把临时文件copy到想要上传的目录下即可,注意原始文件名可能会重复,应该为文件生成新的唯一文件名,然后在数据库中同时保存原始文件名和新文件名,这样原始文件名信息就不会丢失

  注意如果把文件上传到服务器部署目录的项目目录下面,项目修改重新部署时就会把以前上传的文件清理掉,解决办法是使用外面的目录作为上传目录,或者把外面的目录配置成服务器的虚拟目录

@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { request.setCharacterEncoding("UTF-8");
String comment = request.getParameter("comment");//文件说明 //这个时候文件数据已经上传并保存到了服务器临时文件中
//Part封装了上传文件的信息
Part part = request.getPart("uploadFile");
String origFilename = part.getSubmittedFileName();//原始文件名
String inputName = part.getName();//文件表单控件name值
InputStream input = part.getInputStream();//上传到服务器的临时文件读取流 //接下来只需要把临时文件copy到想要保存的目录下
String targetDir = getServletContext().getRealPath("/upload"); //为避免文件名重复,不能使用原始文件名,可以使用UUID生成新的文件名
String realFileame = UUID.randomUUID().toString();
OutputStream output = new FileOutputStream(new File(targetDir, realFileame)); byte[] buff = new byte[1024 * 8];
int len = 0;
while ((len = input.read(buff)) > -1) {
output.write(buff, 0, len);
}
input.close();
output.close(); // JDBCUtils.executeUpdate("insert into T_Files( origFilename, realFileame, comment)", origFilename, realFileame, comment);
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
  • Filter

  Filter 过滤器,使用“拦截器”更容易理解,Filter可以在请求到达Servlet之前拦截请求,以便做一些预处理和后处理

  Filter和Servlet在使用方式上非常相似,甚至可以相互代替,但我们通常不这么做。他们在功能上各有分工:Servlet专注于处理业务逻辑,Filter专注于其他非业务逻辑,比如设置post请求参数编码、检查权限等

  使用Filter的步骤:

  1 实现自己的Filter类,并实现doFilter方法

  2 使用@WebFilter标注Filter,并指定Filter的虚拟路径,因为Filter专门执行预处理,所以Filter和Servlet的虚拟路径需要重叠

  注意 在Filter中 /* 才表示匹配全部请求,这点和Servlet( / )有差别

@WebFilter("/*")
public class CharsetFilter implements Filter {
@Override
public void init(FilterConfig fConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException { //这样Servlet就不用单独设置post请求参数编码了
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

  Filter生命周期:和Servlet不同,Filter在项目启动时就创建好,而且以单例的形式存在,项目停止时销毁

  Filter工作方式:服务器收到一个请求,先查找有没有匹配的Filter,如果有,则先把请求交给Filter处理,即调用FIlter的doFilter()方法。

如果有多个Filter匹配,匹配的Filter就会和Servlet一起组成调用链。当前Filter只有在调用了chain.doFilter()方法后,请求才会传递到调用链的下一个节点

  如果Filter在web.xml中配置,多个Filter的调用顺序就是配置顺序,如果使用@WebFilter配置,调用顺序就是Filter类名称自然排序的顺序

  • Listener

  在Web项目整个生命周期过程中,会发生很多事件,比如ServletContext的创建、销毁,HttpSession的创建、销毁等,在发生这些事件时,如果我们希望做一些事情,就可以通过Listener监听器给这些事件注册事件处理程序

  事件种类有很多,每种事件都有对应Listener注册处理程序。但整体上Listener使用不多,我们只学习ServletContextListener和HttpSessionActivationListener

  ServletContextListener

  该接口提供了contextInitialized()和contextDestroyed()两个方法分别注册项目启动、项目停止时的事件处理程序

  当项目启动即ServletContext对象创建成功后,服务器就会回调contextInitialized()方法

  当项目停止即ServletContext销毁前,服务器就会回调contextDestroyed()方法

@WebListener
public class MyServletContextListener implements ServletContextListener { @Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象创建完成,项目启动成功");
} @Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("项目即将停止");
}
}

  session钝化和活化

  很多web服务器都支持session钝化和活化

  序列化是指把内存中的对象按照一定的规则转化为"一串"二进制数据,方便保存到硬盘或者通过网络发送到另外一台电脑。

  一个类只有实现了Serializable接口才可以被序列化

  为了判断一个类是否被修改过,通常使用long serialVersionUID字段作为类的"版本"

  钝化是指把内存中的session对象序列化到硬盘上(session的实现类StandardSession实现了Serializable接口)

  活化是指把保存到硬盘上的session数据反序列化为内存中的session对象

  用途:

  可以把达到一定空闲时间的session钝化到硬盘上,减少内存占用

  当web服务器关闭或者重启时,可以把内存中的session全部钝化到硬盘上

  注意:钝化某个session后,只有当用户再次访问时,才会活化该session

  session默认是不会被钝化的,需要在项目中配置开启:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="10">
<Store className="org.apache.catalina.session.FileStore" directory="sessionPassivationDir"/>
</Manager>
</Context>

  maxIdleSwap:session空闲时间超过此时间就可以被钝化,单位秒,默认-1表示永不钝化

  directory:钝化文件存储在哪个目录下(从Tomcat的work目录往下找)

  注意:Tomcat大概每隔60秒检查一次哪些session需要被钝化,所以session达到钝化条件后可能并不会立刻出现钝化效果。此外,钝化文件会在session过期后被删除

  HttpSessionActivationListener

  放入session中的属性只有实现了Serializable接口才会随session一起钝化、活化

  如果需要监听属性随session一起钝化、活化的事件,属性类需要实现HttpSessionActivationListener接口

public class User implements Serializable, HttpSessionActivationListener {

    private Long id;
private String email;
private String name;
private String password;
private Date birthday; @Override
//钝化前服务器会回调此方法
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("本user对象将要随着session一起钝化");
} @Override
//活化后服务器会回调此方法
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("本user对象已经随着session一起活化了");
}

JavaWeb中的高级知识总结的更多相关文章

  1. 【Vue高级知识】细谈Vue 中三要素(响应式+模板+render函数)

    [Vue高级知识]细谈Vue 中三要素(响应式+模板+render函数):https://blog.csdn.net/m0_37981569/article/details/93304809

  2. JavaWeb学习篇之----Tomcat中配置数字证书以及网络传输数据中的密码学知识

    今天是学习JavaWeb的第二天,我们来了解什么呢?就了解一下Tomcat中配置数字证书的相关内容,但是在说这部分内容的时候,我们貌似得先说一下数字证书的相关概念,那说到数字证书的时候我们还得了解一些 ...

  3. [转载]JavaEE学习篇之——网络传输数据中的密码学知识以及Tomcat中配置数字证书EE

    原文链接:http://blog.csdn.net/jiangwei0910410003/article/details/21716557 今天是学习JavaWeb的第二天,我们来了解什么呢?就了解一 ...

  4. RSA原理、ssl认证、Tomcat中配置数字证书以及网络传输数据中的密码学知识

      情形一:接口的加.解密与加.验签 rsa不是只有加密解密,除此外还有加签和验签.之前一直误以为加密就是加签,解密就是验签.这是错误的! 正确的理解是: 数据传输的机密性:公钥加密私钥解密是密送,保 ...

  5. DataBase MongoDB高级知识

    MongoDB高级知识 一.mongodb适合场景: 1.读写分离:MongoDB服务采用三节点副本集的高可用架构,三个数据节点位于不同的物理服务器上,自动同步数据.Primary和Secondary ...

  6. 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  7. MySQL高级知识(十六)——小表驱动大表

    前言:本来小表驱动大表的知识应该在前面就讲解的,但是由于之前并没有学习数据批量插入,因此将其放在这里.在查询的优化中永远小表驱动大表. 1.为什么要小表驱动大表呢 类似循环嵌套 for(int i=5 ...

  8. MySQL高级知识(十五)——主从复制

    前言:本章主要讲解MySQL主从复制的操作步骤.由于环境限制,主机使用Windows环境,从机使用用Linux环境.另外MySQL的版本最好一致,笔者采用的MySQL5.7.22版本,具体安装过程请查 ...

  9. MySQL高级知识(十四)——行锁

    前言:前面学习了表锁的相关知识,本篇主要介绍行锁的相关知识.行锁偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率低,但并发度高. 0.准备 #1.创建相关测试表tb_ ...

随机推荐

  1. 【LGR-(-8)】洛谷入门赛 #5 题解

    比赛链接 9道题. 注:题目名称中链接为题目链接,题号中链接为比赛内链接 题目编号 洛谷题号 题目名称 题目难度 A P5713 [深基3.例5]洛谷团队系统 \(\color{red}{入门}\) ...

  2. 使用kali中的Metasploit通过windows7的永恒之蓝漏洞攻击并控制win7系统(9.27 第十三天)

    1.开启postgresql数据库 2.msfconsole 进入MSF中 3.search 17-010 搜索cve17-010相关的exp auxiliary/scanner/smb/smb_ms ...

  3. 屏幕切换 onStart() onStop() onRestart() onDestroy()

    android:configChanges="orientation|keyboardHidden|screenSize"          //xml文件<activity ...

  4. 17. react redux的中间件

    1. redux 数据流程图 View 会派发一个 Action Action 通过 Dispatch 方法派发给 Store Store 接收到 Action 连同之前的 State 发给  Red ...

  5. OFD系列软件说明(免费试用、QQ交流群:877371250)

    前言 OFD是一个版式文档格式.所谓版式文档格式是版面呈现效果固定的电子文档格式. 我们今天接触到最多的版式文档就是国际通用的PDF. 国内的就是由工业和信息化部软件司牵头中国电子技术标准化研究院成立 ...

  6. Django xadmin图片上传与缩略图处理

    基本摘要 用python django开发时,个人选中Xadmin后台管理系统框架,因为它*内置功能丰富, 不仅提供了基本的CRUD功能,还内置了丰富的插件功能.包括数据导出.书签.图表.数据添加向导 ...

  7. Element.scrollIntoView() 和 document.elementFromPoint ()

    Element​.scroll​Into​View() 让当前的元素滚动到浏览器窗口的可视区域内 element.scrollIntoView(); // 等同于element.scrollIntoV ...

  8. django-替代为自定义的User model

    https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model Subs ...

  9. XXE--XML外部实体注入漏洞

    XXE漏洞原理 XXE漏洞全称XML External Entity Injection 即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部 ...

  10. 一天一个设计模式——工厂方法(FactoryMethod)模式

    一.模式说明 在前一个模板方法(Template Method)模式中,父类定义了处理流程,而流程中用到的方法交给子类去实现.类似的,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类 ...