JavaWeb之Servlet学习(1)

Servlet

什么是Servlet?

  • Servlet是JavaWeb三大组件之一(Servlet、Filter、Listener)

  • Servlet是用来处理客户端请求动态资源。服务器会把接收到的请求交给Servlet来处理

  • Servlet的任务有:

    获取请求数据
    处理请求
    完成响应

  • Servlet接口方法:

    void init(ServletConfig)
    void service(ServletRequest,ServletResponse)
    void destory()
    ServletConfig getServletConfig()
    String getServletInfo()

实现Servlet的方式

  • 实现Servlet接口(不方便)
  • 继承GenericServlet类(不方便)
  • 继承HttpServlet类(方便,常用)

如何使用Servlet?

  1. ​ 定义一个类并且extends HttpServlet

  2. ​ 重写servive()方法

  3. ​ 在web.xml中进行映射配置

  4. ​ 通过浏览器访问映射的url

    LoginServlet.java
    
    public class LoginServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
        /**
         * 构造方法
         */
        public LoginServlet() {
            System.out.println("========构造方法=======");
        }
        
        /**
         * 服务方法
         */
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        	System.out.println("=========service(req,resp)=======");
        	
            String method = req.getMethod();
        	if("get".equalsIgnoreCase(method)) {
        		this.doGet(req, resp);
        	}else if("post".equalsIgnoreCase(method)) {
        		this.doPost(req, resp);
        	}
        }
    
    	/**
    	 * 当前请求的method为get时 执行这里
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println("==========doGet()======");
    	}
    
    	/**
    	 * 当前请求的method为post时 执行这里
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println("=========doPost()======");
    	}
    	
    	@Override
    	public void init() throws ServletException {
    		System.out.println("=========init()初始化======");
    	}
    	
    	@Override
    	public void init(ServletConfig config) throws ServletException {
    		System.out.println("========init(config)======");
    	}
    	
    	@Override
    	public void destroy() {
    		System.out.println("=======destroy()销毁方法=====");
    	}
    }
    
    
    web.xml配置Servlet,把访问路径/login与一个com.wdzl.servlet.LoginServlet绑定到一起
        
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.wdzl.servlet.LoginServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

    浏览器不能直接访问Servlet文件,只能通过映射的方式来间接访问Servlet,映射配置方式:

    • 基于xml文件配置

      • 的子标签:
    <servlet>  
    	<servlet-name>hello</servlet-name>  
    	<servlet-class>org.my.servlet.HelloServlet</servlet-class> 
    </servlet>
    <servlet-mapping>  
    	<servlet-name>hello</servlet-name>  
    	<url-pattern>/demo2</url-pattern> 
    </servlet-mapping>
    • 注解配置
    @WebServlet("/demo2") 
    public class HelloServlet implements Servlet {
    
    }

Servlet生命周期 (重点):实例化,初始化,服务,销毁

1.由谁来控制的 ? == 容器

​ 由容器(Tomcat,Jboss,Weblogic,glassfish等) 不需要我们去实例化和调用

2.四个阶段:实例化,初始化,服务,销毁

  1. **加载和实例化:**容器通过构造方法完成实例化,一次,单例的 。

    注意:serlvet的请求和响应使用的是多线程

    服务器创建Servlet:
    • ​ 当Servlet第一次被请求时,或服务器启动时,服务器会创建Servlet实例。
    • ​ 服务器默认是在servlet第一次被请求时创建Servlet实例,如果希望服务器启动时就创建Servlet实现需要在web.xml中配置
    • ​ 服务器只为一个Servlet创建一个实例对象,所以Servlet是单例的
  2. **初始化:**init()方法

    注意:init有两个重载的方法,有参和无参,执行一次。

    想要获取初始化参数时,使用init(ServletConfig config)

    服务器初始化Servlet:
    • ​ 当服务器创建Servlet实例后会马上调用Servlet的init(ServletConfig)方法,完成对Servlet的初始化
    • ​ init(ServletConfig)只会被调用一次
    • ​ 服务器会在调用init()方法时传递ServletConfig参数
  3. **服务:**service()方法, 执行多次,每次请求都会执行

    服务器使用Servlet处理请求:
    • ​ 当Servlet被请求时,服务器会调用Servlet的service(ServletRequest,ServletResponse)方法
    • ​ service(ServletRequest,ServletResponse)方法每处理一次请求,就会被调用一次,所以它可能会被调用N次
    • ​ 因为Servlet是单例的,所以可能在同一时刻一个Servlet对象会被多个请求同时访问,所以这可能出现线程案例问题
    • ​ Servlet不是线程案例的,这有助与提高效率,但不能让Servlet具有状态,以免多个线程争抢数据
  4. **销毁:**destroy()方法,执行一次。 服务器容器停止或servlet实例需要重新加载时

    服务器销毁Servlet:
    • ​ 服务器通常不会销毁Servlet,通常只有在服务器关闭时才会销毁Servlet
    • ​ 服务器会在销毁Servlet之前调用Servlet的destory()方法
    • ​ 可以在destory()方法中给出释放Servlet占有的资源,但通常Servlet是没什么可要释放的,所以该方法一般都是空的
2.1 顺序?

​ web.xml中配置,load-on-startup设置

2.2 Servlet实例化、初始化时间?(面试)
  • 默认情况下,Servlet是在第一次被访问时由服务器创建的。

  • 如果服务器启动时就创建Servlet,那么还需要在web.xml文件中配置。

    ​ 在服务器启动时,进行实例化和初始化,启动配置为-1,表示不随服务器启动(第一次被访问时加载)

    ​ 如果大于等于0时,按数字由小到大依次启动

    	<servlet>
    		<servlet-name>hello1</servlet-name>
    		<servlet-class>my.servlet.Hello1Servlet</servlet-class>
    		<load-on-startup>0</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>hello1</servlet-name>
    		<url-pattern>/hello1</url-pattern>
    	</servlet-mapping>
    	<servlet>
    		<servlet-name>hello2</servlet-name>
    		<servlet-class>my.servlet.Hello2Servlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>hello2</servlet-name>
    		<url-pattern>/hello2</url-pattern>
    	</servlet-mapping>
    	<servlet>
    		<servlet-name>hello3</servlet-name>
    		<servlet-class>my.servlet.Hello3Servlet</servlet-class>
    	<load-on-startup>2</load-on-startup>
    	</servlet>
      <servlet-mapping>
    		<servlet-name>hello3</servlet-name>
      		<url-pattern>/hello3</url-pattern>
    	</servlet-mapping>
    

service和doGet doPost 关系?

​ 在HttpServlet的**service(HttpServletRequest,HttpServletResponse)**方法会去判断当前请求是GET还是

POST**(在service方法中,获取请求的method,来调用doGet和doPost)**,如果是GET请求,那么会去调用本类

的doGet()方法,如果是POST请求会去调用doPost()方法,这说明我们在子类中去覆盖doGet()或doPost()方法即

可。

    /**
     * 服务方法
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	System.out.println("=========service(req,resp)=======");
    	
        String method = req.getMethod();
    	if("get".equalsIgnoreCase(method)) {
    		this.doGet(req, resp);
    	}else if("post".equalsIgnoreCase(method)) {
    		this.doPost(req, resp);
    	}
    }

如何正确的获取request,response,out,application,session,config对象

  • request、response:service(HttpServletRequest req, HttpServletResponse resp),

    是容器帮我们实例化,传过来的

  • session:HttpSession session = req.getSession()

  • out:PrintWriter out = resp.getWriter();

  • ​ **application:ServletContext application = getServletContext(); **

    正常使用的前提,没有定义有参的init方法

对象描述
requestHttpServletRequest 接口的实例
responseHttpServletResponse 接口的实例
outJspWriter类的实例,用于把结果输出至网页上
sessionHttpSession类的实例
applicationServletContext类的实例,与应用上下文有关
configServletConfig类的实例
pageContextPageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page类似于Java类中的this关键字
ExceptionException类的对象,代表发生错误的JSP页面中对应的异常对象
public class CountServlet extends HttpServlet {
	private int count;//计数
	/**
	 * 9大内置对象:
	 * request response out session config
	 * page,exception,application,pageContext
	 * 
	 * request,session,application
	 * response out config 
	 * 
	 */
    
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//注意:设置的位置一定是在getWriter()之前
		resp.setContentType("text/html;charset=utf-8");
		
        PrintWriter out = resp.getWriter();
		HttpSession session = req.getSession();  
		ServletContext application = getServletContext();  //正常使用的前提,没有定义有参的init方法
		System.out.println(">>>=="+application.getInitParameter("config"));
		System.out.println(">>>=="+application.getInitParameter("charset"));
		count++;
		
		out.println("<h1>第"+count+"次访问!</h1>");
	}

	@Override
	public void destroy() {
		
	}

	@Override
	public void init() throws ServletException {
		System.out.println("=======init()=========");
	}
    
    
	private ServletContext application;
    
