02-Servlet

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linzhaoliangyan/article/details/88574672

1 什么是Servlet   

  A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol

    servlet 是运行在 Web 服务器中的小型 Java 程序即:服务器端的小应用程序)。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求

    查看Servlet源码:

假如没有导入源码,就导入源码

2 Hello Servlet 的开发步骤

     1 新建web工程

     2 写个类HelloServlet实现Servlet接口

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 HelloServlet implements Servlet{

	@Override
	public void init(ServletConfig config) throws ServletException {
		
	}

	@Override
	public ServletConfig getServletConfig() {
		return null;
	}

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		//响应文本到浏览器
		res.getWriter().write("hello Servlet");
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void destroy() {
		
	}

}

3 在service里面响应文本到浏览器

扫描二维码关注公众号,回复: 5561742 查看本文章

在web.xml里面配置servlet

<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.etc.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

   5 访问这个servlet

         1 再eclipse跑web的项目

 

 

eclipse tomcat的默认部署位置  

 

 

修改eclipse tomcat的默认部署位置

要满足可以修改的条件:移除所有的项目

 访问:http://localhost:8080/5HelloServlet/hello

3 Servlet的执行流程    

  1 通过http://localhost:8080/5HelloServlet/hello  去访问服务器

  2 通过/5HelloServlet在server.xml找到对应web工程

 

 4 Tomcat创建Servlet的对象并且调用init的方法

 5 再调用service方法之后会响应给浏览器

  6 停止tomcat时候,会调用destroy

4 Servlet的生命周期

    实例化--->init--->service--->destroy

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 HelloServlet implements Servlet{

	public HelloServlet() {
		System.out.println("HelloServlet");
	}
	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init");
	}

	@Override
	public ServletConfig getServletConfig() {
		return null;
	}

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		System.out.println("service");
		//响应文本到浏览器
		res.getWriter().write("hello Servlet");
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void destroy() {
		System.out.println("destroy");
	}

}

5 Servlet的三种创建方式

    1 实现Servlet(参考HelloServlet)

    2 继承GenericServlet

            模拟写一个适配器Servlet

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
public abstract class MServlet implements Servlet{
	// 重写这个方法,只有一个不重写(service)
	@Override
	public void init(ServletConfig config) throws ServletException {
		
	}
	@Override
	public ServletConfig getServletConfig() {
		return null;
	}
	@Override
	public String getServletInfo() {
		return null;
	}
	@Override
	public void destroy() {
		
	}
}
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloServlet1 extends MServlet{

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		res.getWriter().write("hello Servlet1");
	}

}
import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class HelloServlet1 extends GenericServlet{

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		res.getWriter().write("hello Servlet1");
	}

}
<servlet>
		<servlet-name>hello1</servlet-name>
		<servlet-class>com.etc.servlet.HelloServlet1</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>hello1</servlet-name>
		<url-pattern>/hello1</url-pattern>
	</servlet-mapping>

   3 继承HttpServlet 

分析HttpServlet的service方法:

 

 

开发步骤:

        1 继承HttpSerlvet

        2 重写doGet和doPost

import java.io.IOException;

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

public class HelloServlet2 extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doGet(req, resp);
		System.out.println("doGet");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doPost(req, resp);
		System.out.println("doPost");
	}
}

 3 web.xml 配置

<servlet>
		<servlet-name>hello2</servlet-name>
		<servlet-class>com.etc.servlet.HelloServlet2</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>hello2</servlet-name>
		<url-pattern>/hello2</url-pattern>
	</servlet-mapping>

  post请求的测试:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<form action="/5HelloServlet/hello2" method="post">
		<input type="submit" value="提交">
	</form>
</body>
</html>

4 创建Servlet快捷的形式

创建好之后,会自动创建Servlet,xml的配置

6 Servlet的细节

    1 映射细节-配置多个映射路径

<servlet-mapping>
    <servlet-name>hello5</servlet-name>
    <url-pattern>/hello5</url-pattern>
  </servlet-mapping>
   <servlet-mapping>
    <servlet-name>hello5</servlet-name>
    <url-pattern>/hello567</url-pattern>
  </servlet-mapping>

 2 映射细节-通配符*(代表任意字符串)

           1 *.do

