servlet入门

Servlet入门

1.servlet概念:

image-20220331203709239

2.Servlet初体验

image-20220331215337795

通过web.xml配置,访问我创建的ServletDemo类,tomcat自带解析web.xml功能

image-20220331225016649

image-20220331221541875

整个项目:

image-20220402141055535

package com.xurong.servlet;

import javax.servlet.*;
import java.io.IOException;

/**
 * @auther xu
 * @date 2022/4/2 - 13:44
 */
public class ServletDemo2 implements Servlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//        servletResponse.getWriter().write("hello servlet2");
        System.out.println("helloTest");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public void destroy() {

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

}

xml文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--创建一个Servlet实例-->
    <servlet>
        <servlet-name>servletDemo1</servlet-name>
        <servlet-class>com.xurong.servlet.ServletDemo2</servlet-class>
    </servlet>
    <!--给Servlet提供(映射)一个可供客户端访问的URL-->
    <servlet-mapping>
        <servlet-name>servletDemo1</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>


</web-app>

结果:没有向客户端响应响应代码,客户端并没有输出什么,不过服务器端输出了服务端运算的代码:

image-20220402141439235

3.Servlet执行过程

image-20220331230221745

补充:ServletDemo1没有main方法,ServletDemo类是Tomcat实例化的,其中的service()方法也是服务器调用的。

image-20220331230714696

image-20220331230954497

4.Servlet生命周期

image-20220402150010843

1--实例化---》初始化----》服务(多个服务)----》销毁

image-20220402144959428

2--理解--应用卸载了,secondServlet删除:(这个还是欧典有点懵)

image-20220406073808938

注意在服务器运行时,该文件正在使用,无法卸载。

image-20220402152417090

image-20220402152856715

注意:设置了该管理模式需要重启服务器再来探究destroy()方法目的,服务器在运行时,将webapp卸载,也就是destroy()方法实际执行的动作,我们不能通过文件直接删除,但是可以通过管理模式,将正在运行的应用程序卸载,从而达到执行destroy目的

image-20220402153901607

image-20220402154359502

以上模拟了web应用程序的全过程。

特别注意:服务器停了与应用程序卸载(我理解是从内存中删除了,一个应用进程的结束,垃圾回收,并非是静态代码删除)之间的区别(服务器停了,应用程序肯定关闭卸载了,但是应用程序卸载了服务器并不一定停了,因为应用要部署到服务器上才能运行。)

3.创建一个实例,该实例中的service方法可以多次调用,体现多线程。

image-20220402155630535

package com.xurong.servlet;

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

import java.io.IOException;

/**
 * @auther xu
 * @date 2022/3/31 - 21:43
 */
public class ServletDemo2 implements Servlet {
    //Servlet生命周期的方法
    //实例化方法
    //在servlet第一次访问时被调用
    public ServletDemo2() {
        super();
        System.out.println("************ServletDemo实例化了*********");
    }
    //Servlet生命周期的方法
    //初始化
    //在servlet第一次访问时被调用
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("--------init()初始化了-----------");
    }

    //Servlet生命周期的方法
    //服务
    //每一次访问时都会被调用
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//        servletResponse.getWriter().write("hello helloservletDemo1");
        System.out.println("---------service()方法执行了----------");
    }


    //Servlet生命周期的方法
    //销毁
    //应用卸载的时候销毁
    @Override
    public void destroy() {
        System.out.println("------------destroy()方法执行了-----------");
    }

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


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


}

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--创建一个Servlet实例-->
    <servlet>
        <servlet-name>servletDemo1</servlet-name>
        <servlet-class>com.xurong.servlet.ServletDemo2</servlet-class>
    </servlet>
    <!--给Servlet提供(映射)一个可供客户端访问的URL-->
    <servlet-mapping>
        <servlet-name>servletDemo1</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>


</web-app>

4.服务器已启动就实例化化与初始化设置,关于<load-on-startup>2</load-on-startup>数字问题

image-20220402164100295

运行结果:image-20220402164635390

对比:

image-20220402164850863

5.真正的执行过程

image-20220402170123849

5.适配器模式--继承javax.servlet.GenericServlet类

作用:实现了Servlet,ServletConfig俩个接口,想调用这两个接口中的方法直接继承GernicServlet类即可

image-20220402220702326

image-20220402221307005

所遇到的问题:

1.报505错误:

image-20220402143719377

解决:(我觉的是Tomcat中类(不同包中的非子类)实例化时,需要权限为public,default不行)

image-20220402144435354

6.javax.servlet.HttpServlet

1.从一个客户端访问报错405研究doPost()与doGet()方法

image-20220403074358465

1.继承的HttpServlet类的方法显示

image-20220403080536939

2.HttpServlet继承的方法(对父类的方法进行重写)-----service(ServletRequest req, ServletResponse res)

image-20220403081206235

image-20220403081104820

3.HttpServlet自己定义的----protected void service(HttpServletRequest req, HttpServletResponse resp)方法

image-20220403082302523

1.this.doGet(req,resp);

image-20220405072617684

"http.method_get_not_supported"字符串内容:

image-20220403083025526

2.this.doPost()方法

image-20220403083333951

image-20220403083414849

http.method_post_not_supported

image-20220403083544745

4.通过对HttpServlet中doPost()与doGet()方法的探索总结一下

image-20220403085156477

通过继承HttpServlet类,重写其方法,达到从服务器端反馈给客户端数据的目的