//	@Override    
//	public void init(ServletConfig config) throws ServletException {
//		String ct = config.getInitParameter("initCount");
//		
//		application = config.getServletContext();  //获取application  serlvet的上下文
//		System.out.println(">>>==="+obj);
//		try {
//			count = Integer.parseInt(ct);
//		} catch (Exception e) {
//			count = 0;
//		}
//	}

}

注意:乱码问题

区分是请求乱码还是响应乱码:

获取提交参数乱码了,request请求的问题 req.setCharacterEncoding("UTF-8");

如果是out输出乱码了,response响应问题 resp.setContentType("text/html;charset=utf-8");

ServletContext是JavaWeb四大域对象之一:

  • PageContext;

  • ServletRequest;

  • HttpSession;

  • ServletContext;

Session获取问题:

HttpSession session = Request.getSession(true/false);

//false:获取session对象=====如果获取到session对象,则返回对象;如果获取不到,返回null
//true:默认的,无参时,默认为true=====获取session对象,如果获取到session对象,返回对象;								   			   如果获取不到,创建一个新的session对象并返回

问题:Object o = request.getSession(); o可能为null ?

​ 不可能

//登录成功
request.getSession();


//注销操作(原来session存在,注销,否则不用重复注销)
HttpSession session = request.getSession(false);
if(session != null){
    session.invalidate();
}