<servlet>
    <servlet-name>hello2</servlet-name>
    <servlet-class>com.etc.servlet.HelloServlet2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  2 /*

<servlet>
    <servlet-name>hello2</servlet-name>
    <servlet-class>com.etc.servlet.HelloServlet2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

  3 /action/*

  2 匹配规则细节(优先级)

优先级:从高到低

            绝对匹配-->/开头匹配 --> 扩展名方式匹配

            /hello         /*                        *.do

    3 load-on-startup

       servlet在服务器启动时就创建

<servlet>
        <description></description>
        <display-name>hello5</display-name>
        <servlet-name>hello5</servlet-name>
        <servlet-class>com.etc.servlet.HelloSerlvet5</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet> 

7 Servlet的线程安全

    Servlet单实例,多线程访问存在线程安全的问题。

    解决方案:

    1 尽量避免使用成员变量,改用局部变量

    2 在某些代码块synchronized

8 ServletConfig

    A servlet configuration object used by a servlet container to pass

      information to a servlet during initialization.

      总结:主要用配置(servlet初始化的时候)

    1 常见的方法

        public String getServletName();//获取servlet的名字

        public ServletContext getServletContext();//获得上下文对象

   public String getInitParameter(String name);//根据名字获取servlet的初始化参数

   public Enumeration<String> getInitParameterNames();//获取servlet的初始化参数名字的集合

    2 开发步骤

        1 获取ServletConfig对象

 

 private ServletConfig config;   
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		super.init(config);
		this.config=config;
	}

 getServletConfig()

 2 在doGet方法测试方法

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1 获取Servlet的名字
		String servletName = config.getServletName();
		System.out.println("servletName:"+servletName);
		//2 根据名字获得参数信息
		String param = config.getInitParameter("Encoding");
		System.out.println(param);
		System.out.println("-------------------------------------");
		//3 获取参数名字的集合,再通过这些名字获取参数
		Enumeration<String> names = config.getInitParameterNames();
		while(names.hasMoreElements()) {
			String name=names.nextElement();
			String value=config.getInitParameter(name);
			System.out.println("name:"+name+";"+"value:"+value);
		}
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

  3 配置文件

<servlet>
		<description></description>
		<display-name>hello6</display-name>
		<servlet-name>hello6</servlet-name>
		<servlet-class>com.etc.servlet.HelloServlet6</servlet-class>
		<init-param>
			<param-name>Encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>age</param-name>
			<param-value>20</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>hello6</servlet-name>
		<url-pattern>/hello6</url-pattern>
	</servlet-mapping>

 测试结果:

9 ServletContext(上下文)

    Defines a set of methods that a servlet uses to communicate with its servlet container.

    总结:上下文看成是web应用,定义一系列方法,操作这个应用

     1 获取ServletContext对象

        1 config.getServletContext()

    2 servlet:getServletContext()

  2 常见的方法:

    public String getContextPath();// 获取上下文路径,Servlet 2.5

    public String getServletContextName();//获取上下文名字

    public String getServerInfo();//获取服务器的信息(使用服务器,服务器版本号)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1 获取上下文
//		getServletConfig().getServletContext();
		ServletContext context=getServletContext();
		
		//2 获取上下文路径,获取上下文名字,获取服务器的信息
		String contextPath = context.getContextPath();
		String servletContextName = context.getServletContextName();
		String serverInfo=context.getServerInfo();
		System.out.println(contextPath);
		System.out.println(servletContextName);
		System.out.println(serverInfo);
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

     

    public String getRealPath(String path);//根据相对路径获取绝对路径
    public String getMimeType(String file);//传递一个文件路径获取MIME类型
    public InputStream getResourceAsStream(String path);//根据路径(相对路径)获取文件输入流

 

//3 根据相对路径获取绝对路径,传递一个文件路径获取MIME类型,根据路径(相对路径)获取文件输入流
		String path="/WEB-INF/web.xml";
			// 根据相对路径获取绝对路径
		String absolutePath=context.getRealPath(path);
		String path2=context.getRealPath("/hello.json");
		System.out.println(absolutePath);
			//传递一个文件路径获取MIME类型
		String mimeType = context.getMimeType(absolutePath);
		String mimeType2 = context.getMimeType(path2);
		System.out.println(mimeType);//application/xml
		System.out.println(mimeType2);//application/json
		
		InputStream is = context.getResourceAsStream(path);// 而且这个路径是相对路径,传绝对路径的返回null
		IOUtils.copy(is, System.out);

 public String getInitParameter(String name);//获取初始化参数,全局

 public Enumeration<String> getInitParameterNames();//获取初始化名字的集合,全局

String contextParam = context.getInitParameter("bookName");
		System.out.println(contextParam);
		Enumeration<String> paramNames = context.getInitParameterNames();
		while(paramNames.hasMoreElements()) {
			String name=paramNames.nextElement();
			String value=context.getInitParameter(name);
			System.out.println(name+":"+value);
		}

<context-param>
  	<param-name>bookName</param-name>
  	<param-value>Java in thinking</param-value>
  </context-param>
   <context-param>
  	<param-name>test</param-name>
  	<param-value>helloworld</param-value>
 </context-param>

 结果:

public RequestDispatcher(String path);//获取请求转换器
    public Object getAttribute(String name);// 更加名字获取属性的值
    public void setAttribute(String name, Object object);
    public void removeAttribute(String name);
    public Enumeration<String> getAttributeNames();

 

在Servlet1:

//1设置在Servlet1某个属性
		context.setAttribute("age", 20);
		//2 Servlet1 转发跳转Servlet2
		context.getRequestDispatcher("/hello8").forward(request, response);

在Servlet2 :

ServletContext context = getServletContext();
		//3 在Servlet2获取这个属性
		int age = (int) context.getAttribute("age");
		System.out.println("age:"+age);
		response.getWriter().append("age:"+age);

 

10 Servlet3.0版本

 1 @WebServlet 

        String name() default "";// servlet-name

        String[] value() default {};//url-pattern的简单写法

        String[] urlPatterns() default {};//url-pattern的写法

        int loadOnStartup() default -1;// tomcat启动时候,实例化Servlet并且调用init

        WebInitParam[] initParams() default {};//配置初始化参数

        

     2 @WebInitParam

      String name();// 初始化参数的名字

   String value();// 初始化参数的值

     3 开发步骤

      第一个测试:

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(name="hello",value= {"/hello"})
public class HelloServlet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().append("Hello Servlet3.0");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
}

 第二步测试:

@WebServlet(name="hello",urlPatterns= {"/hello"})
public class HelloServlet extends HttpServlet

 第三步测试:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet

第四步测试:

import java.io.IOException;

import javax.servlet.ServletConfig;
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(name="hello",value= {"/hello"},loadOnStartup=1)
public class HelloServlet extends HttpServlet{
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		System.out.println("HelloServlet init 3.00000000");
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().append("Hello Servlet3.0");
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
}

 第五步:

猜你喜欢

转载自blog.csdn.net/linzhaoliangyan/article/details/88574672