Servlet和JSP学习总结

目录

  1. Jsp会被编译成servlet,在页面被第一次访问的时候
  2. Jsp中可以在html页面中嵌入java代码或者引入jsp标签
  3. 可以在html中引入自定义标签
  4. Web工程的目录结构
  5. Jsp的注释
  6. Jsp声明部分
  7. Jsp输出表达式
  8. Jsp脚本
  9. Jsp的三个编译命令
  10. B/S结构
  11. 九大内置对象
  12. Servlet的缺点
  13. servlet的编写步骤
  14. Servlet与Jsp的区别
  15. Servlet与Jsp的生命周期
  16. 自定义标签
  17. Filter的使用
  18. Listener的使用
1. Jsp会被编译成servlet,在页面被第一次访问的时候
2. Jsp中可以在html页面中嵌入java代码或者引入jsp标签
3. 可以在html中引入自定义标签
4. Web工程的目录结构
<webDemo> --工程名称
|--WEB-INFO
|   |-- classes
|   |--lib
|   |--web.xml
|--a.jsp
5. Jsp的注释
<%-- --%> 这种注释在浏览器中查看源码时看不见
<!-- --> 这种注释在浏览器中点击查看源码时看见注释中的内容
6. Jsp声明部分

声明变量或者方法,转换为Servlet后对应的是成员变量和成员方法。

<%! 
public int a;
public int add(a, b){
    return a + b;
}
%>
7. Jsp输出表达式
<%=a %>
<%=add(1,2) %>
8. Jsp脚本
<table>
<%
for(int i=0; i<10; i++){
%>
    <tr><td>循环值</td><td><%=i %></td></tr>
<%
}
%>
</table>
9. Jsp的三个编译命令

编译指令的格式如下

<%@ 编译指令 属性名=”属性值” %>

编译指令为:

page

include

taglib

编译指令都有默认值,不需要为每一个指令设置值。

  • page指令
%@ page language="java"
   extends=""//指定此jsp编译成servlet继承的类
   import="package1","package2",……,"packagen"//导入页面需要的包
   session="true|false"//指定页面是否需要session
   pageEncoding="utf-8"//指定生成网页的编码字符集
%>
  • include指令
  • taglib指令
10. B/S结构

B/S也即Browser/Server

B完成的功能为:

  1. 向远程服务器发送请求
  2. 读取远程服务器返回的字符串数据
  3. 根据远程服务器返回的字符串渲染出一个web页面

S完成的功能为:

  1. 启动单独的线程
  2. 使用I/O流读取用户的请求数据
  3. 从请求数据中简析参数
  4. 处理用户请求
  5. 生成响应数据
  6. 使用I/O流向客户端发送请求数据

上面步骤中1、2、6由服务器完成,3、4、5由用户编码完成。

11. 九大内置对象
  • application
  • config
  • excaption
  • page
  • pageContext
  • request
  • session
  • out
  • response

作用域对象

  application、session、request、page
  application、session、request和pageContext 4个对象分别用于操作application、session、request和page范围内存的数据。

application

  application中的数据的作用范围是从第一次创建该数据开始,在应用的整个生命周期中有效,并且在所有jsp和servlet中都可以访问。

setAttribute(String name, String value);
getAttribute(String name)

pageContext

  pageContext对象可以获取application、session、request、page 4个范围内的数据,使用的是如下两个方法:

getAttribute(String name);
getAttribute(String name, int scope);
//scope的值为如下:
PageContext.PAGE_SCOPE
PageContext.REQUEST_SCOPE
PageContext.SESSION_SCOPE
PageContext.APPLICATION_SCOPE

  同样也提供了两个set方法来向这4个范围设置属性值。

setAttribute(String name,String value);
setAttribute(String name, String value, int scope);

request

  request包含了用户的一次请求的所有数据,包括请求头和用户设置的参数。
获取用户设置的参数信息:

String getParamater(String name);//获取参数name对应的值
Map getParamaterMap();//获取所有参数的名称和值组成的Map对象
Enumeration getParamaterNames();//获取所有参数的名称组成的枚举对象
String[] getParamaterValues(String name);//一个参数有多个值,返回该参数所有的值组成的数组

  获取用户请求头信息:

