一、Servlet
1、Servlet简介
Servlet 是一个用 Java 编写的程序,此程序在服务器上运行以处理客户端请求。
Servlet优点
高效
支持缓存和多线程
方便
Servlet提供了大量的实用工具例程,例如自动地解析和解码HTML表单数
据、读取和设置HTTP头、处理Cookie、跟踪会话状态等。
功能强大
以Java API作为后盾
可移植性好
用Java语言编写
在服务器端运行
Servlet执行过程
1)客户端发送请求至服务器端;
2) 服务器遍历web.xml中url-pattern,找到 Servlet;
3)执行service()方法,service解析用户请求,匹配对应方法
4) Servlet方法 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
5) 服务器将响应返回给客户端;
2、Servlet原理
2.1、Servlet体系结构
ServletConfig 接口
用来封装web.xml中对当前Servlet的配置信息
getInitParameter()---可以获取初始化参数
web.xml
<init-param>
<param-name/>
<param-value/>
</init-param>
ServletContext
代表当前Servlet运行的上下文环境,用于获取来自其容器的信息的方法
ServletContext对象通常也被称之为context域对象。
setAttribute()
getAttribute()
removeAttribute()
利用ServletContext对象读取资源文件(注释)
ServletRequest
为Servlet所发送的请求,用ServletRequest封装
setAttribute()
getAttribute()
removeAttribute()
getParameter()
常用子接口HttpServletRequest
ServletResponse
Servlet对客户段所做的响应,用ServletResponse描述
getWriter():获取PrintWriter输出流给客户发送的响应内容
setContentType:设置响应内容的响应类型和字符集信息
sendRedirect:设置重新请求路径
子接口HttpServletResponse
2.2、Servlet生命周期
服务器只创建每个Servlet的单一实例,每个用户请求都会引发新的线程。
init()
在Servlet的生命周期中,仅执行一次init方法,是在servlet第一次被访问时执行,并用它的ServletConfig对象参数来启动配置
Public void init(ServletConfig config) throws ServletException
service()
在调用service()方法之前,应确保已完成init()方法
service()方法是Servlet的核心。
每当一个客户请求一个HttpServlet对象,该对象的service()方法就被调用
Public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
destroy()
在服务器停止且卸装Servlet时执行该方法,进行销毁
Public void destroy()
3、HttpServlet应用
HttpServlet 类提供一个抽象类以创建 HTTP Servlet
//自定义类继承HttpServlet以实现控制器角色
public class HelloServlet extends HttpServlet { }
//doGet() 方法处理客户端作出的 GET 请求。
public void doGet(HttpServletRequest req,HttpServletResponse res)
//doPost() 方法处理客户端作出的 post 请求。
public void doPost(HttpServletRequest req,HttpServletResponse res)
3.1、HttpServletRequest
request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。
要向容器输出数据,只需要找response对象就行了。
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
常用方法
获得客户机信息
方法名 | 说明 |
---|---|
getRequestURL | 方法返回客户端发出请求时的完整URL |
getRequestURI | 方法返回请求行中的资源名部分 |
getQueryString | 方法返回请求行中的参数部分 |
getRemoteAddr | 方法返回发出请求的客户机的IP地址 |
getRemoteHost | 方法返回发出请求的客户机的完整主机名 |
getRemotePort | 方法返回客户机所使用的网络端口号 |
getLocalAddr | 方法返回WEB服务器的IP地址 |
getLocalName | 方法返回WEB服务器的主机名 |
getMethod | 得到客户机请求方式 |
获得客户机请求参数(客户端提交的数据)
方法名 | 说明 |
---|---|
getParameter(name) | 获取单个入力值 |
getParameterValues(String name) | 获取一组数据 |
getParameterMap | 做框架用 |
req.setCharacterEncoding(“utf-8”) | 设置http请求编码格式 |
3.2、HttpServletResponse
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法
//用OutputStream(字节流)发送数据
response.getOutputStream().write(“中国”.getBytes("UTF-8")))//以UTF-8编码发送数据,浏览器(默认用GB2312)会 出现乱码
Response应用
通过response实现请求重定向
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
地址栏会变,并发送2次请求,增加服务器负担
实现方式:
response.sendRedirect()
3.3、编码格式设置
请求参数的中文乱码问题
解决:request.setCharacterEncoding(“UTF-8”);//POST有效
更改Tomcat的配置解决URL编码问题:<Connector URIEncoding=“UTF-8”/>
响应乱码
通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);
response.setContentType("text/html;charset=UTF-8");
3.4、forward和redirect区别
forward方法只能将请求转发给同一个WEB应用中的组件;sendRedirect方法可以重定向到其他应用程序中的资源
forward方法保持初始的URL地址不变;sendRedirect方法由初始的URL地址变成重定向的目标URL
forward方法的调用者与被调用者属于同一个访问请求和响应过程;sendRedirect 方法调用者与被调用者属于两个独立的访问 请求和响应过程
3.5、Servlet配置
xml配置
<Servlet>
<Servlet-name>text</Servlet-name>
<Servlet-class>com.soft.servlet.DomoServlet</Servlet-class>
<load-on-startup>1</load-on-startup>
</Servlet>
<Servlet-mapping>
<Servlet-name>test</Servlet-name>
<url-pattern>/domo</url-pattern>
</Servlet-mapping>
注解配置
//@WebServlet 可替代web.xml中的servlet请求配置,urlPatterns为对应Servlet类的请求地址
@WebServlet(urlPatterns="/addServlet")
pubic class AddServlet extends HttpServlet{
}
4、Servlet应用例
4.1、Servlet交互
GET方式将数据接在URL后面传送给服务器端程序
POST方式将数据放在HTTP请求的请求头后面发送
4.2、应用例
protected void doPost(HttpServletRequest req, HttpServletResponse resp){
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setCharacterEncoding("utf-8");
//获取浏览器输入的用户ID和用户密码
String userId = req.getParamter("userId");
String psd = req.getParameter("psd");
}
5、Servlet会话跟踪技术
什么是会话
会话是指一个终端用户(服务器)与交互系统(客户端)进行通讯的过程
什么是会话跟踪
对同一个用户对服务器的连续的请求和接受响应的监视。(将用户与同一用户发出的不同请求之间关联,为了数据共享)
为什么需要会话跟踪
浏览器与服务器之间的通信是通过HTTP协议进行通信的,而HTTP协议是”无状态”的协议,它不能保存客户的信息,即一次响应完成之后连接就断开了,下一次的请求需要重新连接,这样就需要判断是否是同一个用户,所以才应会话跟踪技术来实现这种要求
5.1、URL重写
URL(统一资源定位符)是Web上特定页面的地址,URL地址重写的原理是将该用户Session的id信息重写 到URL地址中,以便在服务器端进行识别不同的用户。
URL重写能够在客户端停用cookies或者不支持cookies的时候仍然能够发挥作用。
controller
@WebServlet("/B")
public class DemoBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");//URL重写
System.out.println(name);
name = URLDecoder.decode(name,"utf-8");
System.out.println(name);
}
}
Encode
public class EncodeUtil {
//转码
public static String encodingString(String str){
try{
str = URLEncoder.encode(str,"utf-8");
}catch(Exception e){
System.out.println(e.getMessage());
}
return str;
}
//解码
public static String decodeString(String str){
try{
str = URLDecoder.decode(str,"utf-8");
}catch(Exception e){
System.out.println(e.getMessage());
}
return str;
}
}
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script>
function funA(){
var val = document.getElementById("name").value;
alert(val);
val = encodeURI(val);
alert(val);
val = encodeURI(val);//浏览器解码一次,不再编码一次的话输出到控制台就是两次中文
alert(val);
location.href = "B?name="+val;
}
</script>
</head>
<body>
<input type="text" id="name"/>
<button οnclick="funA()">发送</button>
</body>
</html>
5.2、隐藏表单域:
将会话ID添加到HTML表单元素中提交到服务器,此表单元素并不在客户端显示,浏览时看不到,源代码中有。
controller
@WebServlet("/A")
//隐藏域表单
/*
a1提交表单时,a2如果不接收a1的数据并转发出去的话,在a2中想显示a1的东西
,就不会显示,必须将a1发送过来的东西也接收了并发送出去。
*/
public class DemoAServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
System.out.println(name);
}
}
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>//注意要将siELIgnored属性设置成false 才能使用el表达式
<html>
<head>
<title>Title</title>
</head>
<body>
${param.name}:${param.content}
<hr/>
<form action="a2.jsp" method="post">
<input type="text" name="content" placeholder="请输入内容"/>
<input type="hidden" name="name" value="${param.name}"/><!--不再次转发的话会读不到-->
<button>发送</button>
</form>
</body>
</html>
5.3、Cookie
cookie是一个用于在客户端浏览器中缓存数据的客户端文件,适用于稍大量的数据信息,比如:购物车信息,网站历史浏览器记录;
客户端可以采用两种方式来保存这个Cookie对象,一种方式是 保存在 客户端内存中,称为临时Cookie,浏览器关闭后 这个Cookie对象将消失。另外一种方式是保存在 客户机的磁盘上,称为永久Cookie。
controller
@WebServlet("/C")
public class DemoCServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");//设置请求的编码集
String name = req.getParameter("name");
String pass = req.getParameter("pass");
String is = req.getParameter("is");
if ("admin".equalsIgnoreCase(name)&&"a123".equals(pass)){
if (is!=null){//选中记住密码
Cookie names = new Cookie("USER_NAME",name);
names.setMaxAge(60*60*24);
resp.addCookie(names);
Cookie passes = new Cookie("USER_PASS",pass);
passes.setMaxAge(60*60*24);
resp.addCookie(passes);
}
resp.sendRedirect("index.jsp");
}else{
resp.sendRedirect("c.jsp?error=1");
}
}
}
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:if test="${param.error==1}">
你的账号或密码错误!
</c:if>
<form method="post" action="C">
<table border="1">
<tr>
<th>账号</th>
<td><input type="text" name="name" value="${cookie.USER_NAME.value}"/></td>
</tr>
<tr>
<th>密码</th>
<td><input type="password" name="pass" value="${cookie.USER_PASS.value}"/></td>
</tr>
<tr>
<th colspan="2"><input type="checkbox" name="is" value="1"/>是否记住密码</th>
</tr>
<tr>
<th colspan="2"><button>登录</button></th>
</tr>
</table>
</form>
</body>
</html>
5.4、session
session是用于存储客户端和服务端一次会话信息一个缓存空间
session由于是存储在服务端的缓存空间,因此处于效率考虑,不应该向session中存储大量数据,session适用于存储少量的信息,并且对安全性要求较高的数据,比如说用户身份信息。
HttpSession session = request.getSession();
session.setAttribute("user",user);
注意:session的默认有效期是30分钟,可以通过在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">
<!--配置session的超时时间-->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
</web-app>
5.5、Cookie和session的区别
1、cookie数据存放在客户的浏览器上,session数据存放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
6、Servlet过滤器
Servlet过滤器是在Java Servlet 2.3 规范中定义的,它是一种可以插入的Web组件,它能够对Servlet 容器的接收到的客户端请求和向客户端发出的响应对象进行截获,过滤器支持对Servlet程序和JSP页面的基本请求处理功能,如日志、性能、安全、会话 处理、XSLT转换等。
Servlet过滤器的作用
查询请求并做出相应的动作
阻塞请求-响应时,使其不能下一步行动发
修改请求的头部和数据,用户可以提供自定义的请求
修改相应的头部和数据,用户可以通过定制的相应版本实现
与外部资源进行交互
Servlet对请求的过滤过程:
Servlet创建一个过滤器实例
过滤器实例调用init方法,读取过滤器的初始化参数
过滤器实例调用doFilter方法,根据初始化参数的值判断该请求是否合法,如果请求不合法,则阻塞该请求;如果请求合法, 则调用chain.doFilter方法将该请求向后传递
Servlet对响应的过滤过程
过滤器截获客户端的请求
重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流
将请求向后续传递
Web组件产生响应
从封装后的ServletResponse中获取用户自定义的输出流
将响应内容通过用户自定义的输出流写到缓冲流中
在缓冲流中修改响应的内容后清空缓冲流,输出响应内容
Servlet过滤器接口的构成
void init(FilterConfig):过滤器的初始化方法,Servlet容器在创建过滤器实例时调用这个方法,在这个方法中可以读出在web.xml文件中为该过滤器配置的初始化参数。
void doFilter(ServletRequest,ServletResponse,FilterChain):用于完成实际的过滤操作,当客户请求访问与过滤器相关联的URL时,Servlet容器将先调用过滤器的这个方法,FilterChain参数用于访问后续过滤器。
void destroy():过滤器在被取消前执行这个方法,释放过滤器申请的资源
Servlet过滤器的创建步骤
1.创建一个实现了javax.servlet.Filter接口的类。
2.重写init(FilterConfig)方法,读入过滤器配置的初始化参数就。
3.重写方法doFilter,完成过滤操作,从ServletRequest参数中得到全部的请求信息,从ServletResponse参数中得到全 部的响应信息。
4.在doFilter()方法的最后,使用FilterChain参数的doFilter()方法将请求和响应后传。
5.对响应的Servlet程序和JSP页面注册过滤器,部署文件(web.xml)
过滤器类
public class CopyrightFilter implements Filter {
protected FilterConfig config;
protected String date;
public void init(FilterConfig filterconfig)throws ServletException{
this.config = filterconfig;
date = filterconfig.getInitParameter("date");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
PrintWriter out = response.getWriter();
out.println("<br><center><font color='red'>Web监听器测试,下面是监听器添加的时间"
+ "</font></center>");
if(date!=null){
out.println("<br><center><font color='red'>"+date+"</font></center>");
out.flush();
}
}
public void destroy(){
this.config=null;
}
}
xml
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>ch13.SessionFilter</filter-class>
<init-param>
<param-name>logonStrings</param-name>
<param-value>Login.jsp</param-value>
</init-param>
<init-param>
<param-name>includeStrings</param-name>
<param-value>.jsp;.html;.htm</param-value>
</init-param>
<init-param>
<param-name>redirectPath</param-name>
<param-value>./Login.jsp</param-value>
</init-param>
<init-param>
<param-name>disabletestfilter</param-name>
<param-value>n</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7、监听器
监听器就是监听某个对象的的状态变化的组件
通过它可以监听Web应用的上下文(环境)信息、Servlet请求信息、Servlet会话信息,并自动根据不同情况,在后台调用相应的处理程序。通过监听器,可以自动激发一些操作,比如监听在线人数。
监听器的类型
ServletRequest监听器(请求监听器)
ServletRequestListener
作用:用来监听ServletRequest对象创建和销毁
接口方法:requestInitialized()、requestDestroyed()
接收事件:RequestEvent
触发场景:在request(HttpServletRequest)对象建立或被销毁时,会分别调用这两个方法。
ServletRequestAttributeListener
作用:用来监听ServletRequest 对象属性的变化
接口方法: attributeAdded()、 attributeReplaced()、attributeRemoved()
接收事件: HttpSessionBindingEvent
触发场景: 若有对象加入为request(HttpServletRequest)对象的属性,则会调用attributeAdded(),同理在置换属性与移除属性时,会分别调用attributeReplaced()、 attributeRemoved()。
HttpSession监听器(会话监听器)
HttpSessionListener
作用:用来监听HttpSession对象创建和销毁
接口方法:sessionCreated()、sessionDestroyed ()
接收事件:HttpSessionEvent
触发场景:在session (HttpSession)对象建立或被销毁时,会分别调用这两个方法。
HttpSessionAttributeListener
作用:用来监听HttpSession 对象属性的变化
接口方法: attributeAdded()、 attributeReplaced()、attributeRemoved()
接收事件: HttpSessionBindingEvent
触发场景: 若有对象加入为session(HttpSession)对象的属性,则会调用attributeAdded(),同理在置换属性与移除属性时,会分别调用attributeReplaced()、 attributeRemoved()。
ServletContext监听器(上下文监听器)
ServletContextListener
作用:用来监听ServletContext对象创建和销毁
接口方法:contextInitialized()、contextDestroyed()
接收事件:ervletContextEvent
触发场景:在服务器加载Web 应用程序时,会调用contextInitialized(),而当容器移除Web 应用程序时,会调用contextDestroyed ()方法。
ServletContextAttributeListener
作用:用来监听ServletContext 对象属性的变化
接口方法: attributeAdded()、 attributeReplaced()、attributeRemoved()
接收事件: ServletContextAttributeEvent
触发场景: 若有对象加入为application(ServletContext)对象的属性,则会调用attributeAdded(),同理在置换属性与移除属性时,会分别调用attributeReplaced()、attributeRemoved()。
在web.xml中,使用来配置监听器
<listener>
<listener-class>包名.类名</listener-class>
</listener>
二、Java EE
1、JSP页面技术
1.1、JSP简介
JSP的全称是:Java Server Pages。
JSP 页面技术擅长页面表现,Servlet 擅长逻辑控制
JSP 可以看做一个变种的Servlet
1.2、JSP执行过程
翻译阶段
将JSP文件中的脚本代码(HTML)和代码片段(java代码)全部转换为java代码
编译阶段
Java 类编译成 class 文件
执行阶段
编译后的class对象被加载到容器中,并根据用户的请求生成HTML格式的响应页面返回给客户端
1.3、JSP页面的基本构成
静态内容
HEML静态文本
指令元素
JSP指令元素主要用来提供整个JSP网页相关的信息,并且用来设定JSP页面的相关属性
【语法】<%@ 指令名 属性= “属性值” %>
JSP有3种指令元素
page指令
page指令用来设定JSP页面的全局属性,该配置作用于整个JSP页面。
【语法】 <%@page 属性="属性值" 属性="属性值"%>
include指令
include指令用于将文件的内容插入到include指令所在的位置,先执行被包含文件,再执行JSP
【语法】 <%@ include file="被包含文件的URL"%>
taglib指令
taglib指令用来声明此JSP文件使用了自定义的标签,同时制定所引用的标签库并设置前缀。
【语法】 <%@ taglib uri="taglibrary's uri" prefix="tagPrefix"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
脚本元素
脚本段是写在<% %>标记中Java代码片段,•可以进行复杂的操作和处理业务逻辑。
【语法】
<% Java代码片段 %>
【例】
<%
for (int i = 1; i <= 20; i++) {
if (i % 2 == 0) {
%>
<%=i %> <br/>
<%
}
}
%>
表达式
表达式主要用来输出一个变量或一个表达式的值。
【语法】
<%=java表达式 %>
【例】
<%=i %> <br/>
声明
声明就是在JSP页面中定义Java的变量和方法
【语法】
<%! Java代码 %>
【例】
<%!
String formatDate(Date d){
SimpleDateFormat formater = new SimpleDateFormat("yyyy年MM月dd日");
retrun formater.format(d);
}
%>
你好,今天是
<%=formatDate(new Date()) %>
1.4、动作指令
JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。
1、jsp:include动作
jsp:include动作指令表示在当前的JSP页面中,包含静态或动态资源
【例】
<jsp:include page="bottom.jsp" flush="true"></jsp:include>
2、jsp:forward动过
jsp:forward动作用于将请求转发到另一个JSP、Servlet或者静态资源文件。
【例】
<%
String username = request.getParameter("xzl");
String pwd = request.getParameter("pwd");
if(!"admin".equals(username)&&!"123".equals(pwd))
%>
<jsp:forward page="error.jsp"></jsp:forward>;
<%} else {%>
<jsp:forward page="success.jsp"></jsp:forward>
<%}%>
用户名为:<%=username%>
密码为:<%=pwd%>
3、jsp:param动作
jsp:param动作用于页面之间传递参数。在使用jsp:param动作时,必须配合jsp:include、jsp:forward动作使用
注:param只能作为子标签使用
【例】
<jsp:include page="paramInclude.jsp" flush="true">
<jsp:param name="username" value="某某某"/>
<jsp:param name="password" value="108"/>
</jsp:include>
用户名:<%=request.getParameter(“username”)%><br>
用户密码:<%=request.getParameter(“password”)%>
1.5、内置对象
JSP内置对象是可以直接在JSP页面使用的对象,无需使用“new”获取实例,不需要声明和实例化
【例】
<%
String username = request.getParameter(“username”);
String password = request.getParameter(“pwd”);
%>
九大内置对象
输入输出对象:
request
【例】String getParameter(String name)
Object getAttribute(String name)
void setAttribute(String name,Object obj)
response
【例】 void sendRedirect(String name)
void setContentType(String name)
void setCharacterEncoding(String cahrset)
out
【例】out.print(输出数据):输出数据到页面
out.close();关闭输出流
作用域通信对象:
session
application
pageContext
Servlet 对象
page
config
错误对象
exception
2、EL表达式
2.1、EL简介
什么是EL表达式?
EL即Expression Language(表达式语言)
EL表达式的作用
替代 JSP 页面中复杂的 Java 代码
EL表达式的特点
类型自动转换,类型的限制更加宽松
使用简单
EL语法
${变量名}
【例】
${username}
[ ]和点操作符
[] 操作符
获取对象属性:${ user[‘uname’] }
从集合中通过下标获取数据:${ users[1].uname }
点操作符
获取对象属性: ${ user.uname }
2.2、EL的四大作用域
pageContext 变量只在定义的页面上有效(默认值)
request 变量在一个请求中有效,即变量的值可以从一个页面传到下一个页面(代表同一个对象)
session 在整个会话中有效,可跨越多个界面(代表一次会话)
application 由于在服务器端,所以此作用域是整个系统(代表一个用户)
范围:
page < request < session < application
查找作用域数据顺序
pageContext(第一)–> request(第二)–>session(第三)–>application(第四)
指定查找方式
{pageScope.键名}
{requestScope.键名}
{sessionScope.键名}
{applicationScope.键名}
2.3、EL隐式对象
EL 表达式通过隐式对象可以更加方便,精准的查找数据
作用域访问对象
pageScope
requestScope
sessionScope
applicationScope
参数访问对象
param
paramValues
JSP隐式对象
pageContext
3、JSTL
3.1、JSTL简介
JSTL全称:(JavaServerPages Standard Tag Library)JSP标准标签库
JSTL 是一个JSP标签集合,它封装了JSP应用的通用核心功能
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。
JSTL 还提供了一个框架来使用集成JSTL的自定义标签
JSTL的优点
提供一组标准标签
可用于编写各种动态 JSP 页面
3.2、JSTL环境搭建
下载jar包
1. 从官方下载:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
2. Maven 下载
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
引入标签库
在 JSP 页面中,引入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3.3、JSTL标签分类
JSTL核心库core
通用标签:
set
【作用】将数据存储到指定的作用域中,默认作用域为 pageContext
【例】<c:set value="要新增数据的值" var="要新增数据的键" scope="作用域名"></c:set>
out
【作用】结合 EL表达式 将数据响应给浏览器
如果 value 中值为空,则返回 default 中的默认值
【例】<c:out value="" defalut=""></c:out>
remove
【作用】删除作用域中的数据,默认是删除四个作用域中的符合的数据
可以通过 scope 删除指定作用域的数据。
【例】<c:remove var="要删除数据的键名" scope="作用域名" ></c:remove>
流程控制标签:
if
【例】<c:if test="条件"></c:if>
choose:
【例】<c:chooose>
<c:when test="${表达式}">
执行语句
</c:when>
..
<c:otherwise>
执行语句
</c:otherwise>
</c:chooose>
循环标签:
forEach
【例】格式一:<c:forEach begin="0" end="6" step="1" varStatus="i">
循环体
</c:foreach>
格式二:<c:forEach items="${list}" var="i">
循环体
</c:forEach>
4、Internet Media Type
Internet Media Type,即互联网媒体类型,也叫做于MIME类型,有时在一些协议的消息头中叫做“Content-Type”。
常见的媒体格式类型
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
以application开头的媒体格式类型
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
5、文件上传
5.1、文件上传类型
enctype 默认类型为:application/x-www-form-urlencoded。只处理表单域中的value属性值,采用这种编码的方式的表单会将表单域的值处理成url编码方式。
multipart/form-data:需要在表单中进行文件上传时,就需要使用该格式.这种编码方式的表单会以二进制流的方法来处理表单数据,会将文件域指定文件的内容也封装到请求参数里。
表单的设置
<form id="form1" method="post" action="upload" enctype="multipart/form-data">
</form>
添加jar包
commons-io
commons-fileupload ( 依赖 io 包 ,所以2个都需要引用 )
使用的API
DiskFileItemFactory
ServletFileUpload
FileItem
【实例】
// 检查请求是否是 multipart/form-data类型
if (!ServletFileUpload.isMultipartContent(req)) {
throw new RuntimeException("表单的enctype属性不是multipart/form-data类型!");
}
// 设置环境:创建一个DiskFileItemFactory 工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory); // 解析器依赖于工厂
// 创建容器来接受解析的内容
List<FileItem> items = new ArrayList<FileItem>();
// 将上传的文件信息放入容器中
try {
items = sfu.parseRequest(req);
} catch (FileUploadException e) {
e.printStackTrace();
}
// 遍历容器,处理解析的内容
for (FileItem item : items) {
if (item.isFormField()) {
String fieldName = item.getFieldName(); //得到表单域的name的值
String value = item.getString("utf-8"); //得到普通表单域中所输入的值
System.out.println("fieldName:"+fieldName+"--value:"+value);
} else {
String path = this.getServletContext().getRealPath("/files");
File childDirectory = new File(path); //创建子目录
String fileName = item.getName(); //得到上传文件的文件名
try {//写入服务器或者磁盘
item.write(new File(childDirectory.toString(),UUID.randomUUID()+"_"+fileName));
} catch (Exception e) {
e.printStackTrace();
}
}
}
6、文件下载
下载是通过 HttpServletResponse 对象设置响应头部的信息来达成的
1、Web容器为Servlet生成并且传递的HttpServletResponse对象不仅可以返回HTML文本,而且可以返回任何主流的其他文件格式,如:doc、pdf、avi等内容格式的文件
2、content-type 向浏览器指明有效负载区里的内容是什么类型的。
3、设置HTTP协议响应消息消息头部的属性,使用 response.setHeader()
设置浏览器进行文件下载
Content-Type:服务器告诉浏览器它发送的数据属于什么文件类型
Content-Disposition:其类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型
下载示例
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
String serverPath = request.getSession().getServletContext().getRealPath("");
String filename = request.getParameter("filename");
File f = new File( serverPath+"/files/"+ filename );
if( f.exists() ){
FileInputStream fis = new FileInputStream(f);
byte[] b = new byte[fis.available()];
fis.read(b);
response.setHeader("Content-Type","application/msword"); // 设置文件类型
response.setHeader("Content-Disposition","attachment; filename="+filename );
ServletOutputStream out =response.getOutputStream();
out.write(b);
out.flush();
out.close();
fis.close();
}
}