Servlet 初步

Servlet学习

1.如何写一个Servlet
    1.编写普通Java类,继承HttpServlet类
    2.重写doGet和doPost方法
    3.把这个Servlet交给Tomcat运行
    3.1:servlet字节码拷贝到WEB-INF/classes目录
    3.2:在web.xml中进行配置


tomcat启动的时候,首先加载webapps中的每个web应用的web.xml配置文件;

1.在day10的web.xml中查找是否有匹配的uri-pattern内容。
2.如果找到匹配的url-pattern,则使用当前的servlet-name的名称到web.xml文件中查询是否有相同的名称的servlet配置;
3.如果找到,则取出对应的servlet配置信息中的servlet-class内容:字符串
    gz.itcast.a_servlet.firstServlet

通过反射:
a.构造FirstServlet的对象;
b.然后调用FirstServlet里面的方法

Servlet映射路径

1.url-pattern要么以/开头,要么以*开头;
2.不能同时使用两种模糊匹配
3.当有输入的URL有多个servlet同时被匹配的情况下:
3.1精确匹配优先;
3.2以后缀名结尾的模糊匹配优先级最低

URL输入http://localhost:8080/day10/index.html
1.到当前day10应用下web.xml文件中查找有匹配的uri-pattern
2.如果没有匹配的uri-pattern,那么会交给tomcat的内置DefaultServlet处理
3.DefaultServlet程序到day10应用中的根目录下查找是否有一个名称为index.html的静态文件
4.如果找到该文件,则读取该文件的内容,返回给浏览器;
5.如果找不到,则返回404

结论:先找动态资源,在找静态资源。

Servlet的生命周期

Servlet类对象什么时候创建?创建时候调用什么方法?什么时候销毁?
Servlet程序的声明周期是tomcat服务器控制的。

Servlet重要的生命周期

构造方法:创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象只调用1次,证明servlet对象在tomcat是单例的。
init方法:创建完servlet对象的时候调用,只调用1次;
service方法:每次发出请求时候调用,调用n次。
destroy方法:销毁的时候

改变servlet创建对象的时机,提前到加载web应用的时候!!!
如果让servlet对象自动加载,那么在servlet的配置信息中,加上
1
注意整数值越大,创建优先级越低。

Servlet中的有参数init()和无参数init()

GenericServlet中的有参init方法:

    public void init(ServletConfig config) throws ServletException{
        this.config=config;
        this.init();
    }
    public void init(){

    }

//因此我们不覆盖有参数的init方法,只需要重写无参数的init方法,那么有参数的init方法会自动帮我们调用。

servlet对象在tomcat是单实例多线程

一个用户一个线程
    Thread1
    public void run(){
            first.service(request,response);        
    }

    Thread2
    public void run(){
            first.service(request,response);        
    }
//线程1和2都是同一个对象,但是2个封装的request和response对象不相同

servlet线程安全问题

servlet是有线程安全问题的。如果多个线程同时访问了servlet对象的共享数据(成员变量)

解决线程安全问题

使用到共享数据的代码块进行同步,使用synchronized(response)