String getHadder(String name);//获取指定请求头的值
Enumeration<String> getHadderNames();//获取请求头的所有名称
Enumeration<String> getHadderNames(String name);//获取指定请求头的多个值
int getIntHadder(String name);//获取指定请求头的值,并将该值转化为整数

  操作request范围内的属性:

setAttribute(String attName, Object attValue);
Object getAttribute(String attName);//获取request范围内的属性

get与post的区别:

请求方式 发起方式 表现效果 数据传输量
get 在浏览器地址栏直接输入网址,或者form表单没有设置method属性,或者form表单的method属性设置为get。 在浏览器地址栏将请求参数以key=valued的方式显示在地址后面 一般不超过2KB
post form表单中的method属性设置为post 在浏览器地址栏中不会显示key=value的方式 一般认为不受限制,取决于服务器。
**response**
  response是一个输出对象,跟out对象功能相似。不同的是out对象是JspWriter的实例,JspWriter是Writer的子类。Writer是字符流,无法输出非字符类容。如果需要输出字节流(Excel,位图,PDF等),out无法完成,但是response可以完成。

  response作用之重定向:

<% response.sendRedirect(“target.jsp”); %>

请求转发和重定向的区别:

请求转发(forward) 重定向(redirect)
执行forward后依然是上一次请求 执行redirect后生产第二次请求
forword后的页面可以访问原请求的请求参数,因为是同一次请求,所有原请求的请求参数、request范围内的所有属性都存在 redirect后的页面不能访问原请求的请求参数,因为是第二次请求,所有原请求的请求参数、request范围内的所有属性都丢失
地址栏中的请求URL不会变化 地址栏改为重定向的目标URL,相当于在浏览器的地址栏输入新的URL按回车键

response作用之增加Cookie:

在浏览器设置为运行Cookie写入的情况下

<%
String userName = request.getParamater(“name”);
Cookie c = New Cookie(“userName”, userName);
c.setMaxAge(24*3600);
response.addCookie(c);
%>

request有一个获取Cookie的方法

<%
Cookie[] cs = request.getCookies();
for(Cookie c : cs){
	if(c.getName.equals(“userName”)){
		out.println(c.getValue());
    }
}
%>

session

  session是一次会话,一次会话的含义是:用户连接服务器开始,到用户连接服务器结束。session中的属性在一次会话中有效,不管一次会话执行了多少次的请求转发或者重定向,session中的属性都有效,直到改会话结束,所有的属性就失效。

12. Servlet的缺点

  如果使用servlet来开发html页面,需要在java代码中编写大量的html标签,通过servlet的输出流输出到页面,这样开发效率很低。

  后来servlet主要在MVC模式中演变为控制器。

13. Servlet的编写步骤

  编写普通java类,继承HttpServlet类,重写一下两个方法:

doGet(HttpServletRequest request, HttpServletResponse response)
doPost(HttpServletRequest request, HttpServletResponse response)

  HttpServlet还包括以下以前方法:

doPut(HttpServletRequest request, HttpServletResponse response);
doDelete(HttpServletRequest request, HttpServletResponse response);
init(ServletConfig config);
destroy();
14. Servlet与Jsp的区别

  (1)Servlet没有内置对象,原来Jsp中的对象对必须由程序显示创建。

  (2)对应静态的HTML标签,Servlet都必须使用页面输出流进行输出。

15. Servlet与Jsp的生命周期

  Servlet实例的创建时机:

  (1)系统第一次访问某个Servlet时,系统创建改Servlet的实例。

  (2)系统启动是立即创建Servlet的实例,及load-on-startup Servlet

  Servlet的生命周期:

graph LR
创建实例成功-->完成初始化
完成初始化-->响应客户请求
响应客户请求-->资源回收完成
资源回收完成-->实例被销毁

  系统完成Servlet的初始化后,Servlet将一直存在于容器中。

16. 自定义标签