其原理过程:客户端发送请求----》Tomcat服务器实例化应用程序(多态:Servlet s = new ServletDemo4();)ServletDemo4类,并执行初始化init()方法----》实例化对象调用HttpServlet类对GenericServlet类重写的service()方法----》servlet()方法调用HttpServlet本类的service()方法-----》HttpServlet本类的service()方法调用ServletDemo4类中重写的doGet()与doPost()方法(采用实例化子类对象时,相同的方法在子类中重写了,会优先调用子类的方法,this句柄指向的是ServletDemo4对象,this.doGet()与this.doPost()自然指向ServletDemo4类中的方法),而非HttpServlet本类中的方法。

结果:(可以通过调试看到访问的是重写的doPost()与doGet()方法)

image-20220403090741970

image-20220403095315784

7.doGet()与doPost()方法设计技巧,多个映射路径可以指向一个Servlet

1.设计技巧:

image-20220403101709369

注意:一般客户端访问默认是get方式

2.多个映射路径可以指向一个Servlet

image-20220403102930511

使用通配符方式改进:

image-20220403103203143

*.action:

image-20220403103821603

/*:

image-20220403104153140

/action/*:

image-20220403104327864

匹配规则:

image-20220403104718536

image-20220403105008968

补充:

image-20220403105338796

image-20220403105604747

image-20220403105539770

image-20220403110751830

tomcat服务器自带默认的DefaultServlet(), 其中包含一个web.xml

image-20220403105719717

image-20220403110048649

image-20220403110134008

总结:/映射也是一个DefaultSevlet,所以说所有资源都是servlet.

8.Servlet线程安全:

image-20220403144641717

1.全局变量导致的线程安全问题

package com.xurong.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther xu
 * @date 2022/4/3 - 14:48
 */
public class ServletThread extends HttpServlet {
    //全局变量会导致线程安全
    int i = 1;

    public ServletThread() {
        super();
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        i++;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("一个实例多个线程,当前值为:"+i);//不出意外,线程安全会出现i值不一定都是累加的
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

输出结果:

image-20220403150623627

2.解决线程安全:不要定义全局变量

image-20220403151015641

image-20220403151040059

9.获取Servlet配置信息

方式1:

image-20220403153012854

image-20220403153542023

演示:

package com.xurong.servletOther;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther xu
 * @date 2022/4/3 - 15:31
 */
public class ServletConfigureDemo extends HttpServlet {
    private ServletConfig config;

    public ServletConfigureDemo() {
        super();
    }

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

    @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取配置文件方式1:
        String encodingValue = config.getInitParameter("encoding");
        System.out.println(encodingValue);
        

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

image-20220403154725372

image-20220403154805313

image-20220405074611422

image-20220405074744291

方式2:

image-20220403214415967

image-20220404003514906

image-20220404003711749

报500错误:

image-20220403214651727

错误原因:

方式3:

image-20220403164407768

image-20220404003859544

image-20220404003948197

11.ServletContext(重要)

1.作用1:

image-20220404084005271

域对象补充一下:image-20220404084707901

image-20220404085708012

java代码实现:

package com.xurong.servletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther xu
 * @date 2022/4/4 - 9:01
 */
public class ServletContextDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取应用对象方法1:
//        ServletContext application = super.getServletConfig().getServletContext();
        //获取应用对象方法2:
        ServletContext application = this.getServletContext();
        application.setAttribute("name","Tom");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       this.doGet(req,resp);
    }
}

配置路径web.xml:

image-20220404092309991

结果:

image-20220404092702008

image-20220404092850095

小技巧:查看类名

image-20220404093342057

image-20220404093719710

ServletContext的超类不是Object,而是有Apach服务器提供

2.作用2:获取全局配置信息

image-20220404084841147

image-20220404095510384

image-20220404095533882

3.作用3:获取当前应用任何位置的任何资源(只要深处该应用中)

image-20220404084940803

image-20220405102141746

image-20220405104327968

1.WEB-INF/b.properties访问

image-20220405110521318

image-20220405110459729

image-20220405110538901

2.src/b.properties访问

image-20220405121732004

image-20220405120951334

所遇问题:

image-20220405113515764

image-20220405120311269

3.src\com\xurong\servletContext\c.properties文件内容

image-20220405122319855

image-20220405122235194

image-20220405122419782

12.实现servlet请求转发

image-20220405132415531

image-20220405132756400

image-20220405132826844

13.总结:

image-20220403163452616

image-20220405140245239

image-20220405140205606

所遇到的问题:

1.IDEA 使用Tomcat Server output输出中文乱码问题

image-20220331223754325

image-20220331223632136

补充Tomcat:

1.Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。

2.Tomcat包含servlet-api.jar

3.Tomcat不需要配置环境变量,很少在本地访问,一般直接部署到

其实,一般很少在本地启动Tomcat,大多数都是在开发工具(eclipse或者Idea)中集成外部本地Tomcat,无须配置环境变量,因为eclipse内部已经直接找到了Tomcat的根目录中。下面完整演示一下,Tomcat在本地的启动过程。

注意:无论何时,最后关闭IDE前一定要先关闭Tomcat服务器,有的IDE会提示你Tomcat服务器没关,有的不会提示,那么你下次启动IDE后,启动Tomcat,很大概率上会失败。电脑死机,eclipse自动闪退也会发生这种问题。如果你真的发生这种问题,可以参考我之前写的解决方案:

参考:

posted @ 2022-04-05 20:40  远道而重任  阅读(1)  评论(0编辑  收藏  举报