实现Servlet的三种方式以及注解与xml两种映射关系配置总结

Servlet实现的三种方式

​ 什么是Servlet?

  1. servlet是java EE 中规范。—>文档
    2. Servlet本质上就是一个接口
    3. Servlet表示一个可以被浏览器访问到java类(程序)
    4. Servlet实现类直接或者间接(继承)实现接口的实现类
    5. servlet接口存放tomcat/lib/servlet-api.jar

​ Servlet技术可以扩展服务器端的功能,让java代码在服务器端也能成为一种资源(动态资源),客户端浏览器可以通过指定的资源地址(URI),来访问这个java代码(Servlet),同时在Servlet代码中,还可以使用IO流把结果写回给浏览器。

按照Servlet规范要求,编写一个Servlet程序,只需要让自己的类实现 javax.servlet.Servlet 接口就可以了,但是该接口也有一些默认的实现类,所以除了实现接口的方式之外,我们也可以继承它默认的几个实现类,并且重写指定方法,也同样可以完成Servlet程序的编写。

javax.servlet.Servlet
    	它是Servlet技术的核心接口,所有的Servlet程序,都必须是该接口的实现类。
//Servlet接口
package javax.servlet; 
import java.io.IOException; 
public interface Servlet { 
    //初始化servlet对象的时候被调用 
    public void init(ServletConfig config) throws ServletException; 
    //返回ServletConfig对象,该对象封装了Servlet的配置信息 
    public ServletConfig getServletConfig(); 
    //访问servlet对象的时候被调用(最重要的方法) 
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; 
    //返回servlet相关信息,比如作者、版本、版权等 
    public String getServletInfo(); 
    //销毁servlet对象的时候被调用 
    public void destroy(); 
}

项目创建:Dynamic Web project

java Resources/src目录下编写代码

ps:三种方式都直接间接的实现了Servlet接口

 * 客户端访问servlet
 * url——请求行--访问Tomcat--读取web.xml--找到对应的Servlet程序
  • –>创建一个Servlet对象 创建一次–>自动调用service方法
  • url<–>java类
  • 映射关系: web.xml文件形式或者(注解方式)
  • 配置web.xml:建立映射关系
  • 提供一个映射的逻辑
    • 编写一个HTTP相应报文内容
    • 主要添加相应正文
  • 每次请求,自动调用一次service方法
方式一(直接实现 Interface: Servlet)
package com.briup.web.day02;

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 TestServlet implements Servlet{
	public TestServlet() {
		
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		// 当对象创建成功后,会自动调用此初始化方法,并且只调用一次
		
	}

	/**
	 * 1.客户端访问servlet
	 * url——请求行--访问Tomcat--读取web.xml--找到对应的Servlet程序
	 * 
	 */
	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		//1.根据请求信息获取请求的参数
		String name=req.getParameter("name");
		//2.进行逻辑处理
		//3.将逻辑处理结果,响应给浏览器
		res.setContentType("text/plain;charset=utf-8");
		res.getWriter().append("hello 亲爱的"+name+" ,这是实现Servlet的第一种方式直接实现Servlet接口");
	}

}

可以在web.xml中设置告诉tomcat,这个servlet对应的URI地址是什么,其实就是一种映射关系的配置也可以后面用@WebServlet()注解的方式,目的也是为了简化xml

web.xml


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>servlet_demodisplay-name>
  <welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
    <welcome-file>default.htmlwelcome-file>
    <welcome-file>default.htmwelcome-file>
    <welcome-file>default.jspwelcome-file>
  welcome-file-list>
  
	<servlet>
			<servlet-name>testServletservlet-name>
			<servlet-class>com.briup.web.day02.TestServletservlet-class>
	servlet>
  	<servlet-mapping>
  		<servlet-name>testServletservlet-name>
  		<url-pattern>/testurl-pattern>
  	servlet-mapping>
  
  
  
web-app>

然后通过带参url地址:http://localhost:8080/servlet_demo/test?name=宇轩 访问这个Servlet

从浏览器控制台可以看出 响应头信息中的Content-Type字段值,就是我们在Servlet中进行设置的值

方式二(通过继承GenericServlet)
javax.servlet.GenericServlet

它是一个抽象类,它对Servlet接口中的方法进行了默认实现,但是最重要的 service 方法并没有实现

