servlet 执行顺序
public class TestServelt { public static void main(String[] args) {
ChildServlet childServlet = new ChildServlet();
childServlet.service();
} } class FatherServlet{ public void service(){
System.out.println("父类service");
doGet(); }
public void doGet(){
System.out.println("父类goGet");
} } class ChildServlet extends FatherServlet{ public void service(){
System.out.println("子类service");
super.service(); }
public void doGet(){
System.out.println("子类goGet");
} }
1、初始化阶段 调用init()方法
2、响应客户请求阶段。调用service()方法,由service()方法根据提交的方式选择执行doGet()或者doPost()方法
3、终止阶段 调用destroy()方法--关闭tomcat的时候
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.myServlet</servlet-class>
<load-on-startup>1</load-on-startup> 启动tomcat的时候初始化当前servlet 调用init,数字越小越先加载
</servlet>
<context-param>
<param-name>context/param</param-name>
<param-value>avalible during application</param-value>
</context-param>
参数通过getServletContext().getInitParameter("context/param")获取
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>com.wes.controller.MainServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>avalible in servlet init()</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
只能在servlet的init()方法中通过this.getInitParameter("param1")获取
Servlet不是线程安全的。 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。 当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。 上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。 比如下面的Servlet中的 name 和 i变量就会引发线程安全问题。 import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; public class ThreadSafeServlet extends HttpServlet { public static String name = "Hello"; //静态变量,可能发生线程安全问题
int i; //实例变量,可能发生线程安全问题
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); @Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet初始化");
} @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.printf("%s:%s[%s]\n", Thread.currentThread().getName(), i, format.format(new Date()));
i++;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s:%s[%s]\n", Thread.currentThread().getName(), i, format.format(new Date()));
resp.getWriter().println("<html><body><h1>" + i + "</h1></body></html>");
}
} 在Tomcat中启动这个Servlet并在浏览器发起多个HTTP访问,最后会发现变量 i 是多线程共享的。 如果需要更加深入透彻地了解Tomcat接收HTTP的细节,以及与Servlet交互的细节,可以深入看看Tomcat的架构和源码。 jsp 9大内置对象 1.request对象
2.response对象
3.session对象
4.out对象
- out对象是JspWriter类的实例,是向客户端输出内容常用的对象
5.page对象
- page对象就是指向当前JSP页面本身,有点象类中的this指针,它是
- java.lang.Object类的实例
- 序号方法说明
- classgetClass 返回此Object的类
- inthashCode() 返回此Object的hash码
- booleanequals(Objectobj) 判断此Object是否与指定的Object对象相等
- voidcopy(Objectobj) 把此Object拷贝到指定的Object对象中
- Objectclone() 克隆此Object对象
- StringtoString() 把此Object对象转换成String类的对象
- voidnotify() 唤醒一个等待的线程
- voidnotifyAll() 唤醒所有等待的线程
- voidwait(inttimeout) 使一个线程处于等待直到timeout结束或被唤醒
- voidwait() 使一个线程处于等待直到被唤醒
- voidenterMonitor() 对Object加锁
- voidexitMonitor() 对Object开锁
6.application对象
application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器
的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前
后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何
地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和
关闭决定了application对象的生命。它是ServletContext类的实例。
7.exception对象
exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产
生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,
否则无法编译。他实际上是Java.lang.Throwable的对象
8.pageContext对象
pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是
说他可以访问到本页所在的SESSION,也可以取本页面所在的application的
某一属性值,他相当于页面中所有功能的集大成者,它的本类名也叫
pageContext。
9.config对象
config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
HttpSession
是基于Cookie 实现的
HttpSession的创建时间
jsp中 显示调用时会创建session
servlet 中调用 request.getSession时会创建session
自定义标签
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1"> <description>testjsp 1.1 core library</description>
<display-name>testjsp core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>testjsp</short-name>
<uri>http://tj.com/testjsp</uri> <tag>
<!-- 描述 HelloSimpleTag的名称-->
<name>hello</name>
<tag-class>com.tag.TestJspFragment</tag-class>
<body-content>scriptless</body-content> <attribute>
<name>value</name>
<!-- 是否必须 -->
<required>true</required>
<!-- 是否支持EL表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute> <!-- 标签体 -->
<!-- 没有标签体 -->
<!-- <body-content>empty</body-content> -->
<!-- 不经过处理直接把内容交给标签处理器类 -->
<!-- <body-content>tagdependent</body-content> --> <!-- 可以有EL${} 不可以有<%=%> 大部分情况下取值为scriptless-->
<body-content>scriptless</body-content> </tag>
</taglib> public class TestJspFragment extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
//当定义标签体的时候会调用setJspBody(JspFragment arg0) {
//把JspFragment传递过来
JspFragment fragment = getJspBody();
StringWriter sw = new StringWriter();
//若为NULL输出到页面 等同于fragment.invoke(getJspContext().getOut());
fragment.invoke(sw);
//把内容写到sw中
String content = sw.toString().toUpperCase();
//把内容转换成大写写入到页面
getJspContext().getOut().print(content);
} } //InputStream inputStream = pageContext.getServletContext().getResourceAsStream("src");//根路径 //如果有标签体就会调用此方法,把JspFragment传过来
public void setJspBody(JspFragment arg0) {
System.out.println("setJspBody");
} public void setParent(JspTag arg0) {
//父标签获取不到子标签,子标签可以获取到父标签的引用
System.out.println("setParent");
//arg0指的就是父标签的引用,需要强转
}
/*Cookie cookie = new Cookie("name", "aaaa");
//cookie 的作用范围默认为当前文件路径的子目录
cookie.setPath("/");//站点的根目录
cookie.setMaxAge(30);//最大秒数,存在磁盘对应当前浏览器,同一个站点最多存20个cookie,每个cookie最大4k //客户端第一请求时 服务端给客户端返回一个cookie 在请求头中set-cookie
//第二次客户端访问服务端会带着cookie
response.addCookie(cookie);*/ //response.encodeURL("session/a.jsp"); response.encodeUrl("session/a.jsp");//实现URL的重写,在后边加上;jeesessionid=331232131321 //服务端获取客户端cookie /*Cookie []cookies = request.getCookies(); if(cookies!=null){ for (Cookie coo : cookies) {
System.out.println(coo.getName()+":"+coo.getValue());
} }*/
//http://localhost:8080/spring1/IndexServlet
String method = request.getServletPath();//IndexServlet try {
Method me = getClass().getDeclaredMethod("add", request.getClass(),response.getClass());
me.invoke(this, request,response);
//cs.getDeclaredMethod("add", null).invoke(this, null);
} catch (Exception e) {
e.printStackTrace();
}
自定义标签函数
之前例子已经写好了,由于时间关系一直没有发布,这次带来的是关于taglib中的<tag>的基本功能已经介绍完毕了,在taglib中我们发现有一个标签叫做<function>,这次简单介绍<function>标签的基本用法,<function>标签可以做什么呢?它可以让我们在jsp用直接调用某个方法,根据自定义的方法返回指定的值,兼容jstl标签,省去了在jsp中直接使用<%!%>来定义方法体再调用的繁琐.如果你用过el语言的话估计会很快上手,其实<function>标签就是一个拥有方法体的el语言.注意:function所定义的方法必须需要是静态的,如果不是静态的话jstl是不能识别所定义的方法.
Java代码如下:
package org.lxh.taglib; import java.util.List; public class FunctionTag { public static String hello(String name) { return name;
} public static Integer bbq(List list) { return list.size();
}
}
方法必须静态,可以定义有返回值或者void类型的方法.
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">
<tlib-version>1.0</tlib-version>
<short-name>my</short-name>
<uri>http://lauedward.spaces.live.com</uri>
<function>
<!--EL页面调用名字-->
<name>hello</name>
<!--指定标签的处理类,指定了标签由哪个Java类来处理。-->
<function-class>org.lxh.taglib.FunctionTag</function-class>
<!--指定EL页面调用名字中实际调用的方法.指定处理类的实际方法.参数和回调函数要写完整路径-->
<function-signature>java.lang.String hello(java.lang.String)</function-signature> </function> <function>
<name>bbq</name>
<function-class>org.lxh.taglib.FunctionTag</function-class>
<function-signature>java.lang.Integer bbq(java.util.List)</function-signature>
</function>
</taglib>
注意:在<function-signature>需要写完整的类名,假如是String类型的话就必须写java.lang.String这样字,不支持泛型的定义如java.util.List<java.lang.String>eclipse会把<>当作xml的格式来判断的,所以就省略该泛型的定义.
jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="my" uri="/WEB-INF/tld/testFunction.tld"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.util.*"%><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
List<String> list = new ArrayList<String>();
list.add("aa");
list.add("bb");
list.add("cc");
request.setAttribute("list", "helloword");
request.setAttribute("name", list);
Map map = new HashMap();
map.put("1","a");
map.put("2","b");
map.put("3","c");
map.put("4","d");
%>
<br>
${my:hello(list)}
<br>
${my:bbq(name)}
<br>
</body>
</html>
注意:调用方法的时候必须类型要传入相同类型的值,否则的话会报错,不过对于方法体是String的话,是可以传入list,set,map那些,因为传入后会直接调用list的.toString()方法直接当字符串输出.
HttpSessionListener
HttpSessionAttributeListener
ServletContextListener
web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。
servlet 执行顺序的更多相关文章
- web.xml中多个Servlet执行顺序的问题!
1.两个servlet或者两个servlet-mapping,其中的servlet-name名称不能存在相同. 2.所有的servlet-mapping标签下,url-pattern中包含的文本不能相 ...
- Servlet 3.0 之@WebFilter怎么控制多个filter的执行顺序
之前我们控制多个filter的执行顺序是通过web.xml中控制filter的位置来控制的,放在上面的会比放在下面的先执行,如下“用户登录检查过滤器”会比“接口日志过滤器”先执行 <!-- ...
- web项目中的监听器,过滤器以及自定义servlet的执行顺序
可以看到web容器一启动就会实例化监听器的contextInitialized(ServletContextEvent event)方法,然后是过滤器的init()方法,最后在用户访问web应用的 时 ...
- filter、servlet、interceptor的执行顺序
1. Filter可认为是Servlet的一种“变种”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链.它与Servlet的区别在于:它不能 ...
- 简单理解Struts2中拦截器与过滤器的区别及执行顺序
简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...
- netty4 Handler的执行顺序
转载:https://my.oschina.net/jamaly/blog/272385 Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet中的filter很像,通 ...
- filter的执行顺序
一直没有仔细去研究下filter ,最近系统的测试了下: 先看代码吧 FirstFilter.java ================== package com.test.filter; impo ...
- java 过滤器Filter中chain.doFilter()之前和之后代码的执行顺序
过滤器拦截到响应url的请求后会先执行doFilter()方法中chain.doFilter()之前的代码,然后执行下一个过滤器或者servelt.紧接着执行chain.doFilter()之后的代码 ...
- 04_过滤器Filter_03_多个Filter的执行顺序
[Filter链] *在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链. *web服务器根据Filter在web.xml中的注册顺序,决定先调用哪个Fi ...
随机推荐
- Linux-task_struct和文件系统及管道的关系
推荐:文件描述符和文件指针的关系 fs_struct 记录该进程所在文件系统等信息. files_struct 记录该进程当前打开的所有文件等信息,其中有一个元素为数组,数组索引是文件描述符,数组元素 ...
- Docker入门 - 003 Docker 实例
Docker Hello World Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序. 输出Hello world runoob@runoob: ...
- 自建证书配置HTTPS服务器
1.写这篇博客的初衷是因为最近iOS9出来了,苹果官方默认要求使用HTTPS,所以自己想整一个HTTPS服务器,也想好好了解一下HTTPS通信,也知道了HTTPS其实就是在HTTP的基础上加上了SSL ...
- Android 开发笔记
11.android使用全局变量 定义Data类继承Application 在manifest.xml中声明 http://blog.csdn.net/feiyangxiaomi/article/de ...
- 文档大师 在Win10 IE11下,文档集画面无法正常显示Word等Office文档的解决方法
在文档集界面中显示Word文档,是文档大师的一个核心功能. 最近在 Win10 升级到最新版后,发现 无法正常显示Office 文档的问题. 一开始以为是Word版本问题,从2007升级到2016,问 ...
- tensorflow 笔记14:tf.expand_dims和tf.squeeze函数
tf.expand_dims和tf.squeeze函数 一.tf.expand_dims() Function tf.expand_dims(input, axis=None, name=None, ...
- 【Java】Java8的Lambda入门记录
简化定义匿名实现类 匿名实现类的传统方式 创建一个线程,需要实现Runnable接口,并实现public void run()方法,用传统的方式是这样的: public static void mai ...
- Java编程的逻辑 (95) - Java 8的日期和时间API
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- android手机测试中如何查看内存泄露
(一) 生成.hprof文件生成.hprof 文件的方法有很多,而且Android 的不同版本中生成.hprof 的方式也稍有差别,我使用的版本的是2.1,各个版本中生成.prof 文件的方法请参考: ...
- SQL查看死锁+清理死锁
----查看sql死锁 CREATE procedure sp_who_lock as begin declare @spid int declare ...