Servlet全面详解(学习笔记)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值