在servlet类中尽量不要成员变量,如果确实要使用,必须同步。而且尽量缩小同步代码块的范围(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致开发效率降低。

Servlet重要对象

HttpServletRequest对象:请求对象,获取请求信息;
HttpServletResponse对象:响应对象,设置响应对象;
ServletConfig对象:servlet配置对象
ServletContext对象:servlet的上下文对象

ServletConfig对象

作用:
    ServletConfig对象:主要是用于加载servlet配置参数;
创建时间:
    在创建完servlet对象之后,在调用init方法之前创建;
得到对象:
    直接从有参数的init方法中得到

servlet初始化参数

tomcat启动会加载web.xml中,那么配置文件也会被加载,封装到ServletConfig对象中,通过有参数的init方法传递过来。

    /**
    *ServletConfig的 Api
java.lang.String getInitParameter(java.lang.String name)
java.util.Enumeration getInitParameterNames()获取所有参数
ServletContext getServletContext()得到Servlet上下文对象
java.lang.String getServletName() 得到servlet名字
    */
    public class ConfigDemo extends HttpServlet{
        private ServletConfig config=null;
        //第一种方法拿到config 
        public void init(ServletConfig config) throws Exception{
            this.config=config;
        }
        //2.第二种方法拿到config

        String path=        this.getServletConfig().getInitParameter("path");
        public void doGet(XXX){


        }

//获取所有参数
Iteration<String> enums=this.getServletConfig.getInitParam


    }

ServletContext对象

servlet的上下文对象,表示一个web应用中的所有配置信息。
作用:
String getContextPath()拿到当前web 应用的路径,即项目名称,如/day10
getInitParameter(String name)web应用的初始参数(上面是servlet的初始化参数)
用在重定向中用的最多 response.sendRedirect(“/day10/index.html”), 如果项目名称发生变化那么response.sendRedirect (this.getContext()+”/index.html”)
Enumeration getInitParameter(String name)在所有servlet的外面,在web-app的里面,如
    <context-param>
            <param-name>AAA</param-name>     
            <param-value>AAA value</param-name>   
    </context-param>
任意的Servlet都可以用ServletContext context=this.getServletContext(); context.getInitParameterName(“AAA”);
getInitParameter(String name): web应用的初始参数(上面是servlet的初始化参数)
Enumeration getInitParameter(String name)

void setAttribute(java.lang.String name,java.lang.Object object) 域对象有关的方法

getAttribute
removeAttribute

RequestDispatcher getRequestDispatcher(String path)
转发,类似于重定向

getRealPath :得到web应用的资源文件
InputStream getResourceAsStream :

得到对象:
从ServletConfig对象的getServletContext方法中得到。

Sun公司设计:
1.创建ServletContext对象
ServletContext context=new ServletContext();

2.创建ServletConfig对象
ServletConfig config=new ServletConfig();
config.setServletContext(context);

class ServletConfig{
public ServletContext getServletContext(){
return context;
}
}
public void init(ServletConfig config){
得到ServletConfig对象
//从ServletConfig对象中得到ServletContext对象
ServletContext context=config.getServletContext();
}

一个web应用中可以有多个servlet,一个servlet就可以有一个servletConfig对象,而一个web应用只有一个ServletContext。

域对象有关的方法

域对象:作用是保存数据,获取数据。可以在不同动态资源之间共享数据
Servlet1 Servlet2
name=eric XXX
方法1:
传参数:response。sendRedirect(“/Servlet2?name=eric”)
接收:request.getParameter(“name”);
方案2:可以用 域对象,可以共享任何类型的数据

ServletContext就是一个域对象。

在2个Servlet中传递数据


每个应用中都只有一个ServletContext对象,无论哪个Servlet对象调用getServletContext()得到的都是同一个“账户”

    public class ContextDemo3{
        public void doGet(){
            //1.得到域对象
            ServletContext context
            =this.getServletContext();
            //2.把数据保存到域对象中
            context.setAttribute("name","eric");
        }
    }

//ContextDemo4中拿到数据
    public class ContextDemo4{
        public void doGet(){
            //1.得到域对象
            ServletContext context
            =this.getServletContext();
            //2.把数据保存到域对象中
            String name=(String)context.setAttribute("name");
            System.out.println("name="+name);
        }
    }
//还可以传递对象
//ContextDemo3中
context.setAttribute("student",new Student("jacky",20));

//ContextDemo4中
Student stu=(Student)context.getAttribute("student");
System.out.println(stu);

转发与重定向

//转发
RequestDispatcher rd=
this.getServletContext().getRequestDispatcher(“/index.html”);

rd.forward(request,response);

//重定向
response.sendRedirect(“day10/index.html”);
this.getServletContext())
区别:
1.转发地址不会发生变化,重定向地址会发生变化
2.forward转发不能转发到当前web应用以外的资源,而重定向的可以(“/day09/adv.html”);
3.转发可以将数据保存到域对象,而重定向则不行,重定向的request和response不是一个对象
转发的原理:
//ForwardDemo1
rd.forward(request,response)—->

//GetDataServlet中

因此,如果要使用request域对象进行数据共享,只能使用转发技术

重定向的话返回302+location,然后在访问GetDataServlet这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值