package javax.servlet; 
import java.io.IOException; 
import java.util.Enumeration;
public abstract class GenericServlet implements Servlet,ServletConfig,java.io.Serializable { 
   private static final long serialVersionUID = 1L; 
    private transient ServletConfig config; 
    public GenericServlet() { 
        // NOOP 
    }
    @Override public void destroy() { 
        // NOOP by default 
    }
    @Override public String getInitParameter(String name) { 
        return getServletConfig().getInitParameter(name);
        }
    @Override public Enumeration<String> getInitParameterNames() { 
        return getServletConfig().getInitParameterNames(); 
    }
    @Override public ServletConfig getServletConfig() { 
        return config; 
    }
    @Override public ServletContext getServletContext() { 
        return getServletConfig().getServletContext(); 
    }
    @Override public String getServletInfo() { 
        return ""; 
    }
    @Override public void init(ServletConfig config) throws ServletException { 						this.config = config; this.init(); 
                                                                           
          }
    public void init() throws ServletException { 
        // NOOP by default 
    }
    public void log(String msg) { 
        getServletContext().log(getServletName() + ": " + msg); 
    }
    public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t); 
                                                 }
    @Override public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; 
    @Override public String getServletName() { 
        return config.getServletName(); 
    }
	}

该类中,实现了Servlet接口中的init(ServletConfig config)方法,同时又重载了一个无参的init方法,并且有参数的init方法中又调用了这个重载的无参init方法。由此可知,将来我们对Servlet进行初始化操作的时候,重写这个无参的init方法即可。

package com.briup.web.day02;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
/**
 * Servlet实现第二种
 * 继承GenericServlet(Servlet实现类)其余四种方法它里
 * 已经添加了实现逻辑,不需要再进行重写只需要实现其中的service方法
 * @author 强宇轩
 *
 */
@WebServlet("/test1")
public class TestServlet1 extends GenericServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String name=req.getParameter("name");
		res.setContentType("text/plain;charset=utf-8");
		//获取输出流
		PrintWriter out = res.getWriter(); 
        //向输出流写入信息
		out.println("hello!这是第二种方式:"+name);   //使用流写出到浏览器
	}

}

@WebServlet("/test1")相当于配置了xml,只是代替了xml中的映射配置

这种方式只用实现一个 service 方法即可,其他方法在父类中已经进行了默认实现

​ 使用带参URl 访问 http://localhost:8080/servlet_demo/test1?name=宇轩

浏览器页面显示:hello!这是第二种方式:宇轩

方式三(继承HttpServlet)
javax.servlet.http.HttpServlet
    /**它是一个抽象类,但是类中没有抽象方法。 
    它继承了 GenericServlet ,对接收到的客户端请求,进行了细分,对应不同的请求类型:
    DELETE HEAD GET OPTIONS POST PUT TRACE
    分别使用不同的方法进行处理。
例如,当前如果是GET请求,那么就调用doGet方法进行处理,当前如果是POST请求,那么就调用doPost
方法进行处理,所以在HttpServlet中,定义了很多doXxx方法,用来处理不同类型的请求。*/

HttpServlet继承了GenericServlet,实现了service方法,并且对service方法进行了重载

实现的service方法中,对请求和响应进行了强制类型转换,将普通的请求和响应对象,强制转换

成了针对HTTP协议的请求和响应,然后调用重载的service方法,将转换的请求和响应传入

重载后的service方法中,根据当前请求的类型(get、post获取其他),再调用对应的doXxx方法

进行处理

doXxx方法中会有一些默认的实现,例如doGet方法中会默认返回

http.method_delete_not_supported

我们编写子类继承 HttpServlet ,并且重写方法即可,如果需要处理GET方式的请

求,那么就重写doGet方法,如果需要处理POST方式的请求,那么就重写doPost方法。

package com.briup.web.day02;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/test2")
public class TestServlet2 extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			String name = req.getParameter("name");
			
			resp.setContentType("text/plain;charset=utf-8");
			resp.getWriter().append("这是第三种方式:"+name);
	}

}

总结:在service方法中 ServletRequest res 和ServletResponse req
表示 请求信息通过浏览器发送给tomcat后,然后由tomcat对字符串进行封装成请求对象。
ServletRequest 是一个Servlet中的接口 其实现类是tomcat提供的 (可类比于数据库厂商提供对于不同数据库连接的实现),其目的就是将面向协议开发—>转为面向对象开发
我们需要做的事就是 添加相应正文的操作

你可能感兴趣的:(总结,tomcat,java,http,servlet,javaee)