(1)编写标签类

  编写没有任何标签属性的标签类

package cn.com.starit.tag;

import java.io.IOException;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class HelloWorldTag extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		this.getJspContext().getOut().write("hello world " + new Date());
	}

}

  编写带有标签属性的标签类

package cn.com.starit.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class PagingTag extends SimpleTagSupport {

	private String currPage;  //当前页
	private String countPage; //每页多少条
	public String getCurrPage() {
		return currPage;
	}
	public void setCurrPage(String currPage) {
		this.currPage = currPage;
	}	
	public String getCountPage() {
		return countPage;
	}
	public void setCountPage(String countPage) {
		this.countPage = countPage;
	}
	@Override
	public void doTag() throws JspException, IOException {
		JspWriter out = this.getJspContext().getOut();
		out.write("<div> ");
		out.write("<button>&lt&lt</button> ");
		out.write("<button>&lt</button> ");
		out.write("······ ");
		int currPageI = Integer.parseInt(currPage);
		if(currPageI == 1) {
			out.write("<button style=\"background-color: #7ED321;color: #FFFFFF\">1</button> ");
			out.write("<button>2</button> ");
			out.write("<button>3</button> ");
			out.write("<button>4</button> ");
			out.write("<button>5</button> ");
		}
		if(currPageI == 2) {
			out.write("<button>1</button> ");
			out.write("<button style=\"background-color: #7ED321;color: #FFFFFF\">2</button> ");
			out.write("<button>3</button> ");
			out.write("<button>4</button> ");
			out.write("<button>5</button> ");
		}
		if(currPageI >= 3) {
			out.write("<button>"+(currPageI-2)+"</button> ");
			out.write("<button>"+(currPageI-1)+"</button> ");
			out.write("<button  style=\"background-color: #7ED321;color: #FFFFFF\">"+currPageI+"</button> ");
			out.write("<button>"+(currPageI+1)+"</button> ");
			out.write("<button>"+(currPageI+2)+"</button> ");
		}
		out.write("······ ");
		out.write("<button>&gt</button> ");
		out.write("<button>&gt&gt</button> ");
		out.write("每页<select> ");
		int countPageI = Integer.parseInt(countPage);
		if(countPageI == 1000) {
			out.write("<option value=\"1000\" selected>1000</option> ");
		} else {
			out.write("<option value=\"1000\" >1000</option> ");
		}
		if(countPageI == 100) {
			out.write("<option value=\"100\" selected>100</option> ");
		} else {
			out.write("<option value=\"100\" >100</option> ");
		}
		if(countPageI == 50) {
			out.write("<option value=\"50\" selected>50</option> ");
		} else {
			out.write("<option value=\"50\" >50</option> ");
		}
		if(countPageI == 30) {
			out.write("<option value=\"30\" selected>30</option> ");
		} else {
			out.write("<option value=\"30\" >30</option> ");
		}
		if(countPageI == 20) {
			out.write("<option value=\"20\" selected>20</option> ");
		} else {
			out.write("<option value=\"20\" >20</option> ");
		}
		if(countPageI == 10) {
			out.write("<option value=\"10\" selected>10</option> ");
		} else {
			out.write("<option value=\"10\" >10</option> ");
		}
		out.write("</select>条 ");
	
	}

}

(2)编写tld文件

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>mytaglib</short-name>
    <uri>http://passport.kdgcsoft.com/mytaglib</uri>
    <tag>
        <description>Outputs Hello, World</description>
        <name>helloWorld</name>
        <tag-class>cn.com.starit.tag.HelloWorldTag</tag-class>
        <body-content>empty</body-content>
    </tag>
    <tag>
    	<description>Construct Paging Tag</description>
    	<name>paging</name>
    	<tag-class>cn.com.starit.tag.PagingTag</tag-class>
    	<body-content>empty</body-content>
    	<attribute>
    		<name>currPage</name>
    		<required>true</required>
    		<fragment>true</fragment>
    	</attribute>
    	<attribute>
    		<name>countPage</name>
    		<required>true</required>
    		<fragment>true</fragment>
    	</attribute>
    </tag>
