目录
如何创建web项目?
https://blog.csdn.net/u013393958/article/details/78329192
如何开发一个servlet程序?
- 编写java类,继承HttpServlet类
- 重写doGet和doPost方法
- Servlet程序交给tomcat服务器运行
- .class放入classes文件夹
- 配置web.xml配置文件
- servlet程序的目录结构。
tomcat是一个wed服务器,也可以说是一个小型的web容器
src为servlet源程序,主要写的是服务程序,之后交给tomcat运行。classes存放编译后的字节码文件,lib存放web应用程序需要的jar包。web下的html和jsp等文件属于静态资源。web.xml是这个web应用的配置文件,主要配置url-pattern到servlet-name的一个映射,再根据servlet-name找到servlet-class.
<?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">
<servlet>
<servlet-name>ResponseDemo1</servlet-name>
<servlet-class>c_response.ResponseDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResponseDemo1</servlet-name>
<url-pattern>/ResponseDemo1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo1</servlet-name>
<servlet-class>c_cookie.CookieDemo1</servlet-class>
</servlet>
- tomcat如何找到servlet程序?
tomcat启动时,首先加载webapps的配置文件,通过web.xml配置文件,根据url-pattern找到servlet-name,再通过servlet-name找到servlet-class。根据servlet.class可获得.class字节码,通过反射即可得到相关函数。
- url映射路径
精确匹配:http://localhost:8080/url <url-pattern> /url </url-pattern>
模糊匹配:
http://localhost:8080/(任意路径) <url-pattern> /*</url-pattern>(/*和/是一个意思)
http://localhost:8080/url_first/(任意路径) <url-pattern> /url_first/*</url-pattern>
http://localhost:8080/(任意路径).(do/action/html) <url-pattern> *.(do/action/html)</url-pattern>
注意:
- 要么/开头,要么以*开头,/url_first/*.do不可以
- 精确匹配优先,长得最像优先被匹配
- 以后缀名结尾的模糊匹配优先级最低
- servlet缺省路径
Servlet的缺省路径是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web引用的静态资源文件。
问题:URL输入http://localhost:8080/index.html时,tomcat如何读取文件?
- 到web文件夹下的web.xml中查找是否有匹配的url-pattern。
- 如果没有匹配的url-pattern,那么就交给DefaultSeevlet。
- 那么就去conf/web.xml中查找,如果找到该文件,则读取该文件内容。
- 如果找不到,则返回404
结论:先动态资源,再动态资源。
servlet的生命周期
servlet生命周期是指servlet从被web服务器加载到它被销毁的整个生命过程。
分为三个阶段:
- 初始化阶段,调用init()方法
- 相应客户请求阶段,调用service()方法
- 终止阶段,调用destory()方法
Web服务器加载Servlet:Web服务器启动后,它会根据每个工程的web.xml文件去查找该工程的Servlet,并且找到这些Servlet的Class文件所在的地址,将它们载入到Web容器中,不同的Servlet被Web容器加载的次序不同,通过web.xml文件可以配置每个Servlet载入的次序。一般来说,Servlet在服务器启动时就会被Web服务器加载,而JSP文件只有在用户访问到该页面时才会被动态载入。
创建一个Servlet实例:这时会调用该Servlet的构造函数去创建一个具体的对象。
经过以上的两个步骤后,这时如果有客户端请求,Web服务器就会调用Servlet对象的init()方法
接着Web服务器调用Servlet的service()方法去接收请求,处理请求,并把处理结果返回。
销毁:Servlet实例被销毁,这是通过调用Servlet的destory()方法来实现的。
- 伪代码实现servlet的生命周期
- 通过映射找到servlet-class的内容,即类全名的字符串 Try.Demo01
- 通过反射构造Demo01对象
得到字节码对象:
Class clazz = Class.forName(“Try.Demo01”);
调用无参数的构造方法来构造对象
Object obj = Clazz.newInstance();
创建Demo01对象,并通过反射调用init(ServletConfig);
得到方法对象:Method m = clazz.getDeclareMethod(“init”,ServletConfig.class);
调用方法:m.invoke(obj,config);
用service方法:
得到方法对象:Method m = clazz.getDeclareMethod(“service”,HttpServletRequest.class,HttpServletResponse.class);
调用该方法:m.invoke(obj,request,response);
调用destroy方法:
得到方法对象:Method m = clazz.getDeclaredMethod(“destroy”,null);//arg1:函数名 arg2:参数类
调用方法:m.invoke(obj,destroy)//arg1:调用对象 arg2:参数
- servlet的自动加载
默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问servlet的时候比较慢。
改变Servlet创建对象的时机,提前到加载web引用的时候。
解决方法:在servlet的配置信息中,加一个<load-on-startup>即可。按道理来说实在web.xml里面配置,在IDEA中可以用注解解决。<servlet><load-on-startup> n </load-on-startup></servlet>。数值越大,优先级越低。
- 两种init(),有参和无参
有参的init方法一定会被Tomcat服务器调用。
无参的init方法是给开发者用来覆盖的。
默认情况下,有参会调用无参的方法。一旦覆盖了父类的有参init且不用super,会导致无参的不会被调用。
- servlet在tomcat中是单例多线程的
- Servlet对象学习
- HttpServletRequest 请求对象:获取请求信息
- HttpServletResponse 响应对象:设置响应对象
- ServletConfig servlet配置对象
创建时机:在创建完servlet之后,在调用init之前创建ServletConfig对象。
得到对象:直接从有参的init方法中来 (this.config = config)
ServletConfig config = this.getServletConfig();String value = config.getInitParameter(name);
- ServletContext servlet的上下文对象(代表了整个web.xml)
创建市级:加载web应用时创建对象,且早于ServletConfig
得到对象:从ServletConfig对象中的getServletContext方法中得到
核心API:
java.lang.String getContextPath() --得到当前web应用的路径
java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()
void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
void removeAttribute(java.lang.String name)
RequestDispatcher getRequestDispatcher(java.lang.String path) --转发(类似于重定向)
java.lang.String getRealPath(java.lang.String path) --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path)
- 作用
1.java.lang.String getContextPath()
response.sendRedirect(contextpath+"/testimgs.html");
获得当前webapp的名字,比如http://localhost:9090/test/demo01 /test就是context,因此可以作为重定向的url
2.java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()
context中的数据相当于是web.xml。相当于是一个全局的,所有/test下的servlet应用(classes文件夹中的class)共享一个web.xml,因此说是全局的。
<context-param>无法通过注解实现,必须在web.xml中手动添加。
3.void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
void removeAttribute(java.lang.String name)
域对象:作用是用于保存数据,获取数据。可以再不同的动态资源之间共享数据。
举例而言:在不同servlet之间共享不同类型的数据。
域对象就是一个容器/中介。ServletContext就是一个域对象,本质是因为ServletContext是全局的,一个应用仅有一个,所有Servlet公用一个,因此可以实现这个效果。
保存数据:setAttribute 获取数据:getAttribute 删除数据:removeAttribute
预告:
HttpServletRequest ServletContext HttpSession PageContext 域对象
4.RequestDispatcher getRequestDispatcher(java.lang.String path) --转发(类似于重定向)
转发的效果类似重定向,但是转发不会改变地址栏的url
1)转发
a)地址栏不会改变
b)转发只能转发到当前web应用内的资源
解释:(1:http://localhost:9090/test/demo01 2:http://localhost:9090/test_2/demo01_2)
test中不能通过转发到2,但是重定向可以。
c)可以在转发过程中,可以把数据保存到request域对象中
解释:本质上转发用的forward(request,reponse)的request和servlet里面的request是同一个,因此request所承载的数据是可以传递的。但是对于重定向而言,是响应一个302+location,直接跳转到另一个页面,request根本就是两个东西。
2)重定向
a)地址栏会改变,变成重定向到地址。
b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。
c)不能再重定向的过程,把数据保存到request中。