JAVAEE基础知识
2018年3月,开源组织Eclipse基金会宣布,JavaEE(Enterprise Edition)被更名为JakartaEE,也就是9版本后改名Jakarta EE,也就是JakartaEE9。
Java EE(Java Platform,Enterprise Edition)是sun公司(2009年4月20日甲骨文将其收购)推出的企业级应用程序版本。这个版本以前称为 J2EE。能够帮助我们开发和部署可移植、健壮、可伸缩且安全的服务器端 Java应用程序。Java EE 是在 Java SE 的基础上构建的,它提供Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和 Web 3.0应用程序。
Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器均支持Java applet。
1、IDEA下载与破解
1、本破解教程除了适用于IDEA,同样适用于JetBrains全家桶,比如PyCharm、DataGrip、Goland、WebStorm等等
本次工具支持2021.3以后版本( 2021.3.1,2021.3.2,2021.3.3,2022.1,2022.1.1,2022.1.2,2022.1.3,2022.1.4,2022.2,2023.1)的IDEA使用.
2、首先下载IDEA相关版本
https://www.jetbrains.com/idea/
3、下载激活脚本
下载地址:https://wwu.lanzoub.com/i2Mls0ha05le
脚本文件夹介绍:
- cripts: 这里存放了激活用到的脚本(windows、mac、linux都有)
- vmoptions:IDEA关联的配置文件
4、 运行激活脚本(如果之前已经激活过,建议先执行卸载脚本,再执行安装脚本)
打开下载文件中的scripts文件,我们可以看到如下几个文件脚本
Windows系统: 双击运行 install-current-user.vbs 脚本,为当前用户安装破解补丁。install-all-users.vbs为所有系统用户安装,不过不太推荐
Mac、Linux系统: 执行install.sh 脚本(Mac 注意给整个文件夹777权限)与之对应的uninstall xxx脚本就是卸载补丁的脚本。
5、双击执行 install-xxx 补丁,我们会看到如下的弹窗,意思是:补丁运行可能需要几秒钟,点击确定,然后等待Done的提示框就可以。
6、输入激活码
【激活码】XIZQAN09CR-eyJsaWNlbnNlSWQiOiJYSVpRQU4wOUNSIiwibGljZW5zZWVOYW1lIjoia2lkZHkgaW5zZWFtcyIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IlBEQiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFNJIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUEMiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDV01QIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUkIiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiSUkiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJQR08iLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBTVyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6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
【注意】其他软件激活码访问:https://www.955code.com/8857.html。
7、之后就看到成功激活到2088年了!部分版本显示2025年,就是永久激活了!太在乎这个时间的。
【注意】同样适用于其他JetBrains产品,比如PyCharm、DataGrip、Goland、WebStorm等等。
如果您是旧版本IDEA(2021.2.2及其之前版本),请参考:https://www.955code.com/2906.html
- idea常用快捷键
2、HTTP协议基础知识
1、B/S架构:Brower--->server,浏览器发送http请求到服务器,服务器获得数据经过逻辑处理后,响应给浏览器。这种架构只需要修改服务器的代码,就可以完成软件的更新。
C/S架构:client---->server,客户端发送数据给服务器,这种架构需要重新安装更新后的软件,维护代码非常不便。
2、HTTP协议是超文本请求和响应传输协议。
3、简单快速:客户向服务器请求服务时
4、HTTP协议特点:
一、支持客户/服务器模块
二、简单快速:只需传送请求方法和路径。请求方式常有的有get和post,由于HTTP协议简单,因而通信速度很快。
三、灵活:HTTP允许传输任意类型的数据对象。传输的类型由Content-Type加以标记。
四、无连接:每次连接只处理一个连接。服务器处理完客户的请求,并收到客户的应答后,断开连接,这种方式可以节省传输时间。HTTP1.1支持可持续连接。
五、无状态:HTTP协议是无状态协议。无状态是指对于事务处理没有记忆能力,缺少状态意味着后续处理需要先前信息,则它必须重传,这样导致传输的数据量增大。
5、浏览器发送到服务器是属于请求协议,服务器发送到浏览器是属于响应协议。
- 浏览器请求地址书写格式分析图:
- HTTP之URL
HTTP是一个基于请求和响应模式的、应用层的协议,常基于TCP的连接方式,绝大多数web开发都是构建在HTTP之上的web应用。
HTTP协议包括:请求行、请求头、请求体(get请求方式没有请求体)、响应行、响应头、响应体(html代码标签/json字符串)
基本格式:
post请求方式:http://IP(主机名/域名):端口/访问的资源路径
get请求方式:http://IP(主机名/域名):端口/访问的资源路径?key=value&key=value&……
- HTTP状态码分类:
- 常见请求头参数
- 常见响应头参数
3、TOMCAT服务器
一、Tomcat基本介绍
1、Tomcat服务器实际上是一个用JAVA编写的软件,它提供一个容器,用于运行web项目,可以实现多个客服端通过网络传输请求访问web项目,实现数据的共享,一个容器可以运行多个项目。
2、硬件服务器实际上是一台电脑,里面一般安装linux系统,可以在服务器上部署软件服务器和web软件,实现客户端通过网络访问远程服务器实现数据共享。
3、Tomcat目录分析:
bin:有开启和停止tomcat的指令文件。
lib:tomcat运行依赖的jar包(jsp.jar,servlet-api.jar等)。
conf:存放tomcat配置文件,其中server.xml可以修改端口号,修改默认加载项目。
log:存放日志的文件夹,可以看日志信息去查bug,相当于javase开发的控制台输出信息。
webapps:存放运行web项目的文件夹。
temps:临时文件存放文件夹。
[注意]:如果在DOS命令窗口启动输出信息出现乱码问题,要修改conf文件夹中的logging.properties文件编码格式,默认是UTF-8,应该改为GBK。
二、Idea配置Tomcat
- 下载Tomcat
1、由于tomcat是用java开发的,所以下载tomcat时要注意jdk版本与tomcat版本配套问题。
2、使用tomcat前,要在window环境配置中,在系统环境path配置好JAVA_HOME环境。
3、在官网下载:http://www.tomcat.apache.org/。下载后解压缩包,并把bin目录配置到系统环境的path中。
- Tomcat与JDK版本兼容图
- 配置tomcat
4、Servlet基础
Servlet是运行在服务器上的应用,tomcat容器三大组件(servlet、filter、listener)之一,通过servlet可以实现页面的请求访问。
一、IDEA搭建web项目
常用的两种方式:
1、在普通java项目中,添加web框架支持。
2、创建javaee,maven项目,导入相关依赖。
- 普通java项目添加web框架支持
- maven工程构建JAVAEE项目
二、搭建servlet的三种方式
- 继承HttpServlet类。
public class Servlet_Demo1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service 方法!");
}
}
2.继承GenericServlet类。
public class Servlet_Demo1 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
}
3.实现Servlet接口
public class Servlet_Demo1 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
三、Servlet设置跳转页面的两种方式
- 传统方式(servlet3.0以前)
在web.xml文件配置servlet编辑器
<servlet>
<servlet-name>servlet1</servlet-name> <!--自定义servlet名字-->
<!--绑定servlet全类名-->
<servlet-class>com.zwf.servletDemo.Servlet_Demo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<!--设置servlet请求跳转路径-->
<url-pattern>/index</url-pattern>
</servlet-mapping>
- 注解方式
//注解设置跳转路径 name:自定义名 value:跳转路径
@WebServlet(name = "servletDemo",value = "/s1")
public class Servlet_Demo1 implements Servlet {
}
四、servlet运行机制
1、浏览器访问响应http页面请求,然后首先执行servlet中的service()方法,然后判断是get还是post请求,然后相应调用doGet()或者doPost()方法。
2、如果你直接重写service()方法,它直接先执行service(ServletRequest req,ServletResponse resp)方法,你可以直接在service()中编写逻辑代码,或者不编写service()方法,直接编写doGet()或者doPost()方法,servlet会根据请求方式不同跳转到相应方法。
5、servlet生命周期
浏览器访问servlet请求路径,servlet会先调用构造器,然后调用初始化函数init(),接着调用service()方法期间封装了HttpServletRequest和HttpServletResponse对象,最后关闭tomcat容器,servlet调用destory()销毁servlet对象。
[注意]只有service()方法可以被调用多次,其他方法只会加载调用一次。
6、HttpServletRequest对象
HttpServletRequest是http请求对象,可以获取请求头中相关信息,它的父类是servletRequest,并且是父类唯一的子接口,目的是长远考虑,如果出现新的协议可以直接继承父接口进行编写。
常用方法有:
getRequestURL():获取项目全路径
getRequestURI():获取项目页面路径 /项目名路径/子路径
getQueryString():获取参数的完整格式 key=value&key=value
getMethod():获取请求方式(get post delete put等请求)
getContextpath():获取项目根路径 /项目名
getProtocol():获取HTTP版本
getParamter(String name); 根据name属性值 获取value。
getParamterValues(String name); 根据name属性值 获取所有value。
- 测试代码
//获取项目全路径(http://服务器:端口号/项目名路径/子路径)
StringBuffer URL = req.getRequestURL();
System.out.println("项目全路径:"+URL);
//获取资源目录路径(/项目名/子路径)
String uri = req.getRequestURI();
System.out.println("资源路径"+uri);
//获取请求方式
String method = req.getMethod();
System.out.println("请求方式:"+method);
//获取项目路径资源路径(webapp站点路径 /项目名)
String path = req.getContextPath();
System.out.println("项目资源路径:"+path);
//获取请求参数(username=zs&pwd=123)
String queryString = req.getQueryString();
System.out.println("请求的参数:"+queryString);
//获取HTTP版本号 HTTP1.1
String proto = req.getProtocol();
System.out.println("超文本传输协议的版本号:"+proto);
System.out.println("**************************************");
//根据name值获取value值
String username = req.getParameter("username");
System.out.println(username);
//根据name值获取所有的value值 一般用于获取多选框的value值 返回一个数组类型
String[] hobbies = req.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies));
- request解决乱码问题
原因:前端表单传来的中文要以UTF-8编码方式通过TCP协议socket方式转为字节数组,传送到servlet时还是UTF-8,但是使用requestParamter(String name);默认是把UTF-8编码转换成ISO-8859-1字符编码,而此编码不支持中文,就出现乱码。
解决方案:使用 String value=new String(request.getParamter().getBytes("ISO-8859-1"),"UTF-8")(新版本tomcat处理乱码问题无效,tomcat8.0以下版本);但是这种方式如果对于多个参数传递,就需要每个参数都要定义,非常繁琐。所以我们就出现了一个新方法。
request.setCharacterEncoding("UTF-8");但是这个方法实际上只对post请求方式解决中文乱码问题有效,我们只需要更换tomcat版本在8.0及其以上就解决了get和post乱码问题。
- 测试代码
//以下方式对新版本tomcat处理中文乱码问题无效 tomcat8.0以上
String username = new String(req.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");
//解决中文乱码问题 tomcat8.0以上 get post请求全部解决 低版本只解决了post乱码问题
req.setCharacterEncoding("UTF-8");
- 请求转发
1、请求转发是浏览器向服务器发送一次请求,服务器内部处理处理数据,地址栏不会变,可设置和在不同页面获取request域中的值,不同页面之间可以共享数据。
2、常用方式:
request.setAttribute(String name,Object obj);
request.getAttribute(String name);
request.getRequestDispathcher(String path).forward(request,response);
- 测试代码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String[] hobbies = req.getParameterValues("hobby");
req.setAttribute("username",username);
req.getRequestDispatcher("infor.jsp").forward(req,resp);
7、ServletResponse对象
- response解决乱码问题
原因:idea默认是UTF-8字符编码,文本网络传输时转化为字节数组,字节数组默认编码格式是ISO-8859-1,要通过response.setCharacterEncoding("UTF-8")把字节数组字符编码转为UTF-8,然后再加响应头response.setContentType("text/pain;charset=UTF-8"),让浏览器以UTF-8字符编码显示文本,如果是字符流可以不设置response.setCharacterEncoding("UTF-8")。
- 测试代码
resp.setCharacterEncoding("UTF-8");
//GBK UTF-8支持中文 iso-8859-1不支持中文格式 三种不同方式的请求头编写方式
resp.setHeader("Content-Type","text/pain;charset=utf-8");
resp.setContentType("text/pain;charset=utf-8");
resp.addHeader("Content-Type","text/pain;charset=utf-8");
- 重定向
客户端向浏览器发送多次请求,多次请求的request不同,导致request域不能存放数据,也就是“服务器指导,客户端操作”,不同页面之间不能共享数据。
常用方法:response.sendRedirect(String path);
- 测试代码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String[] hobbies = req.getParameterValues("hobby");
req.setAttribute("username",username);
req.setAttribute("hobby",hobbies);
resp.sendRedirect("infor.jsp");
- 请求转发和重定向的区别
1、请求转发是处理同一个请求,重定向是处理不同的请求。
2、请求转发地址栏不会改变,重定向会改变跳转地址。
3、请求转发可以通过request域携带参数,重定向不能携带参数。
4、请求转发服务器内部处理,效率高,重定向能跳转到服务器内外部。
5、请求转发表单可以重复提交,重定向表单不能重复提交。
6、请求转发不支持绝对路径,重定向支持绝对路径(推荐绝对路径)。
- 关于请求转发和重定向路径问题
1、请求转发是在服务器根目录下(/项目名/)去找文件,所以设置相对路径应该是getRequestRedirect("/资源路径"),如果是跳转到jsp文件,设置相对路径应该是getRequestDispatcher("/*.jsp")或者getRequestDispatcher("*.jsp");不能使用绝对路径。
2、重定向是在服务器根目录中(http:127.0.0.1:8080/)去找文件,所以设置相对路径应该设置为response.sendRedirect("/项目名/资源路径");设置绝对路径应该是response.sendRedirect("http:127.0.0.1:8080/项目名/资源路径");
3、web项目文件夹下的页面文件,重定向和请求转发都可以访问,而WEB-INF文件夹下的页面文件,只能通过请求转发访问。
5、通过el表达式中的${pageContext.request.contextpath}获取项目根相对路径。
8、Cookie对象
1、cookies是服务器创建给客户端保存的数据对象,可以让客户端下次访问服务端的时候直接用cookie匹配服务端的session进行查找,cookie保存的数据以键值对存在,Cookie不适合大量数据的存储(每个Cookie存储的数据不超过4KB)。
2、特点:
一、cookie只能保存在各自浏览器中,不能跨浏览器。
二、cookie只能保存很小的数,不超过4kb。
三、浏览器保存cookie数量有限,一般有选择性的存储。
四、cookie默认是保存在浏览器内存中,要设置保存时间(单位是秒)才能持久化保存。
五、cookie原则上是不支持保存中文,如果要保存中文的需要进行编码,获取中文时需要解码。
六、同名cookie的值会被覆盖。
- 测试代码
//创建cookie
Cookie cookie=new Cookie("username","zs");
//响应给客户端
resp.addCookie(cookie);
//设置保存时间1分钟 默认不持久化保存,只保存在浏览器内存中
cookie.setAge(60);
//获取浏览器的cookie值 只会获取所有的cookie值
Cookie[] cookies = req.getCookies();
//处理中文字符 不处理中文字符编码问题 会报服务器错误
Cookie cookies=new Cookie( URLEncoder.encode("姓名"),URLEncoder.encode("小曾"))
for (Cookie c:cookies){
System.out.println(c.getName()+"------------>"+c.getValue());
//获取中文字符
URLDecode.decode(c.getName());
}
//可以设置访问cookie的网页路径 / 表示此服务器所有的项目都可以获取cookie值 还可以指定具体获取cookie的请求。
cookie.setPath("/");
9、HttpSession对象
1、session是服务器创建保存的,服务器创建一次session生成sessionId,服务器把sessionId响应到浏览器中以JSEEIONID保存在服务器中,下次请求的时候,浏览器以JSESSION去匹配服务器的sessionId值获取session存储的数据。
2、如果关闭浏览器,再次打开浏览器请求时,前一次的cookie对象被销毁,请求中没有JSEEEIONID,服务器会重新创建sessionId响应新的JSESSIONID保存在浏览器中。
3、如果关闭服务器,在没有钝化的情况下session立即销毁或者执行invidate()销毁session,重新打开服务器会创建新的session,浏览器重新访问又会生成新的cookie。
4、session对象默认销毁时间是30分钟,如果你不进行操作,到了销毁时间就会销毁session对象,如果操作了就会重新计时。
5、session域可以存放数据在用户多次请求中进行数据共享,可以在同一种浏览器发送请求实现数据共享,重定向也可以实现数据共享。
- 测试代码
//设置字符编码
req.setCharacterEncoding("UTF-8");
HttpSession session = req.getSession();
//设置
session.setAttribute("name","session对象");
String id = session.getId();
System.out.println("sessionId="+id);
//设置过期时间 单位是秒
session.setMaxInactiveInterval(30);
//获取最大过期时间 默认是30*60s
int max = session.getMaxInactiveInterval();
System.out.println("最大过期时间:"+max+"s");
//判断sessionId是否是新的
boolean aNew = session.isNew();
System.out.println(aNew?"sessionId是新的":"sessionId是旧的");
//对session进行立即销毁
session.invalidate();
//请求转发到相应路径
req.getRequestDispatcher("/session/get").forward(req,resp);
- 在web.xml文件中配置过期时间
<!--基本单位是分钟 这里设置为60分钟-->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
10、ServletContext对象
1、ServletContext域是servlet对象中范围最大的域,可以实现同一个web容器数据共享,每一个web服务器只能创建一个ServletContext对象,也可以跨浏览器进行数据共享,重定向也可以实现数据共享。
2、获取ServletContext对象的四种方式:
ServletContext context = req.getSession().getServletContext();
ServletContext context1 = req.getServletContext();(常用)
ServletContext context2 = super.getServletConfig().getServletContext();
ServletContext context3 = super.getServletContext();
- 设置服务器容器初始化数据(web.xml)
<!--服务器启动后会加载这个数据,可以用来加载springIOC容器-->
<context-param>
<param-name>name</param-name>
<param-value>张珊</param-value>
</context-param>
- 测试代码
//获取项目真实路径 //D:\bigCode\JavaEEStudy\out\artifacts\Servlet_Demo2_war_exploded\
String realPath = context.getRealPath("/");
System.out.println(realPath);
//获取服务器加载时的初始化对象
String name = context.getInitParameter("name");
System.out.println(name);
//在application域中存放数据
context.setAttribute("age",18);
//获取服务器信息 Apache Tomcat/9.0.60
String info = context.getServerInfo();
System.out.println(info);
resp.sendRedirect("/test/session/get");
11、文件的上传和下载
在上网的时候我们常常遇到文件上传的情况,例如上传头像、上传资料等;当然除了上传,遇见下载的情况也很多,接下来看看我们 servlet 中怎么实现文件的上传和下载。
一、文件上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
文件名:<input type="text" name="fileName" placeholder="请输入上传的文件名">
<label for="upload">文件上传:
<input type="file" name="uploadFile" id="upload"/><br>
</label>
<input type="submit" value="上传文件">
</form>
</body>
</html>
- Servlet后端代码
req.setCharacterEncoding("UTF-8");
String fileName = req.getParameter("fileName");
System.out.println("获取表单文件名:"+fileName);
//获取文件表单名对象
Part part=req.getPart("uploadFile");
//获取上传文件名
String FileName = part.getSubmittedFileName();
//获取项目真实路径
String path=req.getServletContext().getRealPath("/upload/");
System.out.println(path);
//写入项目路径中
part.write(path+FileName);
二、文件下载
- 方式一
html超链接请求,对于不识别文件会自动下载,对于识别文件的会直接打开,所以可以设置为<a href="下载路径" download="1.jpeg">下载文件</a>
download属性有的浏览器不识别,谷歌浏览器识别,download可以设置为下载文件重命名。
- 前端代码(前提是要把存放文件的download文件夹加载到服务器中)
<body>
<%--由于浏览器识别文本和图片 不会下载 浏览器不识别压缩文件 会自动下载
想要让文本文件和图片文件进行下载 要加上download属性还可设置重命名
--%>
<a href="/download/hello2023.txt" download="new.txt">下载文本文件</a>
<a href="/download/test2023.rar" >下载压缩文件</a>
<a href="/download/冰墩墩2023.png" download>下载图片文件</a>
</body>
- 方式二
1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。(设置这个以后,浏览器才会不识别文件而进行下载,否则就会直接识别文件,如文本、图片等)
2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名" (设置这个以后,浏览器才会出现下载框并有下载文件名字)
3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
- 前端代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载文件</title>
</head>
<body>
<form action="download1">
请输入要下载文件的文件名:
<input type="text" name="fileName" placeholder="请输入要下载的文件名"/><br>
<input type="submit" value="下载"/>
</form>
</body>
</html>
- servlet后端
package com.msb.servletDemo;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-17 21:13
*/
@WebServlet("/download1")
public class DownloadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
//获取文件名
String name = req.getParameter("fileName");
//获取文件真实路径
String parentPath = req.getServletContext().getRealPath("/download/");
File file = new File(parentPath+name);
//判断文件是否存在
if(file.exists()){
//设置请求头
resp.setContentType("application/x-msdownload");
resp.setHeader("Content-Disposition","attachment;filename="+name);
//获取设置响应的输出流
ServletOutputStream stream = resp.getOutputStream();
//获取输入流
FileInputStream inputStream=new FileInputStream(file);
byte[] bytes=new byte[1024];
int len=0;
while ((len=(inputStream.read(bytes)))!=-1){
stream.write(bytes,0,len);
stream.flush(); //刷新
}
inputStream.close();
stream.close();
}else {
resp.getWriter().println("下载的文件不存在!!!");
}
}
}
12、过滤器
1、Filter 即为过滤器,用于在 Servlet 之外对 Request 或者 Response 进行修改。它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。
2、应用:处理用户权限分配、乱码问题。
3、过滤器的创建过程:
一、编写类实现Filter接口,重新抽象方法doFilter()。
二、为实现类添加@WebFilter([过滤路径]),让过滤器生效。
三、编写servlet类。
- 单个过滤器的工作原理。
1、启动服务器后初始化过滤器,然后执行doFilter(),每访问一次请求,就执行一次doFilter(),在doFilter()方法中进行拦截前和放行后的操作,关闭服务器就销毁过滤器。
- 多个过滤器的工作原理
1、若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时: 以相反的顺序执行。
2、通俗点讲就是开启服务器后,先配置的过滤器先初始化,然后后配置的后初始化,然后发起一次请求,先配置的过滤器执行doFilter(),后配置的过滤器接着执行doFilter(),然后放行后,先执行后配置的过滤器放行后操作,然后再执行先配置得到过滤器的放行后操作,最后关闭服务器先销毁先配置的过滤器,后销毁后配置的过滤器。
- 为所有请求设置UTF-8字符编码案例代码
package com.zwf.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-18 8:59
*/
@WebFilter("/*") //设置拦截/session/*
public class ServletFilterEncode implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("A过滤器初始化过滤器……");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//进行编码处理
servletRequest.setCharacterEncoding("UTF-8");
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/pain;charset=utf-8");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("A过滤器放行后处理……");
}
@Override
public void destroy() {
System.out.println("A过滤器过滤器销毁……");
}
}
13、监听器
1、监听器实际上是监听Servlet三大域对象(request、session、servletContext)的创建、销毁、动态运行,在创建、销毁、动态运行期间执行一定业务操作设置的对象。
2、应用:在session监听器中监听在线人数等。
3、使用方式
一、创建实现类实现三大域对象监听器接口。
二、重写接口中的抽象方法。
三、使用@WebListener注解激活监听器。
- 三大域八大监听接口
- 测试session监听器
1、关闭服务器session销毁,请求一次会话,创建session会话。session钝化需要下超时前设置,超时了session序列化文件就会删除,如果没有超时,钝化了,下次请求可以加载序列化文件在内存中(活化)。
2、同一种浏览器只有一个session,session对象在同一种浏览器中共享数据,除非删除浏览器中cookie才会创建新的session。
- 创建session钝化和活化的环境
1、配置context.xml文件
<!--
directory:设置序列化文件存放路径
maxIdleSwap: 设置多久后钝化 单位s 这里设置的1s后钝化
-1表示立即钝化
saveOnRestart=true 表示重启后保存序列化文件
-->
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1" >
<Store className="org.apache.catalina.session.FileStore" directory="D:\Tomcat\tomcat9\conf\session"/>
</Manager>
</Context>
2、对象实现序列化接口,并实现session钝化监听器接口。
3、对象存进session中。
4、在没有配置session钝化设置文件时,正常关闭服务器session会进行钝化操作,序列化文件放在tomcat的${TomcatPath}\work\Catalina\localhost\上下文路径名\目录下。(IDEA无法完成此操作,只有把IDEA中out文件夹的项目放在tomcat的webapps目下,DOS窗口启动服务器进行访问。)在未到超时情况下,启动服务器,session会自动进行活化。
5、正常关闭后session序列化后文件
- 测试代码
//前提要是实现序列化接口
public class suser implements Serializable, HttpSessionActivationListener {
private int sno;
private String sname;
private int age;
private String address;
public suser() {
}
public suser(int sno, String sname, int age, String address) {
this.sno = sno;
this.sname = sname;
this.age = age;
this.address = address;
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println(se.getSession().getId()+"session对象钝化了!!!!");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println(se.getSession().getId()+"session对象活化了!!!!");
}
}
//对象存进session域中
HttpSession session = req.getSession();
suser suser = new suser(120104,"张三",25,"北京");
session.setAttribute("suser",suser);
- 编写在线人数案例
@WebListener
public class sessionListenerDemo implements HttpSessionListener {
private int onlineNumber=0;
@Override
public void sessionCreated(HttpSessionEvent se) {
//因为多个session可以访问在线人数 所以要存储在application域中
ServletContext context = se.getSession().getServletContext();
onlineNumber++;
context.setAttribute("countNumber",onlineNumber);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
onlineNumber--;
context.setAttribute("countNumber",onlineNumber);
}
}
14、JSP技术
JSP(全称Java Server Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。
JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。
其实 Jsp 本质就是一个 Servlet,当我们第一次访问Jsp的时候,Jsp引擎都会将这个Jsp翻译成一个Servlet进行执行代码。
- JSP注释
1、显性注释:可以在前端页面上展示的注释。
<!---->
2、隐性注释:不能在前端页面上展示的注释。
jsp注释:<%----%>
java注释:// /**/
一、Scriptlet脚本小程序
<%! /*定义全局变量*/%> //在servlet中执行定义变量
//直接输出,相当于out.print();
<%="你好"%> //在servlet中执行out.print();
<%/*编写java代码 定义局部变量*/%> //在servlet中执行
- 静态引入和动态引入
静态引入是多个文件最终会在一个servlet中执行,重复的页面会被覆盖,效率高,代码耦合度也高。
动态引入是各个页面单独执行,互相调用,重复页面不会被覆盖,每个页面生成各自的字节码文件,效率低,代码耦合度低。
- 测试代码
<%--静态引入 page1.jsp已经定义了局部变量a --%>
<%@include file="page1.jsp"%>
<%
// int a=20; //无法定义局部变量
%>
<%@include file="page2.jsp"%>
<%--动态引入 双标签内如果没有参数 不能有空格--%>
<%
String str="admin";
%>
<%--name属性不能使用scriptLet表达式 而value可以使用--%>
<jsp:include page="page1.jsp"></jsp:include>
<jsp:include page="page2.jsp">
<jsp:param name="username" value="<%=str%>"/>
</jsp:include>
<%--page2页面中可以在scriptLet标签内用java代码获取属性值--%>
<%
String username=request.getParamter("username");
%>
二、jsp四大域对象
pageContext:页面中的数据共享,页面跳转数据失效。
request:服务端请求的数据共享(请求转发),客户端请求数据共享失效。
session:客服端和服务端都可以实现数据共享。
ServletContext:整个项目jsp页面数据共享。
jsp标签实现请求转发:<jsp:forward page="page1.jsp"></jsp:forward>
- 代码测试
pageContext.setAttribute("username","小曾");
request.setAttribute("req","小赵");
session.setAttribute("ses","小王");
application.setAttribute("app","小李");
<%--获取pageContext中的对象--%>
${username}
<%--服务器跳转--%>
<jsp:forward page="page4.jsp"></jsp:forward>
//page4页面如下:
<%--可以获取session和重定向request转发的数据
username是pageContext域中的数据 跳转页面无法获取
--%>
${username}
<%--获取request请求的数据--%>
${req}
<%--获取session数据--%>
${ses}
<%--获取application域数据--%>
${app}
三、jsp九大内置对象(可以直接使用,不用实例化)
- 注意:如果要使用exception内置对象,必须把页面设置为错误页面 isErrPage=truem,其他内置对象直接使用
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" pageEncoding="UTF-8" isErrPage=true%>
<%
//使用内置对象 exception打印异常信息
String message = exception.getMessage();
out.print("错误信息是:"+message);
%>
- jsp页面头部声明属性
常用属性:contextType:浏览器请求头文件声明浏览器展示的文本类型和字符编码
language:声明此页面用java语言编写
errorPage:声明如果页面执行出现异常,跳转到的页面。
pageEncodeing:声明页面字符编码
isErrPage:声明页面是异常跳转页面,也是使用exception内置对象必须声明的属性。
import:导入java类。
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" pageEncoding="UTF-8" import="java.util.List"%>
四、EL表达式
1、EL表达式主要是用于简化输出展示值的java代码,直接在里面编码name属性就可以获取四大域对象存储的值。
2、表达式:${expression}
3、使用EL表达式获取域数据的时候,如果没有指明作用域,那会按照作用域由小到大的顺序去找,直到找到为止:pageContext ---> request ---> session ---> application
4、当域对象全找完了还未找到则返回空字符串""。
- EL对域对象中的值直接操作
<%
pageContext.setAttribute("username","小曾");
request.setAttribute("req","小赵");
session.setAttribute("ses","小王");
application.setAttribute("app","小李");
%>
<%--可以获取session和重定向request转发的数据
username是pageContext域中的数据 跳转页面无法获取
--%>
${username}
<%--获取request请求的数据--%>
${req}
<%--获取session数据--%>
${ses}
<%--获取application域数据--%>
${app}
//EL表达式取对象值
<%
List<String> list=new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
request.setAttribute("list",list);
Map<String,Object> map=new HashMap<>();
map.put("sno",1002);
map.put("age",18);
map.put("address","北京");
request.setAttribute("maps",map);
// 如果实体类中的属性是私有化 必须加上get方法 否则取不出值
User user=new User("1001","张三",18,"北京");
request.setAttribute("user",user);
%>
<%--EL表达式进行取值--%>
${list[0]},
${list[1]},
${list[2]},
${maps.name}<br>
${maps["age"]}
${user}<br>
${user.name}
- 运算符使用
可以直接在${}进行运算。
+-*/运算,但是需要注意的一点是使用+号只是单纯的用于数值计算,不能用于字符串拼接,如果是数值字符型会自动转为数值进行运算。
比较运算符: == equ
不为空:${empty 变量}返回布尔型 如果变量是一个空字符串或者null返回true 如果是一个集合,只要没有添加值就返回true。 如果是自定义对象,只要是null返回true。
逻辑运算符:! || && >= = <= between and
五、JSTL标签
前提需要导入jstl-api.jar和standard.jar两个包。
JSTL标签是对EL表达式的补充,进一步简化<%%>里的java代码,大致可以分为三大类:条件动作标签、格式化动作标签、迭代动作标签。
条件动作标签:<c:if test="${}"> <c:/if>
<c:choose>
<c:when test="">
<c:/when>
<c:otherwise>
<c:/otherwise>
<c:/choose>
迭代动作标签:
<c:foreache item="" var="" begin="" end="" step="" >
<c:foreache>
格式化动作标签:
<fmt:formatNumber>
<fmt:formatDate>
<fmt:parseNumber>
<fmt:parseDate>
- 条件动作标签测试代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl标签核心标签库和动作标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>测试jstl标签</title>
</head>
<body>
<%
request.setAttribute("score",78);
%>
<%-- scope表示jsp四大域,var表示接收变量--%>
<c:if test="${score<60}">
成绩不及格!
</c:if>
<c:if test="${score>=60&&score<70}" >
成绩及格!
</c:if>
<c:if test="${score>=70&&score<80}" >
成绩良好!
</c:if>
<c:if test="${score>=80&&score<=100}">
成绩优秀!
</c:if>
<c:choose>
<c:when test="${score<80}">
成绩在80分以内!
</c:when>
<c:when test="${score>80}">
成绩超过80分!
</c:when>
<c:otherwise>
没有成绩数据!
</c:otherwise>
</c:choose>
</body>
</html>
- 迭代动作标签测试代码
<%@ page import="java.util.List" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %><%--
User: Mr Zeng
Date: 2023/8/19
Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>测试迭代动作标签</title>
</head>
<body>
<%
List list=new ArrayList();
list.add(121);
list.add(1123);
list.add(1546);
list.add(12562);
list.add(1213);
list.add(12135445);
pageContext.setAttribute("list",list);
pageContext.setAttribute("str","abcd#efgh#ijlm");
Map map=new HashMap();
map.put("name","小曾");
map.put("age",23);
map.put("job","程序员");
pageContext.setAttribute("map",map);
%>
<%--items表示获取迭代的key var表示接收的变量 varStatus表示变量数据类型--%>
<c:forEach items="${list}" var="i" varStatus="int">
${i},
</c:forEach>
<br>
<%--直接迭代输出数值--%>
<c:forEach begin="1" end="10" var="i" step="2">
${i}
</c:forEach>
<br>
<%--如果迭代字符串用,分割 则会自动分割--%>
<c:forEach items="${str}" var="s">
${s}
</c:forEach>
<%--如果其他符号分割需要指定分割的符号--%>
<c:forTokens items="${str}" delims="#" var="s">
${s}
</c:forTokens>
<hr>
<%--迭代输出map集合--%>
<c:forEach items="${map}" var="m">
${m.key}--------->${m.value}
</c:forEach>
</body>
</html>
- 测试格式化动作标签
<%
Date date = new Date();
request.setAttribute("date",date);
%>
<%--设置时区是美元--%>
<fmt:setLocale value="en_US" scope="page"/>
<%--数值转型 默认转为人民币数值¥--%>
<fmt:formatNumber type="currency" value="120121012"/><br>
<%--字符串1231转成数值型 用于转表单存储的数据 表单输入的数据是字符串类型--%>
<fmt:formatNumber type="number" value="1231"/>
<%--日期按照相应格式转字符串 pattern表示字符格式--%>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"/><br>
<%--字符串2000-01-16会自动转日期--%>
<fmt:parseDate value="2000/01/16" type="date" pattern="yyyy/MM/dd"/>
<fmt:parseDate value="2000-01-16" type="date" pattern="yyyy-MM-dd"/>
<%--货币或数字转字符串 type:表示传入的值所属类型 number数值型 percent百分数 currency货币--%>
<fmt:parseNumber type="number" value="12121"/>
<fmt:parseNumber type="percent" value="100%"/>
<fmt:parseNumber type="currency" value="$120151"/>
六、MVC三层架构
MVC三层架是model、view、controller,view视图层采用jsp技术,model层采用jdbc技术,controller层采用servlet技术。
业务设置:用户进行登录操作,如果登录失败跳转到登录页并提示信息,登录成功跳转到首页,如果直接进入首页进行拦截并重定向到登录页,如果直接发起登录请求也拦截并跳转到错误页。
- 模拟登录跳转代码
- Servlet请求代码
package com.zwf.controller;
import com.zwf.service.LoginService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-19 16:13
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private final LoginService SERVICE=new LoginService();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String pwd=req.getParameter("password");
boolean login = SERVICE.Login(username, pwd);
String path = req.getContextPath();
HttpSession session = req.getSession();
String username1 =(String)session.getAttribute("username");
if(login){
req.setAttribute("username",username);
session.setAttribute("username",username);
req.getRequestDispatcher("/index.jsp").forward(req,resp);
}else {
System.out.println(username);
System.out.println(pwd);
System.out.println(username1);
if(username!=null||pwd!=null){
if(!"".equals(username)||!"".equals(pwd)){
req.setAttribute("info","用户名或密码错误,请核对密码再进行登录!");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}else{
if(username1==null||"".equals(username1)){
resp.sendRedirect(path+"/error.jsp");
}else {
resp.sendRedirect(path+"/index.jsp");
}
}
}
}
}
- Service层代码
package com.zwf.service;
import com.zwf.dao.DataDao;
import com.zwf.pojo.LoginUser;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-19 16:13
*/
public class LoginService {
private final DataDao DAO=new DataDao();
public boolean Login(String username,String password) {
boolean flag = false;
LoginUser loginUser = DAO.queryFind(username, password);
if (loginUser != null) {
flag = true;
}
return flag;
}
}
- dao层代码
package com.zwf.dao;
import com.zwf.pojo.LoginUser;
import com.zwf.utils.SqlUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-19 16:12
*/
public class DataDao {
private Connection conn=null;
private PreparedStatement statement=null;
private ResultSet rs=null;
public LoginUser queryFind(String username,String password){
LoginUser us=null;
conn = SqlUtils.getConnection();
String sql="select * from login_user where username=? and password=?";
try {
statement=conn.prepareStatement(sql);
statement.setString(1,username);
statement.setString(2,password);
rs = statement.executeQuery();
while (rs.next()){
us =new LoginUser();
us.setUid(rs.getInt(1));
us.setPassword(rs.getString(3));
us.setUsername(rs.getString(2));
}
return us;
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
SqlUtils.conClose(conn,statement,rs);
}
}
}
- 工具类
package com.zwf.utils;
import java.sql.*;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-19 16:14
*/
public class SqlUtils {
private static Connection connection = null;
private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
private static final String USER = "SCOTT";
private static final String PASSWORD = "tiger";
static {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
try {
return connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void conClose(Connection con, Statement state, ResultSet rs) {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (state != null) {
try {
state.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
public static void conClose(Connection con, Statement state) {
conClose(con, state, null);
}
}
- 过滤器
package com.zwf.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-08-19 17:55
*/
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
String username = (String) request.getSession().getAttribute("username");
System.out.println(username);
String path = request.getContextPath();
if(username==null||"".equals(username)){
response.sendRedirect(path+"/error.jsp");
return;
}
filterChain.doFilter(servletRequest,servletResponse);
}
}
- web.xml文件注册过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>encode</filter-name>
<filter-class>com.zwf.filter.EncodeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>login</filter-name>
<filter-class>com.zwf.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>login</filter-name>
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
标签:请求,req,JAVAEE,基础知识,session,servlet,public,String
From: https://www.cnblogs.com/smallzengstudy/p/17643083.html