</taglib>

(3)在jsp页面中通过 taglib标签引入

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://passport.kdgcsoft.com/mytaglib" prefix="mytag" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2><mytag:helloWorld/></h2>
<mytag:paging currPage="5" countPage="100"/>
</body>
</html>
17. Filter的使用

  Filter有如下几个用处:

  • 在HttpServletRequest到达Servlet之前,拦截HttpServletRequest,请求。
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
  • 在HttpServletResponse到达客户之前,连接HttpServletResponse请求。
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

Filter有如下几个种类:

  • 用户授权的Filter,Filter专门用户检查用户情况,过滤不合法的用户请求。
  • 日志Filter,详细记录模型特殊用户的请求日志。
  • 负责解码的Filter,包括对非标准编码的请求解码。

创建Filter的步骤

(1)创建Filter类

  创建Filter类必须实现Filter接口,在Filter接口中定义了如下三个方法:

init(FilterConfig config)//初始化Filter
destroy()//销毁Filter前回收资源
doFilter(ServletRequest request, ServletResponse response, FilterChain chain);//实现过滤功能

  以下是一个Filter类

package cn.com.starit.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
 * 记录请求日志
 */
public class MyFilter implements Filter{

	private FilterConfig config;
	
	@Override
	public void destroy() {
		this.config = null;
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		ServletContext servletContext = this.config.getServletContext();
		HttpServletRequest hrequest = (HttpServletRequest)request;
		System.out.println("开始过滤......");
		System.out.println("已经截获到用户的请求地址"+hrequest.getServletPath());
		chain.doFilter(request, response);
		System.out.println("过滤结束");
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		this.config = config;
	}

}

(1)配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>test_web</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>TestServlet</servlet-name>
  	<servlet-class>cn.com.starit.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>TestServlet</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  
  <!-- 配置myFilter过滤器 -->
  <filter>
  	<filter-name>myFilter</filter-name>
  	<filter-class>cn.com.starit.filter.MyFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>myFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>
18. Listener的使用

  当web应用在web容器中不断的运行时,web容器内部不断的发送各种事件,如web应用被启动,web应用被停止,用户session开启,用户session结束,用户请求到达等。

  Servlet API提供了大量的监听器来监听web应用内部的事件。从而允许当事件发送时可以回调监听器的方法。

创建Listener的步骤:

(1)定义Listener实现类

(2)在web.xml中配置Listener

常用的web监听器事件:

ServletContextListener用于监听web应用的启动和关闭
ServletContextAttributeListener用于监听ServletContext范围内(application)属性的改变
ServletRequestListener用于监听用户的请求
ServletRequestAttributeListener用于监听ServletRequest范围内(request)属性的改变
HttpSessionListener用户监听用户session的开始和结束
HttpSessionAttributeListener用于监听用户HttpSession范围内(session)属性的改变

下面以ServletContextListener创建一个实例

package cn.com.starit.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener{

	@Override
	public void contextDestroyed(ServletContextEvent event) {
		System.out.println("关闭应用之前调用这里......");
	}

	@Override
	public void contextInitialized(ServletContextEvent event) {
		System.out.println("启动应用前调用这里......");
	}

}

在web.xml中配置Listener

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>test_web</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>TestServlet</servlet-name>
  	<servlet-class>cn.com.starit.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>TestServlet</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  
  <!-- 这里是过滤器配置 -->
  <filter>
  	<filter-name>myFilter</filter-name>
  	<filter-class>cn.com.starit.filter.MyFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>myFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- 这里是监听器定义 -->
  <listener>
  	<listener-class>cn.com.starit.listener.MyListener</listener-class>
  </listener>
    
</web-app>
19. JSP中的输出表达式

  输出表达式定义:

${  }

可以输出pageScope、requestScope、sessionScope、applicationScope是个作用域的值。如下:

${pageScope.name }
${requestScope.name }
${sessionScope.name }
${applicationAcope.name }
posted @ 2019-10-26 14:29  东临碣石,以观沧海  阅读(342)  评论(0编辑  收藏  举报