Javaweb三大组件之Servlet

Javaweb开发中有很重要的三个组件分别是:Servlet,Filter,Listener。这些组件在Javaweb的开发中起着不同且至关重要的作用,而我们常用的web框架基本都是基于这些基础组件进行封装之后的用法,所以对于这些原生的方式进行Javaweb开发也要需要了解的,这样对框架的认识也能更加深入,理解为什么要那么做。

1.Serlvet的广义概念

Servlet是运行在服务器容器中的一个小程序,所有的用户请求最终都会汇入这里,然后根据请求,通过url交给不同的Servlet对象去处理,也就是业务逻辑的核心部分。

2.Servlet的作用

Servlet在Javaweb担当核心的作用,最核心的业务逻辑是在Servlet对象中进行处理,然后返回给用户的,也是我们最需要关注的组件。

3.Servlet的狭义概念

但是其实Servlet在Java中就是一个有5个抽象方法的接口而已,通过实现这个接口构建不同的Servlet类,处理不同的业务请求。

Javaweb三大组件之Servlet_第1张图片

这就是那个神奇的Servlet最本来的样子。

这几个函数去看api就知道了,下面主要演示一个Servlet的简单例子,看看怎么使用Servlet来进行web的开发。

 

4. Servlet的基本使用

首先是使用最基本的Servlet接口来实现访问一个url,然后返回success,顺便说一下Servlet的一些xml设置和生命周期

1. 首先需要实现Serlvet接口来创建一个Serlvet类,这样才能创建对象(接口不能实例化,应该都知道吧)

public class ServletDemo implements Servlet{

    //对象销毁时调用
    @Override
    public void destroy( ){
        System.out.println("Servlet has been destroyed");
    }

    //这个方法一般不用管
    @Override
    public ServletConfig getServletConfig(){
        return null;
    }

    //这个方法一般不用管
    @Override
    public String getServletInfo(){
        return null;
    }

    //做Servlet的一些初始化操作,在Serlvet实例创建的同时调用
    @Override
    public void init(ServletConfig servletConfig)throws ServletException{
        //测试ServletConfig对象是否接收到xml里面配置的参数
        String username = servletConfig.getInitParameter("username");
        System.out.println("username: "+ username);

        System.out.println("Servlet has been created");
    }

    //这个是Servlet里面最重要的函数,通过这个函数来处理对应的请求的业务
    // 这里可以去学习ServletRequest和ServletResponse这两个类,整个web的前后端交互都是基于Request和Response的
    @Override
    public void service(ServletRequest request, ServletResponse response)
            throws ServletException, IOException{
        response.getWriter().write("success");
    }
}

这样用一个类ServletDemo来实现了我们最原始的Serlvet接口,这样这个SerlvetDemo就具备处理请求的能力了,但是处理是谁的请求,又是如何映射到这个类的实例上的呢?

接下来配置Servlet另一个很重要的部分,就是web.xml




    
    
        
        servletDemo

        
        com.lyh.servlet.ServletDemo

        
        
            username
            lyh
        
        
            password
            112233
        

        
        
        1

    

    
    
        
        servletDemo

        
        
        /ServletDemo
    

这里的xml就配置了我们访问"项目路径/ServletDemo”的时候,会将请求转到ServletDemo这个name的Servlet实例去处理,然后就去找name为ServletDemo的实例,然后发现找到了,对应的类是com.lyh.Servlet.ServletDemo这个用户创建的类。那么就会去创建一个这个类的对象(一般方便起见,都称为Servlet实例),调用init方法。

此时这个Servlet的生命周期就开始了,通过自己的Service方法来处理从各个ip发来的Http请求,只要是对这个url的请求,都会转给他来处理,知道服务器关闭的时候,这个Servlet实例就被销毁了,然后destroy方法被调用,Servlet实例生命周期结束。

这样一个基础的web响应就完成了,通过Servlet,Java里比较原生的方式实现了。

但是我们发现Servlet这个接口直接实现使用有很多不方便的地方,而且我们一般只是和Http协议进行交互,Java设计者自然也想到了这一点,所以在javax.servlet库中已经有为Http协议专门设计的一个类,HttpServlet。

5.HttpServlet的基本使用

HttpServlet类继承自GenericServlet类,GenericServlet类实现了Servlet接口,ServletConfig接口和Serializable接口。这里的源码也比较简单,建议去读读源码。既然有ServletConfig了,那就能用ServletContext这个全局的东西。

 

下面用HttpServlet来做一个简单的web应用,就可以看到这个这个类比Servlet接口好用多了。

HttpServlet里有很多方法,我们需要重写的一般是doGet(),doPost(),init()等等这些方法,因为在HttpServlet中,通过Service方法实际上调用的都是doGet()和doPost()这样的方法,来对Http协议中具体的方法进行业务处理。

先写一个HttpServletDemo类,继承自HttpServlet类,重写了doGet()和init()方法(重写那个方法是有讲究的,还是建议去读源码,就是看最后调用到那个方法然后父类将这个方法空了下来,那么我们就需要去重写的是这个方法)

public class HttpServletDemo extends HttpServlet{

    @Override
    public void init() throws ServletException {
        System.out.println("HttpServlet has been Created");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //测试ServletConfig对象是否接收到xml里面配置的参数
        ServletContext sc = getServletContext();
        System.out.println(sc);

        //测试向ServletContext中添加数据,进行读取和更新
        if(sc.getAttribute("count") == null){
            sc.setAttribute("count", 1);
        }else{
            int count = (int) sc.getAttribute("count");
            sc.setAttribute("count", count+1);
        }
        Integer count = (Integer) sc.getAttribute("count");
        resp.getWriter().write(count.toString());
    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("HttpServlet has been destroyed");
    }
}

这里可以看到和前面的方式不同的,一个是我们重写的是doGet()方法不再是service方法,这是由于基类为我们细分了请求类型;另外是使用了ServletContext这个对象,至于具体的说明,看下面的web.xml吧




    
    
        test
        hello
    

    
    
        
        servletDemo

        
        com.lyh.servlet.ServletDemo

        
        
            username
            lyh
        
        
            password
            112233
        

        
        
        1

    

    
    
        
        servletDemo

        
        
        /ServletDemo
    

    
    
        HttpServletDemo
        com.lyh.servlet.HttpServletDemo
    
    
        HttpServletDemo
        /HttpServletDemo
    

这个就是HttpServlet的基本使用,实际web开发中不同的知识doGet()方法要处理的业务逻辑更加复杂罢了,为了方便业务处理等,大牛们封装了Servlet而形成了框架。

最后根据Serlvet的生命周期我们知道Servlet实例是单例的,而且没有同步处理,所以是线程不安全的。

你可能感兴趣的:(Java,EE)