JavaWeb
Java Web应用由一组Servlet,HTML页面,类,以及其他可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的Servlet容器中运行。
包含如下内容:
- Servlet
- JSP
- 实用类
- 静态文档如HTML,图片等
- 描述Web应用的信息(web.xml)
Servlet与Servlet容器
web程序的目录结构
Servlet
Servlet 容器
管理Servlet的创建、使用、销毁
运行Servlet,JSP,Filter等的软件环境
可以用来创建Servlet,并调用Servlet的相关生命周期方法
http://c.biancheng.net/servlet2/container.html
现在的Servlet容器相当于Web服务器+Web容器
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
执行原理
- 当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet资源路径
- 查找web.xml文件,是否有对应的标签体内容
- 如果有,则找到对应的全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
生命周期
-
被创建:执行init方法,只执行一次
-
Servlet什么时候被创建?
默认情况下,第一次被访问时,被创建
可以配置执行Servlet的创建时机
<servlet> <servlet-name>demo2</servlet-name> <servlet-class>Demo2</servlet-class> <!-- 指定Servlet的创建时机--> <!-- 1. 第一次被访问时,创建--> <!-- <load-on-startup>的值为负数--> <!-- 2. 服务器启动时,创建--> <!-- <load-on-startup>的值为0或正整数--> <load-on-startup>5</load-on-startup> </servlet>
-
Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
-
多个用户同时访问时,可能存在线程安全问题
-
解决:尽量不要在Servlet中定义成员变量,即使定义了成员变量,也不要对其修改值
-
-
-
提供服务:执行service方法,执行多次
每次访问Servlet时,Service方法都会被调用一次
-
被销毁:执行destroy方法,只执行一次
-
Servlet被销毁时执行,服务器关闭时,Servlet被销毁
-
只有服务器正常关闭时,才会执行destroy方法
-
destroy方法在Servlet被销毁之前执行,一般用于释放资源
-
相关配置
urlpartten:Servlet访问路径
-
一个Servlet可以定义多个访问路径:
@WebServlet({"/d4","/dd4","/ddd4"})
-
路径定义规则:
- /xxx:路径匹配
- /xxx/xxx:多层路径,目录结构
- *.do:扩展名匹配
HTTP
概念
Hyper Text Transfer Protocol 超文本传输协议
传输协议:定义了,客户端和服务器端通信时,发送数据的格式
特点:
- 基于TCP/IP的高级协议
- 默认端口号:8080
- 基于请求/响应模式的:一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
历史版本:
1.0:每一次请求响应都会建立新的连接
1.1:复用连接
响应消息数据格式
-
响应行
组成:协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
-
都是3位数字
-
分类:
-
1XX:服务器接受客户端信息,但没有接收完成,等待一段时间后,发送1XX状态码
-
2XX:成功。代表:200
-
3XX:重定向。代表:302(重定向),304(访问缓存)
-
4XX:客户端错误。
代表:
404(请求路径没有对应的资源)
405(请求方式没有对应的doXxx方法)
-
5XX:服务器端错误。代表:500(服务器内部出现异常)
-
-
-
响应头
-
格式:头名称:值
-
常见的响应头:
-
Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
-
Content-disposition:服务器告诉客户端以什么格式打开响应体数据
值:
in-line:默认值,在当前页面内打开
attachment;filename=xxx:以附件形式打开响应体,文件下载
-
-
-
响应空行
-
响应体:传输的数据
Response
功能:设置响应消息
- 设置响应行
- 格式:HTTP/1.1 200 ok
- 设置状态码:setStatus(int sc)
- 设置响应头:setHeader(String name, String value)
- 设置响应体
- 获取输出流
- 字符输出流:PrintWriter getWriter()
- 字节输出流:ServletOutputStream getOutputStream()
- 使用输出流,将数据输出到客户端浏览器
- 获取输出流
※ 案例:
-
完成重定向:访问/responseDemo1,会自动跳转到/responseDemo2
第一种
response.setStatus(302); response.setHeader("location","/day15/responseDemo2");
第二种
response.sendRedirect("/day15/responseDemo2");
重定向(redirect)的特点:
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求,不能使用request对象来共享数据
转发(forward)的特点:
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
request.getRequestDispatcher("/responseDemo2").forward(request, response);
路径写法:
-
路径分类
-
相对路径:通过相对路径不能确定唯一资源
不以/开头,以.开头的路径
./:当前目录
../:后退一级目录
-
绝对路径:通过绝对路径可以确定唯一资源
以/开头的路径
给客户端浏览器使用:需要加虚拟目录
//动态获取虚拟目录 String contextPath = request.getContextPath();
给服务器使用:不需要加虚拟目录
转发路径
-
-
服务器输出字符数据到浏览器
//获取流对象前,设置流的默认编码 response.setCharacterEncoding("GBK"); //告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码 response.setHeader("content-type","text/html;charset=utf-8"); //简单的形式,设置编码 response.setContentType("text/html;charset=utf-8"); //获取字符输出流 PrintWriter pw = response.getWriter(); //输出数据 pw.write("hello");
-
服务器输出字节数据到浏览器
//设置解码类型 response.setContentType("text/html;charset=utf-8"); //获取字节输出流 ServletOutputStream sos = response.getOutputStream(); //输出数据 sos.write("hello".getBytes("utf-8"));
请求消息数据格式
-
请求行
请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1
请求方式
HTTP协议中有7种请求方式,常用的有两种
- GET
- 请求参数在请求行中,在url后
- 请求的url长度有限制
- 不太安全
- POST
- 请求参数在请求体中
- 请求的url长度没有限制
- 相对安全
- GET
-
请求头
请求头名称: 请求头值
常见的请求头
-
User-Agent:
浏览器告诉服务器,我访问你使用的浏览器版本信息。可以用来在服务器端获取该头的信息,解决浏览器的兼容性问题
-
Referer:http://localhost/login.html
告诉服务器,当前请求从哪里来
作用:
- 防盗链
- 统计工作
-
-
请求空行
空行
-
请求体(正文)
封装POST请求消息的请求参数的
Request
-
request对象和response对象的原理
request和response对象是由服务器创建的,我们来使用它们
request对象是来获取请求消息的,
response对象是来设置响应消息的
-
request对象继承体系结构
ServletRequest -- 接口
| 继承
HttpServletRequest -- 接口
| 实现
org.apache.catalina.connector.RequestFacade 类(tomcat)
-
request功能
-
获取请求消息数据
-
获取请求行数据
GET /day14/demo1?name=ethic HTTP/1.1
方法:
-
获取请求方式:GET
String getMethod()
-
获取虚拟目录:/day14 【重要!】
String getContextPath()
-
获取Servlet路径:/demo1
String getServletPath()
-
获取get方式请求参数:name=ethic
String getQueryString()
-
获取请求URI:/day14/demo1【重要!】
String getRequestURI() //得到/day14/demo1 StringBuffer getRequestURL() //得到http://localhost/day14/demo1 URL:统一资源定位符 URI:统一资源标识符
-
获取协议及版本:HTTP/1.1
String getProtocol()
-
获取客户机的IP地址:
String getRemoteAddr()
-
-
获取请求头数据
-
通过请求头的名称获取请求头的值【重要!】
String getHeader(String name)
-
获取所有请求头名称
Enumeration<String> getHeaderNames()
-
-
获取请求体数据
请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数
步骤:
-
获取流对象
//获取字符输入流,只能操作字符数据 BufferedReader getReader() //获取字节输入流,可以操作所有类型的数据 ServletInputStream getInputStream()
-
从流对象中拿数据
-
-
-
其他功能
-
获取请求参数通用方式(GET和POST都可以)
-
根据参数名称获取参数值
String getParameter(String name)
-
根据参数名称获取参数值的数组
String[] getParameterValues(String name)
-
获取所有请求的参数名称
getParameterNames()
-
获取所有参数的map集合
Map<String,String[]> getParameterMap()
-
中文乱码问题:
get方式:tomcat 8 已经将get方式乱码问题解决了
post方式:在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8")
-
-
请求转发:一种在服务器内部的资源跳转方式
-
通过request对象获取请求转发器对象
RequestDispatcher getRequestDispatcher(String path)
-
使用RequestDispatcher对象来进行转发
forward(ServletRequest request, ServletResponse response)
-
特点:
浏览器地址栏路径不发生变化
只能转发到当前服务器内部资源中
转发是一次请求
-
-
共享数据
域对象:
一个有作用范围的对象,可以在范围内共享数据
request域:
代表一次请求的范围,一般用于请求转发的多个资源***享数据
方法:
-
存储数据
void setAttribute(String name, Object obj)
-
通过键获取值
Object getAttribute(String name)
-
通过键移除键值对
void removeAttribute(String name)
-
-
获取ServletContext
ServletContext getServletContext()
-
-
ServletContext对象
概念:代表整个web应用,可以和程序的容器(服务器)来通信
功能
-
获取MIME类型
-
MIME类型:在互联网通信过程中定义的一种文件数据类型
-
格式:大类型/小类型 text/html image/jpeg
-
获取:
String getMimeType(String file)
-
-
域对象:共享数据
1. setAttribute(String name, Object value) 2. getAttribute(String name) 3. removeAttribute(String name)
ServletContext对象范围:所有用户所有请求的数据
-
获取文件的真实(服务器)路径
方法:String getRealPath(String path)
//获取文件的服务器路径 String realPath = context.getRealPath("/b.txt"); //web目录下资源访问 File file = new File(realPath); String realPath = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问 String realPath = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
步骤:
-
定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
-
定义Servlet
- 获取文件名称
- 使用字节输入流加载文件进内存
- 指定response的响应头:
content-disposition:attachment;filename=xxx
- 将数据写出到response输出流
代码实现:
//1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1找到文件服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/" + filename); //2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); //3.设置response的响应头 //3.1设置响应头类型:content-type String mimeType = servletContent.getMimeType(filename); response.setHeader("content-type",mimeType); //3.2设置响应头打开方式:content-disposition response.setHeader("content-disposition","attachment;filename="+filename); //解决中文文件名问题 //1.获取user-agent请求头 String agent = request.getHeader("user-agent"); //2.使用工具类方法编码文件名即可 filename = DownLoadUtils.getFileName(agent, filename); //4.将输入流的数据写出到输出流中 ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024*8]; int len = 0; while((len = fis.read(buff)) != -1){ sos.write(buff,0,len); } fis.close();
获取
-
通过request对象获取
request.getServletContext();
-
通过HttpServlet获取
this.getServletContext();
会话技术
-
会话:一次会话中包含多次请求和响应
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
-
功能:在一次会话的范围内的多次请求间共享数据
-
方式:
- 客户端会话技术:Cookie
- 服务器端会话技术:Session
Cookie
-
概念:客户端会话技术,将数据保存到客户端
-
快速入门
使用步骤
-
创建Cookie对象,绑定数据
new Cookie(String name, String value)
-
发送Cookie对象
response.addCookie(Cookie cookie)
-
获取Cookie,拿到数据
Cookie[] request.getCookies()
-
-
实现原理
基于响应头set-cookie和请求头cookie实现
-
Cookie的特点和作用
- cookie存储数据在客户端浏览器
- 浏览器对于单个cookie的大小有限制(4kb),以及对于同一个域名下的总cookie数量也有限制(20个)
- cookie一般用于存储少量的不太敏感的数据,在不登录的情况下,完成服务器对客户端的身份识别
-
Cookie的细节
-
一次可不可以发送多个cookie?
可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
-
cookie在浏览器中保存多长时间?
-
默认情况下,当浏览器关闭后,Cookie数据被销毁
-
持久化存储
setMaxAge(int seconds)
- 正数:将Cookie数据写到硬盘的文件中,持久化存储。cookie存活时间。
- 负数:默认值
- 零:删除cookie信息
c1.setMaxAge(30); //将cookie持久化到硬盘,30秒后自动删除cookie文件
-
-
cookie能不能存中文?
tomcat 8之前不可以,需要转码,之后可以
-
cookie共享问题?
-
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
默认情况下不能。setPath(String path):设置cookie的获取范围。默认情况下不能共享。如果要共享,可以把path设置成"/"
-
不同的tomcat服务器间cookie共享问题?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
-
-
-
案例:记住上一次访问时间
-
需求
- 访问一个Servlet,如果是第一次访问,提示:您好,欢迎您首次访问
- 如果不是第一次访问,提示:欢迎回来,您上次访问时间是:显示时间字符串
-
分析
- 可以采用cookie来完成
- 在服务器中的Servlet判断是否有一个名为lastTime的cookie
- 有:不是第一次访问
- 响应数据:欢迎回来,您上次的访问时间是2022年1月25日10:05:59
- 写回Cookie:lastTime=2022年1月25日10:05:59
- 没有:是第一次访问
- 响应数据:您好,欢迎您首次访问
- 写回Cookie:lastTime=2022年1月25日10:05:59
- 有:不是第一次访问
-
代码实现
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应的消息体的数据格式以及编码 response.setContentType("text/html;charset=utf-8"); //1.获取所有Cookie Cookie[] cookies = request.getCookies(); boolean flag = false;//没有cookie为lastTime //2.遍历cookie数组 if(cookies != null && cookies.length > 0){ for (Cookie cookie : cookies) { //3.获取cookie的名称 String name = cookie.getName(); //4.判断名称是否是lastTime if("lastTime".equals(name)){ //有该cookie,不是第一次访问 flag = true;//有lastTime的cookie //设置Cookie的value //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdf.format(date); cookie.setValue(str_date); //URL编码 str_date = URLEncoder.encode(str_date,"utf-8"); cookie.setValue(str_date); //设置cookie的存活时间 cookie.setMaxAge(60 * 60 * 24 * 30); response.addCookie(cookie); //响应数据 //获取Cookie的value,时间 String value = cookie.getValue(); //URL解码 value = URLDecoder.decode(value, "utf-8"); response.getWriter().write("<h1>欢迎回来,您上次访问时间为:"+value+"</h1>"); } } } if(cookies == null || cookies.length == 0 || flag == false){ //设置Cookie的value //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); //URL编码 String strDate = URLEncoder.encode(sdf.format(date),"utf-8"); Cookie cookie = new Cookie("lastTime",strDate); //设置cookie的存活时间 cookie.setMaxAge(60 * 60 * 24 * 30); response.addCookie(cookie); response.getWriter().write("<h1>您好,欢迎您首次访问</h1>"); } }
-
Session
-
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中
-
快速入门:
-
获取HttpSession对象
HttpSession session = request.getSession();
-
使用HttpSession对象
Object getAttribute(String name) void setAttribute(String name, Object value) void removeAttribute(String name)
-
-
原理:Session的实现是依赖于Cookie的
-
细节:
-
客户端关闭后,服务器不关闭,两次获取session是否为同一个?
默认情况下,不是
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
不是同一个,但是要确保数据不丢失
-
session的钝化(序列化)
在服务器正常关闭之前,将session对象序列化到硬盘上
-
session的活化(反序列化)
在服务器启动后,将session文件转化为内存中的session对象即可
-
-
session什么时候被销毁?
-
服务器关闭
-
session对象调用invalidate()
-
session默认失效时间是30分钟
选择性配置修改
<session-config> <session-timeout>30</session-timeout> </session-config>
-
-
-
session的特点
session用于存储一次会话的多次请求的数据,存在服务器端
session可以存储任意类型,任意大小的数据
session与cookie的区别:
- session存储数据在服务器端,cookie在客户端
- session没有数据大小限制,cookie有
- session数据安全,cookie相对来说不安全
-
案例:验证码
- 案例需求:
- 访问带有验证码的登录页面login.jsp
- 用户输入用户名、密码以及验证码
- 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
- 如果验证码输入有误,跳转登录页面,提示:验证码错误
- 如果全部输入正确,则跳转到主页success.jsp,显示:用户名 欢迎你
- 案例需求:
JSP
-
概念
Java Server Pages:java服务器端页面
可以理解为一个特殊的页面,其中既可以定义html标签,又可以定义java代码
-
原理
JSP本质上就是一个Servlet
-
指令
作用:用于配置JSP页面,导入资源文件
格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...%>
指令名称
-
page: 配置JSP页面的
- contentType:等同于response.setContentType()
设置响应体的mime类型以及字符集
设置当前jsp页面的编码
(只能是高级的IDE才能生效,如果使用低级工具,需要设置pageEncoding属性设置当前页面的字符集)
-
import:导包
-
errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
-
isErrorPage:标识当前是否是错误页面
true:是,可以使用内置对象exception
false:否,默认值,不可以使用内置对象exception
-
include:页面包含的,导入页面的资源文件
<%@include file="top.jsp"%>
-
taglib: 导入资源
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
prefix:前缀,自定义的
<% 代码 %> //定义的java代码在service方法中 //service方法中可以定义什么,里面就可以定义什么 <%! 代码 %> //定义的java代码,在jsp转换后的java类的成员位置 <%= 代码 %> //定义的java代码会输出到页面上
-
-
注释
-
html注释:
只能注释html代码片段<%-- --%> 可以注释所有
-
-
JSP的内置对象
在jsp页面中不需要获取和创建,可以直接使用的对象
jsp一共有9个内置对象
-
request
真实类型:HttpServletRequest
一次请求访问的多个资源(转发)
-
response
真实类型:HttpServletResponse
响应对象
-
out
真实类型:JspWriter
字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
response.getWriter()和out.write()的区别:
在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据
response.getWriter()数据输出永远在out.write()之前
-
pageContext
真实类型:PageContext
当前页面共享数据,还可以获取其他八个内置对象
-
session
真实类型:HttpSession
一次会话的多个请求间
-
application
真实类型:ServletContext
所有用户间共享数据
-
page
真实类型:Object
当前页面(Servlet)的对象,this
-
config
真实类型:ServletConfig
Servlet的配置对象
-
exception
真实类型:Throwable
异常对象
-
MVC开发模式
为了简化JSP出现的
M:Model,模型(JavaBean)
完成具体的业务操作,如:查询数据库、封装对象
V:View,视图(JSP)
展示数据
C:Controller,控制器(Servlet)
获取用户的输入,调用模型,将数据交给视图进行展示
优点:
- 耦合性低,方便维护,利于分工协作
- 重用性高
缺点:
项目架构变得复杂
EL表达式
-
概念:Expression Language 表达式语言
-
作用:替换和简化jsp页面中java代码的编写
-
语法:${表达式}
-
注意:
jsp默认支持el表达式,如果要忽略el表达式
- 设置jsp中page指令中:isELIgnored="true"忽略当前jsp页面中所有的el表达式
- \${表达式}:忽略当前这个el表达式
-
使用:
-
运算
-
算数运算符:+ - * / (div) % (mod)
-
比较运算符:> < >= <= == !=
-
逻辑运算符:&&(and) ||(or) !(not)
-
空运算符:empty
功能:用于判断字符串、集合、数组对象是否为null并且长度是否为0
${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
${not empty str}:表示字符串、集合、数组对象是否不为null 并且 长度>0
-
-
获取值
-
el表达式只能从域对象中获取值
-
语法:
-
${域名称.键名}:从指定域中获取指定键的值
域名称:
pageScope ——> pageContext
requestScope ——> request
sessionScope ——> session
applicationScope ——> application(ServletContext)
举例:在request域中存储了name=张三
获取:${requestScope.name}
-
${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止
-
-
获取对象,List集合,Map集合的值
-
对象:${域名称.键名.属性名}
本质上会去调用对象的getter方法
-
List集合:${域名称.键名[索引]}
-
Map集合:
${域名称.键名.key名称}
${域名称.键名["key名称"]}
-
-
-
隐式对象
el表达式中有11个隐式对象
pageContext:获取jsp其他八个内置对象、
动态获取虚拟目录
${pageContext.request.contextPath}
-
JSTL标签
-
概念:JavaServer Pages Tag Library JSP标准标签库
-
作用:用于简化和替换jsp页面上的java代码
-
使用步骤:
- 导入jstl相关jar包
- 引入标签库:taglib指令 <%@ taglib %>
- 使用标签
-
常用的JSTL标签
使用前需引入如下代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/c" %>
-
if
-
属性
test为必须属性,接受boolean表达式
如果表达式为true,显示if标签体内容,如果为false,不显示标签体内容
一般情况下,test属性值会结合el表达式一起使用
-
注意
<c: if>标签没有else的情况,想要else情况,可以再定义一个<c: if>标签
-
-
choose (相当于switch声明)
when (相当于case)
otherwise (相当于default)
<% request.setAttribute("number",3); %> <c:choose> <c:when test="${number == 1}">星期一 </c:when> <c:when test="${number == 2}">星期二 </c:when> <c:when test="${number == 3}">星期三 </c:when> <c:when test="${number == 4}">星期四 </c:when> <c:when test="${number == 5}">星期五 </c:when> <c:when test="${number == 6}">星期六 </c:when> <c:when test="${number == 7}">星期日 </c:when> <c:otherwise>数字输入有误</c:otherwise> </c:choose>
-
foreach
-
完成重复的操作
for(int i=0; i<10; i++){}
begin:开始值
end:结束值
var:临时变量
step:步长
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
<c:forEach begin="1" end="10" var="i" step="1" varStatus="s">${i} ${s.index}</c:forEach>
-
遍历容器
List<User> list; for(User user: list){}
items:容器对象
var:容器中元素的临时变量
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
<c:forEach items="${list}" var="str" varStatus="s"> ${s.index} ${s.count} ${str} </c:forEach>
-
练习
需求:在request域中有一个存有User对象的List集合,需要使用jstl+el将list集合数据展示到jsp页面的表格table中
<% List list = new ArrayList(); list.add(new User("张三",23,new Date())); list.add(new User("李四",24,new Date())); list.add(new User("王五",25,new Date())); request.setAttribute("list",list); %> <table border="1" width="500" align="center"> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> <th>生日</th> </tr> <c:forEach items="${list}" var="user" varStatus="s"> <tr> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.birStr}</td> </tr> </c:forEach> </table>
-
-
三层架构
软件设计架构
-
界面层:用户看的界面,
用户可以通过界面上的组件和服务器进行交互
-
业务逻辑层:处理业务逻辑的
-
数据访问层:操作数据存储文件的
Filter
-
概念
当访问服务器的资源的时候,过滤器可以将请求拦截下来,完成一些特殊的功能
过滤器的作用:一般用于完成通过的操作,如:登录验证、统一编码处理、敏感字符过滤
-
快速入门
-
步骤
- 定义一个类,实现接口Filter
- 复写方法
- 配置
@WebFilter("/*") //访问所有资源之前,都会执行该过滤器 public class FilterDemo1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { } }
-
过滤器细节
-
web.xml配置
<filter> <filter-name>demo1</filter-name> <filter-class> cn.itcast.web.filter.FilterDemo1 </filter-class> </filter> <filter-mapping> <filter-name>demo1</filter-name> <!-- 拦截路径 --> <url-pattern>/*</url-pattern> </filter-mapping>
-
过滤器执行流程
- 执行过滤器
- 执行放行后的资源
- 回来执行过滤器放行代码下的代码
-
过滤器生命周期方法
doFilter方法,每一次请求被拦截时,会执行
服务器启动后,会创建Filter对象,然后调用init方法
在服务器关闭后,Filter对象被销毁
如果服务器正常关闭,执行destroy方法
-
过滤器配置详解
拦截路径配置
- 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录:/user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截:*.jsp 访问所有jsp资源时,过滤器都会被执行
- 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
拦截方式配置:资源被访问的方式
-
过滤器链(配置多个过滤器)
-
-