初始化参数配置和获取?

  • init方法参数如何使用
  • init方法有两个同名重载方法,如果有参构造方法声明了,则不再调用无参方法。
  • config用来获取初始化配置,web.xml中的配置(注解中)

配置url-pattern映射多种方式?

是的子元素,用来指定Servlet的访问路径,即URL(以“/”开头)

  • 可以在中给出多个,例如:

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/AServlet</url-pattern>
        <url-pattern>/BServlet</url-pattern>
      </servlet-mapping>  
    
    一个Servlet绑定了两个URL,无论访问/AServlet还是/BServlet,访问的都是HelloServlet
  • 还可以在中使用通配符“*”,可以匹配任何URL前缀或后缀,使用通配符可以命名一个Servlet绑定一组URL,例如:

    路径匹配:(具体url配置映射,前面注意前面斜杠 /)
    	<url-pattern>/servlet/*<url-patter>		:/servlet/a、/servlet/b,都匹配/servlet/*;
    后缀匹配:(根据请求后缀拦截一类请求  *.jsp 注意:不能有斜杠)
    	<url-pattern>*.do</url-pattern>			:/abc/def/ghi.do、/a.do,都匹配*.do;
    缺省匹配:(匹配所有请求 /*)
        <url-pattern>/*<url-pattern>			:匹配所有URL;
    	

    注意:需要组合配合时,可以对同一个servlet做多次映射

ServletConfig:

​ ServletConfig是Servlet中的init()方法的参数类型

  • String getServletName():获取Servlet配置名,即的值;

  • ServletContext getServletContext():获取ServletContext对象,这个对象稍后介绍

  • String getInitParameter(String name):获取初始化参数

  • Enumeration getInitParameterNames():获取所有初始化参数的名称

    在web.xml文件中,配置<servlet>时可以为<servlet>配置0~N个初始化参数,例如:
    
    <servlet>
      <servlet-name>xxx</servlet-name>
      <servlet-class>my.servlet.MyServlet</servlet-class>
      <init-param>
        <param-name>p1</param-name>
        <param-value>v1</param-value>
      </init-param>
      <init-param>
        <param-name>p2</param-name>
        <param-value>v2</param-value>
      </init-param>
    </servlet>

ServletContext初始化参数配置:

一个JavaWeb应用只创建一个ServletContext对象!

我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据

ServletContext对象在Tomcat启动时就创建,在Tomcat关闭时才会死去!

获取ServletContext对象:(HttpServlet)
  • 在**void init(ServletConfig config)**中:ServletContext context = config.getServletContext();
  • ServletConfig类的getServletContext()方法可以用来获取ServletContext对象:ServletContext sc = this.getServletConfig().getServletContext();
初始化参数配置:
 <context-param>
 	<param-name>config</param-name>
 	<param-value>springmvc-servlet.xml</param-value>
 </context-param>

  
  <context-param>
    <param-name>p1</param-name>
    <param-value>v1</param-value>  	
  </context-param>
  <context-param> 
    <param-name>p2</param-name>
    <param-value>v2</param-value>  	
  </context-param>

  * servletContext.getInitParameter("p1"),返回v1
  * servletContext.getInitParameter("p2"),返回v2
  * servletContext.getInitParameterNames(),返回Enumeration<String>,包含p1和p2

服务器启动时,解析提取,放入ServletContext。 可以在其他Servlet或jsp中获取

注解 :

从Servlet3.0开始,支持注解

​ Servlet常用的几种注解:

● WebServlet:标识Servlet类
  ● WebFilter:标识Filter类
  ● WebListener:标识Listener类
  ● WebInitParam:标识初始化参数
  ● MulitpartConfig:标识上传附件的配置

@WebServlet属性列表:

属性名类型描述
nameString指定Servlet 的 name 属性,等价于 。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。
valueString[]该属性等价于 urlPatterns 属性。两个属性不能同时使用。
urlPatternsString[]指定一组 Servlet 的 URL 匹配模式。等价于标签。
loadOnStartupint指定 Servlet 的加载顺序,等价于 标签。
initParamsWebInitParam[]指定一组 Servlet 初始化参数,等价于标签。
asyncSupportedboolean声明 Servlet 是否支持异步操作模式,等价于 标签。
descriptionString该 Servlet 的描述信息,等价于 标签。
displayNameString该 Servlet 的显示名,通常配合工具使用,等价于 标签。
@WebServlet(name = "servlet1", 
            urlPatterns = {"/url1", "/url2","url3/*"}, 
            loadOnStartup = 1,
        	initParams = {
                @WebInitParam(name = "name", value="hotusm")
       		})
public class MyServlet extends HttpServlet {
    
    private String name;

    public MyServlet() {
        System.out.println("load on startup");
    }

    @Override
    public void init() throws ServletException {
        super.init();
        name= this.getInitParameter("name");
    }

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        System.out.println(session);
        System.out.println("name:"+name);
    }
}

 https://www.cnblogs.com/zr520/p/6095977.html 	

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值