1.Servlet技术
1.1 JavaWeb概述
-
在Sun的Java Servlet规范中,对Java Web应用作了这样定义:“JavaWeb应用由一组Servlet、HTML页、类、以及其它可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的Servlet容器中运行。
-
Java Web应用中可以包含如下内容: Servlet JSP 实用类-------ORM 静态文档如HTML、图片等 描述Web应用的信息(web.xml)
1.2 Servelt与Servlet容器
1.2.1 Serlet容器概念
-
Servlet容器为JavaWeb应用提供运行时环境,它负责管理Servlet和JSP的生命周期,以及管理它们的共享数据。
-
Servlet容器也称为JavaWeb应用容器,或者Servlet/JSP容器。
-
目前最流行的Servlet容器软件括:
Tomcat Resin J2EE服务器(如WebLogic)中也提供了内置的Servlet容器
1.2.2 tomcat简介
Tomcat是一个免费的开放源代码的Servlet容器,它是 Apache软件基金会的一个顶级项目,由Apache,Sun和其他一些公司及个人共同开发而成。由于有了Sun 的参与与支持,最新的Servlet 和JSP规范总是能在Tomcat中的到体现。
(1)Tomcat目录结构
(2) 运行tomcat
-
配置java_home或者jre_home
-
双击bin目录下的startup.bat文件
-
在地址栏中输入http://localhost:8080/
(3) 关闭Tomcat&配置Tomcat的端口号
-
双击bin目录下的shutdown.bat文件关闭Tomcat服务器
-
修改 Tomcat默认的端口号:
打开conf目录下的server.xml文件
修改端口号
(4) tomcat的管理程序
-
Tomcat提供了一个管理程序:manager,用于部署到 Tomcat服务器中的web应用程序
-
要访问manager web应用程序,需要添加具有管理员权限的账号,编辑conf目录下的tomcat-users.xml文件,添加manager角色,设置用户名和密码。
1.2.3 web程序结构
-
一个 web应用程序是由一组Servlet,HTML页面,类,以及其它的资源组成的运行在web服务器上的完整的应用程序,以一种结构化的有层次的目录形式存在。
-
组成 web应用程序的这些文件要部署在相应的目录层次中,根目录代表整个web应用程序的”根”。
-
通常将web应用程序的目录放在webapps目录下,在webapps目录下的每一个子目录都是一个独立的web应用程序,子目录的名字就是web应用程序的名字,也就是 web应用程序的“根”。用户通过web应用程序的”根”来访问web应用程序中的资源。
Servlet规范中定义了web 应用程序的目录层次:
-
WEB-INF目录下的classes和lib目录都可以存放Java的类文件,在Servlet容器运行时,Web应用程序的类加载器将首先加载classes目录下的,其次才是lib目录下的类。如果这两个目录下存在同名的类,起作用的将是classes目录下的类
-
WEB-INF是一个特殊的目录(所有字母都要大写)。这个目录并不属于Web应用程序可以访问的上下文路径的一部分,对客户端来说,这个目录是不可见的。但该目录下的内容对于Servlet代码是可见的
1.2.4 Servlet简介
-
Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式。
-
Servlet可完成如下功能:
(1)创建并返回基于客户请求的动态HTML页面。 (2)创建可嵌入到现有HTML页面中的部分HTML 页面(HTML 片段)。 (3)与其它服务器资源(如数据库或基于Java的应用程序)进行通信。
1.2.5 Servlet容器响应客户请求的过程
映射关系
映射细节介绍
-
同一个Servlet可以被映射到多个URL上,即多个元素的子元素的设置值可以是同一个Servlet的注册名。
-
在Servlet映射到的URL中也可以使用通配符,但是只能有两种固定的格式:一种格式是“扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
<servlet-mapping> <senslet-nane>AnyNane</serwlet-nane> <url-pattern>*,doc</ur1-pattern> </servlet-mapping> <Serlet-mapping> <sgrvlet-nane>AayNane</serwlet-nane> <url-pattern>/action/*</url-pattern> </seowlet-mapping>
1.2.6 ServletConfig接口
-
Servlet在有些情况下可能需要访问Servlet容器或借助Servlet容器访问外部的资源,所以, Serlvet引擎需要将表示Servlet容器的对象传递给Servlet。另外,在web.xml文件中为某个Servlet设置的友好名称和初始化参数等信息也需要传递给该Servlet
-
Servlet引擎将代表Servlet容器的对象(ServletContext)和Servlet的配置参数信息一并封装到一个称ServletConfig的对象中,并在初始化Servlet实例对象时传递给该Servlet。
-
ServletConfig接口则用于定义ServletConfig对象需要对外提供的方法,以便在Servlet程序中可以调用这些方法来获取有关信息。
-
Servlet引擎调用Servlet的实例对象的init(ServletConfig config)方法将ServletConfig对象传递给Servlet,Servlet.getServletConfig()方法必须返回init(ServletConfig config)方法传递进来的这个ServletConfig对象的引用。
1.2.7 ServletConfig接口的方法
-
getlnitParameterNames
-
getInitParameter
-
getServletName
-
getServletContext
1.2.8 ServletContext接口
-
Servlet引擎为每个WEB应用程序都创建一个对应ServletContext对象,ServletContext对象被包含在ServletConfig对象中,调用SelrvletConfig.getServletContext方法可以返回ServletContext对象的引用。
-
由干一个WEB应用程序中的所有Servlet都共享同一个ServletContext对象,所以,ServletContext对象被称之为application对象(Web应用程序对象)。
-
功能:
1.获取WEB应用程序的初始化参数
2.记录日志
3.application域范围的属性
4.访问资源文件
5.获取虚拟路径所映射的本地路径
6.WEB应用程序之间的访问
7.ServletContext的其他方法
1、获取WEB应用程序的初始化参数:
-
为WEB应用程序设置初始化参数的好处在于不需要修改Servlet源程序,就可以改变一些参数信息。
-
ServletContext.getInitParameterNames方法用于返回一个包含WEB应用程序的所有初始化参数名称的Enumeration集合对象。ServletContext.getInitParameter方法用于返回某个指定名称的初始化参数值。
-
在web.xml文件的根元素中增加子元素,如下所示:
<context-paran> <paran-name>campanyNane</param-name> <param-value>lanpbrother</param-value> </context-paran>
2、获取虚拟路径所映射的本地路径
getRealPath(String path)方法:用于返回某个虚拟路径所映射的本地文件系统路径
1.2.9 HTTP
-
WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个规则就是HTTP协议。
-
HTTP是 hypertext transfer protocol(超文本传输协议)的简写,它是 TCP/IP协议集中的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程以及数据本身的格式。
-
HTTP协议的版本HTTP/1.0、HTTP/1.1、HTTP-NG
1、HTTP的会话方式
四个步骤:
2、游览器访问多图网页的过程
3、HTTP请求消息 请求消息的结构:一个请求行、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。
4、使用GET和POST方式传递参数
-
在URL地址后面可以附加一些参数
举例: http://www.it315.org/servlet/ParamsServlet?param1=abc¶m2=xyz
-
GET方式
举例:GET /servlet/ParamsServlet?param1=abc¶m2=xyz HTTP/1.1
特点:传送的数据量是有限制的,一般限制在1KB以下。
-
POST方式 举例:
POST /servlet/ParamsServlet HTTP/1.1 Host: Content-Type: application/x.-www-form-urlencoded Content-Length: 28 param1=abc¶m2=xyz 特点:(1)传送的数据量要比GET方式传送的数据量大得多。(2)相对get数据传输安全
1.2.10 HttpServletRequest简介
-
Servlet API中定义的ServletRequest接口类用于封装请求消息。
-
HttpServletRequest是专用于HTTP协议的ServletRequest子接口,它用于封装 HTTP请求消息。
-
在service()方法内部调用HttpServletRequest对象的各种方法来获取请求消息。
1、获取请求行的相关信息
-
HTTP请求消息的请求行包括请求方式、资源路径和HTTP协议版本:
-
GET /lampbrother/servlet/RequestURl?param1=a¶m2=b HTTP/1.1
-
getMethod:返回HTTP请求消息中的请求方式。
-
getRequestURI:返回请求行中的资源名部分。
-
getQueryString:返回请求行中的参数部分。
-
getProtocol:返回请求行中的协议名和版本。
-
getContextPath:返回请求资源所属于的WEB应用程序的路径。
-
getPathInfo:返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
-
getPathTranslated:返回URL中的额外路径信息所对应的资源的真实路径。
-
getServletPath方法: Servlet的名称或Servlet所映射的路径。
2、获取网络链接信息
-
getRemoteAddr方法返回发出请求的客户机的IP地址,其格式为“192.168.0.3”这种形式的字符文本。(*)
-
getRemoteHost方法返回发出请求的客户机的完整主机名,即“pc1.atguigu.com”这种格式。
-
getRemotePort方法返回发出请求的客户机所使用的网络接口的端口号。
-
getLocalAddr方法返回WEB服务器上接收当前请求的网络接口的IP地址。
-
getLocalName方法返回WEB服务器上接收当前请求的网络接口的IP地址所对应的主机名。
-
getLocalPort方法返回WEB服务器上接收当前请求的网络接口的端口号。
-
getServerName方法返回当前请求所指向的主机名。
-
getServerPort方法返回当前请求所连接的服务器端口号。
-
getScheme方法返回请求的协议名,例如http.https或ftp。
-
getRequestURL方法返回客户端发出请求时的完整URL。
3、获取请求头信息
-
getHeader方法
-
getHeaders方法
-
getHeaderNames方法
-
getIntHeader方法
-
getDateHeader方法
-
getContentType方法
-
getContentLength方法
-
getCharacterEncoding方法
4、获取请求参数
-
getParameter方法
-
getParameterValues方法
-
getParameterNames方法
-
getParameterMap方法
5、请求域属性
-
存储在ServletRequest对象中的对象称之为请求域属性,属于同一个请求的多个处理模块之间可以通过请求域属性来传递对象数据。
-
与请求域属性相关的方法:
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
1.2.11 HttpServletResponse简介
Servlet API中定义的ServletResponse接口类用于创建响应消息。 HttpServletResponse是专用于HTTP协议的ServletResponse子接口,它用于封装HTTP响应消息。
1.2.12 重定向与转发
1、RequestDispatcher接口
RequestDispatcher实例对象是由Servlet引擎创建的,它用于包装一个要被其他资源调用的资源(例如,Servlet、HTML文件、JSP文件等),并可以通过其中的方法将客户端的请求转发给所包装的资源。
RequestDispatcher接口中定义了两个方法:forward方法和include方法。
forward和include方法接收的两个参数必须是传递给当前Servlet的service方法的那两个ServletRequest和ServletResponse对象,或者是对它们进行了包装的 ServletRequestWrapper或ServletResponseWrapper对象。
获取RequestDispatcher对象的方法: ServletContext.getRequestDispatcher(参数只能是以“/”开头的路径)ServletContext.getNamedDispatcher ServletRequest.getRequestDispatcher(参数可以是不以“/”开头的路径)
2 JSP技术介绍
2.1 定义
-
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
-
JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
-
JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
-
JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。
2.2 JSP使用原因
JSP程序与CGI程序有着相似的功能,但和CGI程序相比,JSP程序有如下优势:
-
性能更加优越,因为JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件。
-
服务器调用的是已经编译好的JSP文件,而不像CGI/Perl那样必须先载入解释器和目标脚本。
-
JSP 基于Java Servlet APl,因此,JSP拥有各种强大的企业级Java API,包括JDBC,JNDI,EJB,JAXP等等。
-
JSP页面可以与处理业务逻辑的Servlet一起使用,这种模式被Java servlet模板引擎所支持。
-
JSP是Java EE不可或缺的一部分,是一个完整的企业级应用平台。这意味着JSP可以用最简单的方式来实现最复杂的应用。
2.3 优势
-
与ASP相比:JSP有两大优势。首先,动态部分用Java编写,而不是VB或其他MS专用语言,所以更加强大与易用。第二点就是JSP易于移植到非MS平台上。
-
与纯Servlet相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句。
-
与SSI相比:SSI无法使用表单数据、无法进行数据库链接。
-
与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。
-
与静态HTML相比:静态HTML不包含动态信息。
2.4 JSP/Servlet环境搭建
2.4.1下载安装tomcat
Apache Tomcat® - Apache Tomcat 8 Software Downloads
2.4.2 开启tomcat
注意目录名不能有中文和空格。目录介绍如下:
-
bin:二进制执行文件。里面最常用的文件是startup.bat,如果是Linux或Mac系统启动文件为startup.sh。
-
conf:配置目录。里面最核心的文件是server.xml。可以在里面改端口号等。默认端口号是8080,也就是说,此端口号不能被其他应用程序占用。
-
lib:库文件。tomcat运行时需要的jar包所在的目录 logs:日志
-
temp:临时产生的文件,即缓存
-
webapps: web的应用程序。web应用放置到此目录下浏览器可以直接访问
-
work:编译以后的class文件。
接着我们可以双击startup.bat启动Tomcat,弹出如下界面:
思考:乱码问题如何解决?
乱码出现的集中情况:
数据库结构字段及内容,idea项目或文件,前端页面乱码,tomcat解析乱码
启动成功页面如下
项目运行的流程
2.4.3 编写并访问JSP
<%@ page contentType="text/html;charset=UTF-8" %> <% out.print("祝大家节日快乐 : 祝各位薪资翻倍,前途似锦!!!"); %>
将页面放在webapps/ROOT
接着在游览器中访问地址http://127.0.0.1:8080/test.jsp,输出结果如下
2.4.4 创建Servlet实例
2.5 JSP结构
-
脚本元素(Scripting Elements):在JSP页面中,可以通过脚本元素插入Java代码。主要包括以下三种类型:
-
声明(Declaration):用于声明一个或多个变量或方法,这些变量或方法可以在整个JSP页面中使用。
-
表达式(Expression):将Java表达式的值直接输出到HTML页面中。
-
脚本段(Scriptlet):插入一段可执行的Java代码。
-
案例1:
<%-- 声明变量 --%> <%! String message = "Hello, JSP!"; %> <%-- 表达式 --%> <p>Message: <%= message %></p> <%-- 脚本段 --%> <% int a = 10; int b = 20; int sum = a + b; %> <p>Sum: <%= sum %></p>
-
指令元素(Directive Elements):用于控制JSP页面的行为。主要包括以下三种类型:
-
page指令:用于设置整个JSP页面的属性,如导入类库、设置错误处理等。
-
include指令:将其他文件的内容包含到当前JSP页面中。
-
taglib指令:定义一个自定义标签库,以便在JSP页面中使用自定义标签。
-
案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ include file="header.jsp" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
动作元素(Action Elements):用于执行特定的任务,如请求转发、包含其他资源等。动作元素以"jsp:"为前缀。
案例:
<jsp:forward page="target.jsp" /> <jsp:include page="footer.jsp" />
-
注释(Comments):用于在JSP页面中添加注释,以提高代码的可读性和可维护性。JSP支持两种类型的注释:HTML注释和JSP注释。
案例:
<!-- HTML注释 --> <%-- JSP注释 --%>
2.6 JSP生命周期
JSP生命周期是指从创建JSP页面到销毁JSP页面的整个过程。在这个过程中,JSP容器会调用一系列的方法来处理JSP页面。JSP生命周期主要包括以下几个阶段:
-
初始化(Initialization):当JSP页面被第一次请求时,JSP容器会调用_jspInit()方法对JSP页面进行初始化。
案例:
<%! public void _jspInit() { System.out.println("JSP页面初始化"); } %>
-
解析(Parsing):JSP容器会将JSP页面中的脚本元素、指令元素和动作元素解析成对应的Java代码。
-
编译(Compilation):JSP容器将解析后的Java代码编译成字节码文件(.class文件)。
-
加载(Loading):JSP容器加载编译后的字节码文件到内存中,并创建一个JSP页面对象。
-
请求处理(Request Processing):当用户请求JSP页面时,JSP容器会调用_jspService()方法处理请求。在这个阶段,JSP容器会执行脚本元素中的Java代码,并将生成的HTML内容发送给客户端。
案例:
<%! public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("JSP页面处理请求"); } %>
-
销毁(Destruction):当JSP页面被销毁时,JSP容器会调用_jspDestroy()方法释放资源。
案例:
<%! public void _jspDestroy() { System.out.println("JSP页面销毁"); } %>
2.7 JSP语法
JSP(JavaServer Pages)是一种基于Java技术的Web动态页面技术。它允许开发者在HTML页面中嵌入Java代码,从而实现页面的动态生成。下面是关于JSP语法的详细笔记以及代码片段:
2.7.1 JSP表达式
JSP表达式用于将Java表达式的值直接输出到HTML页面中。表达式以"<%= %>"为前缀和后缀。
案例:
<% int a = 10; int b = 20; int sum = a + b; %> <p>Sum: <%= sum %></p>
2.7.2 JSP注释
JSP支持两种类型的注释:HTML注释和JSP注释。
案例代码:
<!-- HTML注释 --> <%-- JSP注释 --%>
2.7. 3 JSP行为
JSP行为是一种特殊的JSP元素,用于执行特定的任务,如请求转发、包含其他资源等。行为以"jsp:"为前缀。
案例代码:
<jsp:forward page="target.jsp" /> <jsp:include page="footer.jsp" />
2.7.4 JSP隐含对象
JSP隐含对象是在JSP页面中自动创建的对象,可以直接使用,无需手动创建。主要包括以下九个对象:
-
request:HttpServletRequest对象,用于获取客户端请求的信息。
-
response:HttpServletResponse对象,用于向客户端发送响应。
-
pageContext:PageContext对象,用于获取JSP页面的上下文信息。
-
session:HttpSession对象,用于在多个请求之间保存会话信息。
-
application:ServletContext对象,用于在整个Web应用中共享数据。
-
out:JspWriter对象,用于向客户端发送HTML输出。
-
config:ServletConfig对象,用于获取Servlet的配置信息。
-
page:Object对象,表示当前JSP页面实例。
-
exception:Throwable对象,用于处理JSP页面中的异常。
案例:
<% String requestURI = request.getRequestURI(); String sessionID = session.getId(); String contextPath = application.getContextPath(); %> <p>Request URI: <%= requestURI %></p> <p>Session ID: <%= sessionID %></p> <p>Context Path: <%= contextPath %></p>
2.7.5 控制语句
JSP支持Java中的控制语句,如if、switch、for等。
案例:
<% int score = 85; %> <% if (score >= 90) { %> <p>优秀</p> <% } else if (score >= 80) { %> <p>良好</p> <% } else { %> <p>需要努力</p> <% } %>
2.7.6 循环语句
JSP支持Java中的循环语句,如for、while、do-while等。
案例:
<% String[] fruits = {"苹果", "香蕉", "橙子"}; %> <% for (String fruit : fruits) { %> <p>水果:<%= fruit %></p> <% } %>
2.7.7 JSP运算符
JSP支持Java中的运算符,如算术运算符、比较运算符、逻辑运算符等。
案例:
<% int a = 10; int b = 20; int c = a + b; boolean isEqual = a == b; %> <p>Sum: <%= c %></p> <p>Is equal: <%= isEqual %></p>
2.7.8 JSP字面量
JSP支持Java中的字面量,如整数、浮点数、字符串、布尔值等。
案例:
<% int intValue = 42; double doubleValue = 3.14; String stringValue = "Hello, JSP!"; boolean booleanValue = true; %> <p>Integer: <%= intValue %></p> <p>Double: <%= doubleValue %></p> <p>String: <%= stringValue %></p> <p>Boolean: <%= booleanValue %></p>
2.8 JSP指令
JSP(JavaServer Pages)指令是用于为JSP页面提供全局信息的。这些指令在JSP页面加载时由JSP容器(如Tomcat)处理,并影响整个页面的处理。以下是JSP指令的详细笔记以及一些案例代码。
2.8.1 JSP指令的类型
JSP定义了三种指令:
-
page:定义页面依赖的属性,如脚本语言、错误页面、缓存需求等。
-
include:在当前页面中包含其他文件。
-
taglib:定义在页面中使用的标签库。
2.8.2 JSP page指令
page指令是最常用的指令,它定义了与页面相关的各种属性。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
-
language
:指定脚本语言,默认为Java。 -
contentType
:指定响应的MIME类型和字符编码。 -
pageEncoding
:指定JSP文件的字符编码。
其他常用的属性还有:
-
import
:导入Java类。 -
session
:指定页面是否参与HTTP会话,默认为true。 -
isELIgnored
:指定是否忽略表达式语言(EL),默认为false。
2.8.3 JSP include指令
include指令用于在当前页面中包含其他文件。这可以是静态文件(如HTML或JSP)或动态文件(如Servlet)。
<%@ include file="header.jsp" %>
上面的代码将在当前位置包含header.jsp
文件的内容。
2.8.4 JSP taglib指令
taglib指令用于定义在JSP页面中使用的标签库。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
上面的代码导入了JSTL核心标签库,并使用c
作为前缀。
2.8.5 案例代码
案例1:使用page指令
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Page Directive Example</title> </head> <body> <h1>Welcome to JSP Page!</h1> </body> </html>
案例2:使用include指令
假设我们有一个header.jsp
文件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title><%= pageContext.getAttribute("title") %></title> </head> <body>
和一个index.jsp
文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.util.Date" %> <%@ include file="header.jsp" %> <h1>Welcome to Index Page!</h1> <% pageContext.setAttribute("title", "Index Page Title"); %> <p>Current Date: <%= new Date() %></p> </body> </html>
注意:在上面的例子中,title
属性是在包含header.jsp
之后设置的,但header.jsp
在渲染时仍然可以访问它,因为pageContext
对象在包含的文件之间共享。
案例3:使用taglib指令
使用JSTL核心标签库:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Taglib Directive Example</title> </head> <body> <h1>Welcome to JSTL Example!</h1> <c:out value="Hello, JSTL!" /> </body> </html>
3 MAC介绍
-
MVC是Model-View-Controller的简称,即模型-视图-控制器。是一种设计模式,它把应用程序分成三个核心模块:模型、视图、控制器,它们各自处理自己的任务。
-
模型是应用程序的主体部分,模型表示业务数据和业务逻辑。一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以提高了代码的可重用性。
-
视图是用户看到并与之交互的界面,视图向用户显示相关的数据、接受用户的输入、不进行任何实际的业务处理。
-
控制器接受用户的输入并调用模型和视图去完成用户的需求。控制器接收请求并决定调用哪个模型组件去处理请求,然后决定调用哪个视图来显示模型处理返回的数据
4 过滤器(Filter)介绍
4.1 过滤器(Filter)概念
过滤器是Java Web开发中的一个重要组件,用于在请求到达目标资源(如Servlet、JSP或HTML文件)之前或之后执行某些操作。过滤器可以拦截请求和响应,以便对它们进行查看或修改。它们通常用于执行诸如日志记录、身份验证、授权、编码转换、数据压缩等任务。
4.2 Filter接口
Filter
接口是Java Servlet API的一部分,用于定义过滤器的行为。要创建一个过滤器,你需要实现Filter
接口,并覆写以下三个方法:
-
init(FilterConfig filterConfig)
: 在过滤器实例化后调用,用于初始化过滤器的状态。 -
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
: 对请求和响应执行实际的过滤操作。此方法需要调用FilterChain
的doFilter
方法来确保请求到达目标资源,除非你确定要阻止请求。 -
destroy()
: 在过滤器被销毁之前调用,用于释放资源。
4.2.1 FilterConfig接口
FilterConfig
接口用于向过滤器提供配置信息。这些信息在Web应用程序的部署描述符(web.xml)中设置。当init
方法被调用时,FilterConfig
对象会传递给过滤器。你可以使用FilterConfig
来获取初始化参数、过滤器名称和ServletContext对象。
4.2.2 FilterChain接口
FilterChain
接口表示过滤器链中的一组过滤器。当请求/响应到达过滤器时,doFilter
方法被调用,并且过滤器可以选择继续处理链(通过调用chain.doFilter(request, response)
),或者阻止请求(不调用chain.doFilter
)。
4.3 案例
以下是一个简单的过滤器示例,用于记录请求的URL:
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class LoggingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化代码(如果有) System.out.println("LoggingFilter initialized."); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 记录请求的URL String requestURI = httpRequest.getRequestURI(); System.out.println("Request URI: " + requestURI); // 继续处理过滤器链 chain.doFilter(request, response); } @Override public void destroy() { // 销毁代码(如果有) System.out.println("LoggingFilter destroyed."); } }
在web.xml
中配置该过滤器:
<filter> <filter-name>LoggingFilter</filter-name> <filter-class>com.example.LoggingFilter</filter-class> </filter> <filter-mapping> <filter-name>LoggingFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 拦截所有请求 --> </filter-mapping>
现在,每当有请求到达Web应用程序时,LoggingFilter
都会记录请求的URL,然后继续处理过滤器链。
5 文件上传
文件上传是Web开发中常见的功能,它允许用户通过Web表单选择并发送文件到服务器。以下是文件上传的详细说明。
5.1 Enctype属性
在HTML表单中,为了支持文件上传,enctype
属性必须设置为multipart/form-data
。这是因为普通的application/x-www-form-urlencoded
编码类型不支持文件数据。
示例:
<form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="fileToUpload" id="fileToUpload"> <input type="submit" value="Upload Image" name="submit"> </form>
5.2 Commons-fileupload组件
commons-fileupload
是Apache Commons项目的一部分,它提供了一个简单的API来处理multipart/form-data
类型的请求,使得在Servlet中处理文件上传变得容易。
5.3 上传基本原理
-
用户在客户端选择一个或多个文件。
-
客户端通过HTTP POST请求将文件发送到服务器。
-
服务器使用
commons-fileupload
组件来解析这个请求,并将文件数据保存到服务器的某个位置。 -
服务器可能还需要执行一些额外的操作,如验证文件类型、大小等。
-
服务器完成处理后,将结果返回给客户端。
5.4 Commons-fileupload组件API
commons-fileupload
的主要API包括:
-
ServletFileUpload
:这个类是处理文件上传的入口点。它提供了parseRequest
方法来解析HTTP请求,并返回一个List
对象,每个FileItem
代表一个表单字段(可能是文件字段,也可能是普通字段)。 -
FileItem
:这个类代表一个表单字段。你可以使用它的isFormField
方法来判断它是否是一个文件字段,如果是,则可以使用getInputStream
方法获取文件数据,并使用getName
方法获取文件名(包括路径)。
5.5 案例代码
以下是一个使用Commons FileUpload处理文件上传的Servlet示例:
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; 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.IOException; import java.util.List; @WebServlet("/upload") @MultipartConfig public class FileUploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!ServletFileUpload.isMultipartContent(request)) { throw new ServletException("Content type is not multipart/form-data"); } DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); try { List<FileItem> items = upload.parseRequest(request); for (FileItem item : items) { if (!item.isFormField()) { String fileName = new File(item.getName()).getName(); String filePath = "/path/to/save/" + fileName; File storeFile = new File(filePath); item.write(storeFile); response.getWriter().println("File Uploaded Successfully! " + fileName); } } } catch (Exception e) { request.setAttribute("message", "File Upload Failed due to " + e); request.getRequestDispatcher("error.jsp").forward(request, response); } } }
6 文件的下载
-
情景:在一些网络系统中,需要隐藏下载文件的真实地址,或者下载的文件需要一个程序来动态的确定后在传送给客户端
-
方案:利用程序编码实现下载 可以增加安全访问控制,只对经过授权认证的用户提供下载可以从任意位置提供下载的数据
利用程序实现下载需要设置2个报头: 1、Web服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或HTML文件,而是一个要保存到本地的下载文件。设置Content-Type的值为:application/x-msdownload 2、Web服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置Content-Disposition 报头。该报头指定了接收程序处理数据内容的方式,在HTTP应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在attachment后面还可以指定filename参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置Content-Dispostion之前一定要指定Content-Type.