Servlet全面详解(学习笔记)

时间:2025-04-02 09:24:48

文章目录

  • 一、Servlet
    • 1、Servlet简介
    • 2、Servlet原理
      • 2.1、Servlet体系结构
      • 2.2、Servlet生命周期
    • 3、HttpServlet应用
      • 3.1、HttpServletRequest
      • 3.2、HttpServletResponse
      • 3.3、编码格式设置
      • 3.4、forward和redirect区别
      • 3.5、Servlet配置
    • 4、Servlet应用例
      • 4.1、Servlet交互
      • 4.2、应用例
    • 5、Servlet会话跟踪技术
      • 5.1、URL重写
      • 5.2、隐藏表单域:
      • 5.3、Cookie
      • 5.4、session
      • 5.5、Cookie和session的区别
    • 6、Servlet过滤器
    • 7、监听器
  • 二、Java EE
    • 1、JSP页面技术
      • 1.1、JSP简介
      • 1.2、JSP执行过程
      • 1.3、JSP页面的基本构成
      • 1.4、动作指令
      • 1.5、内置对象
    • 2、EL表达式
      • 2.1、EL简介
      • 2.2、EL的四大作用域
      • 2.3、EL隐式对象
    • 3、JSTL
      • 3.1、JSTL简介
      • 3.2、JSTL环境搭建
      • 3.3、JSTL标签分类
    • 4、Internet Media Type
    • 5、文件上传
      • 5.1、文件上传类型
    • 6、文件下载

一、Servlet

1、Servlet简介

​ Servlet 是一个用 Java 编写的程序,此程序在服务器上运行以处理客户端请求。

Servlet优点

高效
    支持缓存和多线程
方便
    Servlet提供了大量的实用工具例程,例如自动地解析和解码HTML表单数
    据、读取和设置HTTP头、处理Cookie、跟踪会话状态等。
功能强大
     以Java API作为后盾
可移植性好
	用Java语言编写
	在服务器端运行

Servlet执行过程

1)客户端发送请求至服务器端;
2) 服务器遍历中url-pattern,找到 Servlet;
3)执行service()方法,service解析用户请求,匹配对应方法
4) Servlet方法 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
5) 服务器将响应返回给客户端;

2、Servlet原理

2.1、Servlet体系结构

ServletConfig 接口

​ 用来封装中对当前Servlet的配置信息

getInitParameter()---可以获取初始化参数


<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 做框架用
(“utf-8”) 设置http请求编码格式

3.2、HttpServletResponse

​ HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法

//用OutputStream(字节流)发送数据
().write(“中国”.getBytes("UTF-8")))//以UTF-8编码发送数据,浏览器(默认用GB2312)会														  出现乱码

Response应用

通过response实现请求重定向
	请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。

地址栏会变,并发送2次请求,增加服务器负担

实现方式:
	()

3.3、编码格式设置

请求参数的中文乱码问题
	解决:(“UTF-8”);//POST有效
	更改Tomcat的配置解决URL编码问题:<Connector URIEncoding=“UTF-8”/>

响应乱码
	通过设置响应头告知客户端编码方式:(“Content-type”, “text/html;charset=UTF-8”);
	("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></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  可替代中的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 = ("name").value;
            alert(val);
            val = encodeURI(val);
            alert(val);
            val = encodeURI(val);//浏览器解码一次,不再编码一次的话输出到控制台就是两次中文
            alert(val);
             = "B?name="+val;
        }
    </script>
</head>
<body>
    <input type="text" />
    <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>
    ${}:${}
    <hr/>
    <form action="" method="post">
        <input type="text" name="content" placeholder="请输入内容"/>
        <input type="hidden" name="name" value="${}"/><!--不再次转发的话会读不到-->
        <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("");
        }else{
            resp.sendRedirect("?error=1");
        }
    }
}

jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<c:if test="${==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分钟,可以通过在中手动设置超时时间:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="/xml/ns/javaee"
         xmlns:xsi="http:///2001/XMLSchema-instance"
         xsi:schemaLocation="/xml/ns/javaee /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方法,根据初始化参数的值判断该请求是否合法,如果请求不合法,则阻塞该请求;如果请求合法,		则调用方法将该请求向后传递

Servlet对响应的过滤过程

过滤器截获客户端的请求
重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流
将请求向后续传递
Web组件产生响应
从封装后的ServletResponse中获取用户自定义的输出流
将响应内容通过用户自定义的输出流写到缓冲流中
在缓冲流中修改响应的内容后清空缓冲流,输出响应内容

Servlet过滤器接口的构成

void  init(FilterConfig):过滤器的初始化方法,Servlet容器在创建过滤器实例时调用这个方法,在这个方法中可以读出在文件中为该过滤器配置的初始化参数。

void doFilter(ServletRequest,ServletResponse,FilterChain):用于完成实际的过滤操作,当客户请求访问与过滤器相关联的URL时,Servlet容器将先调用过滤器的这个方法,FilterChain参数用于访问后续过滤器。

void destroy():过滤器在被取消前执行这个方法,释放过滤器申请的资源

Servlet过滤器的创建步骤

 1.创建一个实现了接口的类。
 2.重写init(FilterConfig)方法,读入过滤器配置的初始化参数就。
 3.重写方法doFilter,完成过滤操作,从ServletRequest参数中得到全部的请求信息,从ServletResponse参数中得到全	部的响应信息。
 4.在doFilter()方法的最后,使用FilterChain参数的doFilter()方法将请求和响应后传。
 5.对响应的Servlet程序和JSP页面注册过滤器,部署文件()

过滤器类

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></filter-class>            
     <init-param>             
         <param-name>logonStrings</param-name>             
         <param-value></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>./</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()。
    

在中,使用来配置监听器

 <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="/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 (d);
		}
	%>
	你好,今天是
	<%=formatDate(new Date()) %>

1.4、动作指令

​ JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。

1、jsp:include动作

​ jsp:include动作指令表示在当前的JSP页面中,包含静态或动态资源

【例】
<jsp:include page="" flush="true"></jsp:include>

2、jsp:forward动过

​ jsp:forward动作用于将请求转发到另一个JSP、Servlet或者静态资源文件。

【例】
<%
	String username = ("xzl");
	String pwd = ("pwd");
	if(!"admin".equals(username)&&!"123".equals(pwd))
%>
	<jsp:forward page=""></jsp:forward>;
<%} else {%>
	<jsp:forward page=""></jsp:forward>
<%}%>
用户名为:<%=username%>
密码为:<%=pwd%>

3、jsp:param动作

​ jsp:param动作用于页面之间传递参数。在使用jsp:param动作时,必须配合jsp:include、jsp:forward动作使用

​ 注:param只能作为子标签使用

【例】
<jsp:include page="" flush="true">
    <jsp:param name="username" value="某某某"/>
    <jsp:param name="password" value="108"/>
</jsp:include>
用户名:<%=(“username”)%><br>
用户密码:<%=(“password”)%>

1.5、内置对象

​ JSP内置对象是可以直接在JSP页面使用的对象,无需使用“new”获取实例,不需要声明和实例化

【例】
<%
	String username = (“username”);
	String password = (“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
	【例】(输出数据):输出数据到页面
		 ();关闭输出流
	
作用域通信对象:
	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 }

点操作符
	获取对象属性: ${  }

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. 从官方下载:/dist/jakarta/taglibs/standard/binaries/

2. Maven 下载
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

引入标签库

在 JSP 页面中,引入标签库
<%@ taglib prefix="c" uri="/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  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协议响应消息消息头部的属性,使用 () 

设置浏览器进行文件下载

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();
    }     
}