servlet是我们学习的第一个动态资源
1、servlet干什么用的?
处理请求,生成响应
2、我们如何创建一个servlet呢?
1>我们只需实现servlet接口即可
2>继承javax.servlet.http.HttpServlet
3>继承javax.servlet.http.HttpServlet
3、Servlet的生命周期的方法
生命周期指的是,必须要经历的过程
1、出生===>init方法,在构造方法调用之后 调用
2、使命===>service方法,当请求发来时,处理请求使用
3、销毁===>destroy方法,当服务器关闭时,会小会servlet,在销毁之前调用该方法释放资源
生命周期:
1、浏览器发送请求
2、服务器分析请求,请求哪个主机哪个项目
3、查找项目下的web.xml是否存在 比如AServlet.java
4、如果是第一次访问,创建servlet实例
5、调用servlet中的init方法,将sevlet实例存储到内存中
6、调用service方法处理请求,将request和respons传递
7、将request和response还给服务器
8、服务器将response组装成http响应协议
9、将http响应协议发送给客户端
servlet中的其他方法
getServletInfo
4.Servlet中的其他方法.
getServletInfo ==> 获得servlet的信息(版本,作者,版权..),没用.
getServletConfig ==> 返回servletConfig对象.
5.ServletConfig对象是什么?
封装了servlet在web.xml中的配置.
方法:
1>getServletName ==> 获得配置文件中 <servlet-name> 元素的内容
2>getInitParameter ==> 根据 <init-param>中的 <param-name> 获得 </param-value>
<init-param>
<param-name>name</param-name>
<param-value>tom</param-value>
</init-param>
3>getInitParameterNames 返回所有<param-name> .
4>getServletContext(下午讲)
6.其他实现server的方式
GenericServlet:
1.帮我们妥善的保管ServletConfig对象
2.实现了ServletConfig接口 ==> 为调用方便
注意: 不要重写servlet接口中的 init方法. 不然 第一步优化就白做了.
我们要做初始化的动作,需要去重写GenericServlet提供的空参init方法.
HTTPServlet:
1.因为我们web项目基于HTTP协议,所以Service方法中传过来的request,response对象都是 基于HTTP协议的.
也就是HttpServletReueqst,也就是HttpServletResponse. 它帮我们进行了强转.
2.我们有可能在不同的请求方式时做不同的事情. 根据请求方式不同,调用不同的方法
例如 GET --> doGet()
POST ==> doPost();
7、Servlet中的其他细节
1>关于Servlet线程安全问题
因为在servlet运行期间只有一个servlet实例存在,可能会同时处理多个请求
那么我们在servlet中声明成员变量来存储用户数据是有线程安全问题的
我们应该如何解决呢?
1、实现SingleThroadModel(不推荐了)
2、使用局部变量保存用户数据(推荐使用)
2>关于servlet随着项目的启动而创建
使用<load-on-startup>配置来实现
例如:
<servlet>
<servlet-name>FServlet</servlet-name>
<servlet-class>my.servletlearn.thread.FServlet</servlet-class>
<load-on-startup>这里填写一个整数</load-on-startup>
</servlet>
整数越小优先级越高,启动顺序按照配置顺序,如果优先级一样,启动顺序按照配置顺序
3>关于Servlet路径配置问题详解
<url-pattern>
路径匹配:
/AServlet http://localhost:8080/MyWeb/FServlet
/ABC/AServlet http://localhost:8080/MyWeb/ABC/FServlet
/ABC/ABC/* http://localhost:8080/MyWeb/ABC/ABC/默认
/* http://localhost:8080/MyWeb/默认
/相当于/*
后缀名匹配:
*.do==>structs 1
*.action ==>structs 2
*.html==>
注意:1、关于路径。配置的路径范围越大优先级越低
2、两种匹配模式不能混用,例如错误的例子: /*.do
4>关于tomcat目录下的web.xml
1、default servlet的配置 404
2、jsp servlet的配置
3、<session-config>
<session-timeout>30</session-timeout>
</session-config>
4、互联网中所有的mime类型
5、欢迎页面配置
-----------------------------------------------------------------------
相关对象之------ServletContext
1、获得:servletConfig======>getServletContext
2、servletContext封装了web.xml中的配置
1> servletContext 封装了web.xml 中的配置
<context-param>
<param-name>name</param-name>
<param-value>jerry</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</context-param>
getInitParameterNames(); ==> 获得所有键
getInitParameter(key); ==> 根据键获得对应的值
2>serlet技术中3大域对象之一
ServletContext对应着Application(应用)域.利用了一个项目中只有一个ServletContext实例的特点.在servletContext中放置了一个map用作数据通信.
这个Map就是所谓域.
关于域的操作,有4个.
放入键值对 setAttribute(key,value)
通过键取值 getAttribute(key)
通过键删除 removeAttribute(key)
遍历所有键 getAttributeNames()
application ==> servletContext
session ==>
request ==>
3>获得项目中资源
3、servlet技术中对象的范围
servlet ==>项目启动期间一个servlet只有一个servlet实例
request===>项目启动期间,request对象的数量,要看当前有多少个请求正在处理
response ===>同上
servletConfig ===>一个servlet实例对应一个servletConfig对象
servletContext===>整个项目中,永远只有一个servletContext实例存在
servlet ==> server applet ==> 服务器端的小程序
1.作用是用来处理请求(request),完成响应(response)的.
2.如何创建一个servlet
*实现servlet接口
*继承GenericServlet
*继承HttpServlet
3.servlet接口中的方法
*init (ServletConfig )
*service (ServletRequest , servletResponse )
*destory ()
//=======
*getServletConfig
*getServletInfo
4.ServletConfig 的 作用.
*getServletName
*getInitParameter()
*getInitParameterNames()
*getServletContext()
5.servlet线程是不安全的.
因为在服务器中,一个servlet只存在一个实例.所以当有多个请求同时访问的时候,如果使用成员变量接受线程参数,就会有问题.
解决办法: 使用局部变量接受线程参数.
6.url-pattern
路径匹配: "/"开头 例如: /AServlet
后缀名匹配: "*"开头 例如: *.do
注意: 1.匹配范围越广优先级越低
2.两种匹配方式不能同时使用.
7.load on startup
该配置可以让servlet在服务器启动时加载.
填入的数字表示优先级.数字越小,优先级越高.
优先级一样,按配置顺序加载.
8.servletContext
范围: 一个项目对应一个servletContext.
获取: 通过servletConfig获取
作用:
1.获得配置文件(web.xml根下的)中的参数
*getInitParameter()
*getInitParameterNames()
2.域的功能 => application
增加一个:setAttribute
删除一个:removeAttribute
获得一个: getAttribute
获得所有键: getAttributeNames
3.获得项目内资源
getResourceAsStream
getRealPath
*以上两个方法都是填写相对路径. "/" ==> 项目的根下(WebRoot)
package my.servletlearn.context.resource;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class KServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
/*// 获得资源的其他方式
// 使用class方法
// "/" ===>代表classes目录
InputStream is2=this.getClass().getResourceAsStream("Student.xml");
// "" ===> 不加 "/",代表当前文件所在目录
InputStream is3=this.getClass().getResourceAsStream("student/xml");
System.out.println(is2);
System.out.println(is3);*/
//---------------------------------------------------------------------------
InputStream is4=this.getClass().getClassLoader().getResourceAsStream("");
// 区别就是不加"/" 还是相对于classes目录
InputStream is5=this.getClass().getClassLoader().getResourceAsStream("/");
System.out.println(is4);
System.out.println(is5);
// 获得路径
String path=this.getClass().getResource("student.xml").getPath();
System.out.println(path+"path");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.context;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.internal.ws.api.policy.PolicyResolver.ServerContext;
public class GServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
// 获得全局init param设置
// 1、获得ServletContext
ServletContext sContext= getServletContext();
// 调用getXXX方法
Enumeration<String> enumeration=sContext.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
String value=sContext.getInitParameter(key);
resp.getWriter().print(key+"===>"+value+"<br/>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.context;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
Constant.str="Hello";
// 向静态变量赋值
// resp.getWriter().print(Constant.str);
// 向女神送包
Constant.obj="Lv";
// resp.getWriter().print(Constant.obj);
Constant.map.put("bag", "Lv");
Constant.map.put("car", "QQ");
Constant.map.put("phone", "ventu");
// 使用ServletContext完成通信
// 1、获得ServletContext对象
ServletContext sc=getServletContext();
// 操作map
sc.setAttribute("ck", "calkin");
sc.setAttribute("eat", "jinqiangyu");
sc.setAttribute("car", "BMW");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.context;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.internal.ws.api.policy.PolicyResolver.ServerContext;
public class IServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
// 取值
String str=Constant.str;
// Object bao=Constant.obj;
String bao=(String) Constant.map.get("bag");
// 输出到客户端
resp.getWriter().print(str+"<br>");
resp.getWriter().print(bao+"<br>");
Constant.map.remove("car");
// 通过servletContext取值
// 获得servletContext对象
ServletContext sContext=getServletContext();
// 操作map
String bag=(String) sContext.getAttribute("ck");
// 输出到客户端
resp.getWriter().print(bag);
// 不喜欢就扔掉(删除)
sContext.removeAttribute("ck");
//遍历
Enumeration<String> enumeration=sContext.getAttributeNames();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
Object value=sContext.getAttribute(key);
System.out.println(key+"====>"+value);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.context.resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
// 获得WEB-InF下的student.xml
File file=new File("D:\\java\\workspace\\MyWeb\\WebContent\\WEB-INF\\student.xml");
// 以上获得student.xml的代码不正确
// 不正确,因为这样获得的tudent.xml指的是Eclipse工程下的文件,而我们真正要操作的是部署到tomcat下的资源
File file2=new File("student.xml");
System.out.println(file2.exists());
// 结论:file的相对路径行不通
// 解决方案:使用servletContext
ServletContext sc=getServletContext();
// "/" ===>代表项目下
InputStream iStream=sc.getResourceAsStream("/WEB-INF/student.xml");
System.out.println(iStream);
// 获得资源的绝对路径
String realPath=sc.getRealPath("/WEB-INF/student.xml");
System.out.println(realPath);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.context.resource;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class KServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
/*// 获得资源的其他方式
// 使用class方法
// "/" ===>代表classes目录
InputStream is2=this.getClass().getResourceAsStream("Student.xml");
// "" ===> 不加 "/",代表当前文件所在目录
InputStream is3=this.getClass().getResourceAsStream("student/xml");
System.out.println(is2);
System.out.println(is3);*/
//---------------------------------------------------------------------------
InputStream is4=this.getClass().getClassLoader().getResourceAsStream("");
// 区别就是不加"/" 还是相对于classes目录
InputStream is5=this.getClass().getClassLoader().getResourceAsStream("/");
System.out.println(is4);
System.out.println(is5);
// 获得路径
String path=this.getClass().getResource("student.xml").getPath();
System.out.println(path+"path");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn.demo;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class AServlet implements Servlet {
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
// init 是在第一次请求Aservlet时调用 ===>Servlet实例的创建是在第一次访问的时候
// servlet在多次访问时,发现只调用了1次init方法,在多次访问,只创建了一个实例
System.out.println("ASerlet的init方法被调用!");
}
// 当客户端请求的时候调用service,参数1 request对象封装了请求信息,参数2 response 中填入信息生成的响应
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
arg1.getWriter().print("hello world!");
System.out.println("ASerlet的service方法被调用le!");
}
@Override
// 在服务器将要关闭时,会小会内存中的servlet实例,在真正小会之前会调用destroy方法
public void destroy() {
// TODO Auto-generated method stub
System.out.println("ASerlet方法被调用了!");
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
// 这个方法没有用
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}
package my.servletlearn.generic;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public abstract class MyGenericServlet implements Servlet,ServletConfig{
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
this.config=config;
}
@Override
//不要忘记抽象方法不需要被实现
public abstract void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return config;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
public String getInitParameter(String arg0) {
return config.getInitParameter(arg0);
}
public Enumeration<String> getInitParameterNames() {
return getServletConfig().getInitParameterNames();
}
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}
public String getServletName() {
return getServletConfig().getServletName();
}
/*public String getServletName() {
return getServletConfig().getServletName();
}
public String getInitParameter(String args0) {
return getServletConfig().getInitParameter(args0);
}
public Enumeration getInitParameterNames() {
return getServletConfig().getInitParameterNames();
}
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}*/
}
package my.servletlearn.generic;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CServlet extends MyGenericServlet{
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
// String servletName=getServletConfig().getServletName();
String servletName=getServletName();
// String param=getInitParameter("name");
arg1.getWriter().print(servletName);
}
// 重新init方法
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("C");
super.init(config);
}
}
package my.servletlearn.http;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import my.servletlearn.generic.MyGenericServlet;
public abstract class MyHttpServlet extends MyGenericServlet{
public static final String Method_Get="GET";
public static final String Method_Post="POST";
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
// 优化:我们开发项目都是基于http协议的,而且服务器在service方法中传给ServletRequest
// 所以我们把request和response强转成HTTP的
HttpServletRequest request=null;
HttpServletResponse response=null;
try {
request=(HttpServletRequest) req;
response=(HttpServletResponse) res;
service(request, response);
} catch (Exception e) {
// TODO: handle exception
}
}
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
// 优化2:我想根据请求方式的不同,做不同的事情
// 获得客户端的请求方式
String method=req.getMethod();// Get/Post
// 根据请求方式的不同,调用不同的方法
if (method.equals(Method_Get)) {
doGet(res,req);
}else if(method.equals(Method_Post)){
doPost(res,req);
}
}
public void doPost(HttpServletResponse res, HttpServletRequest req) {
// TODO Auto-generated method stub
}
public void doGet(HttpServletResponse res, HttpServletRequest req) {
// TODO Auto-generated method stub
}
}
package my.servletlearn.http;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DServlet extends MyHttpServlet{
@Override
public void doPost(HttpServletResponse res, HttpServletRequest req) {
// TODO Auto-generated method stub
System.out.println("您现在使用的是POST访问方式");
}
@Override
public void doGet(HttpServletResponse res, HttpServletRequest req) {
// TODO Auto-generated method stub
System.out.println("您现在使用的是GET访问方式");
}
}
package my.servletlearn.thread;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FServlet extends HttpServlet {
private String name;
private int i=0;
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("F ");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
// name=req.getParameter("name");
i++;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resp.getWriter().print("The number is:"+i);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
package my.servletlearn2.demo;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class BServlet implements Servlet{
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
this.config=config;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
// 获得servlet的name
String servletName=getServletConfig().getServletName();
// 将字符串输出到客户端(浏览器)
res.getWriter().print(servletName+"<br>");
/**
* String getInitParameter(String name)
* Enumeration getInitParameterNames()
* webxml配置里面的init-param的信息
*/
Enumeration<String> enumeration=getServletConfig().getInitParameterNames();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
String value=getServletConfig().getInitParameter(key);
res.getWriter().print(key+"===>"+value+"<br>");
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return config;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}