栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

02、JavaWeb-Servlet

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

02、JavaWeb-Servlet

参阅资料推荐

Tomcat--各个目录详解(二) - 啤酒大泡泡 - 博客园

早期的web应用文件是手动往tomcat文件夹下复制的,由于每改动一次代码就得重新往tomcat的目录下部署一次,后来集成到了IDEA中,只需要重新运行程序即可热启动。

下面看一个demo带你了解一下tomcat

Servelet demo

 

 

 观察这个demo运行起来的页面

真正部署到tomcat中的是 out---->artifacts---->ServeletPractice_war_exploded

1、路径问题

如果想要访问相应的页面,只需在根路径“/”下访问文件名即可,另外jsp文件就是写html的文件。

http://localhost:port/index.jsp
http://localhost:port/index2.jsp

Web-INF中的文件客户端的浏览器是不能直接访问的

 比如Servelet01.class字节码文件无法访问

http://localhost:8080/WEB-INF/classes/com/test/app/Servelet01.class

http://localhost:8080/WEB-INF/classes/com/test/app/Servelet01

均无法访问

 

2、通过映射的方式访问WEB-INF文件夹下的class字节码文件

客户端的浏览器不能直接访问servlet文件只能通过映射间接访问servlet

web.xml中可以添加映射



    
        Servlet001
        com.test.app.Servlet01
    

    
        Servlet001
        /servlet
    

访问的时候出现了中文乱码

去Servlet01.java文件的service方法中设置它的servletResponse.setContentType("text/html;charset=UTF-8");   //设置编码格式

 

 3、带参访问java文件资源

http://localhost:8080/servlet?id=1

在Servlet01.java中添加程序

String id=servletRequest.getParameter("id") ;

 

4、注解方式

@WebServlet("/servlet")

可以达到相同的效果

5、Servlet的生命周期

@WebServlet("/servlet")
public class Servlet01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Serverlet init");
    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet service");
        servletResponse.setContentType("text/html;charset=UTF-8");
        PrintWriter writer =servletResponse.getWriter();
        writer.write("hello! Client~!");
        writer.write("你好,客户端!");
        String id=servletRequest.getParameter("id");
        writer.write("收到id="+id);
    }

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

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

 init service destroy属于生命周期的方法

创建 使用 回收

c++中是这样的

java 由于有GC机制,你只需要创建对象使用即可,不需要考虑回收

回车

回到idea

多次回车访问http://localhost:8080/servlet 

 当第一次访问的时候会调用init方法,当有了对象后就不会再调用init了,会值接调用service方法

存在对象直接调用,不存在再去创建,有点类似于字符串常量池

只需要一个对象,反复去使用,相当于单例模式

当你关闭程序的时候,会调用destroy释放servlet对象

 6、模拟收到请求后tomcat处理Servlet对象创建的过程
访问http:localhost:8080/servlet的时候
程序会到web.xml一解析拿到全类名,通过反射机制去创建对象

1、当浏览器访问Servlet的时候,Tomcat 会查询当前Servlet的实例化对象是否存在,如果不存在,则通过反射机制动态创建对象,如果存在,直接执行第3步。
2、调用init方法完成初始化操作。
3、调用service方法完成业务逻辑操作。
4、关闭Tomcat时,会调用destory方法,释放当前对象所占用的资源。

Servlet 的生命周期方法:无参构造函数、init、service、destory

1、无参构造函数只调用一次,创建对象。
2、init 只调用一次,初始化对象。
3、service 调用N次,执行业务方法。
4、destory 只调用一次,卸载对象。

下面有一段代码,如果不讲servlet.jar引入到JavaSE环境中,就会报错,无法使用Servlet。
因为在javaSE环境中加载不了Servlet01 实现的那个implements Servlet会报错
所以去tomcat解压的目录下找到servlet.jar复制到当前工程下的lib目录下手动导入一下 

    public static void main(String[] args) {
        // 模拟tomcat创建对象的过程
        // http:localhost:8080/servlet到web.xml一解析拿到全类名,通过反射机制去创建对象
        String str = "com.test.app.Servlet01";
        Class clazz = null;
        try {
            clazz = Class.forName(str);
            Constructor constructor = clazz.getConstructor();
            System.out.println(constructor);//会报错
            // 因为在javaSE环境中加载不了Servlet01 实现的那个implements Servlet报错了
            // 去tomcat解压的目录下找到servlet.jar复制到当前工程下的lib目录下手动导入一下
            // 打印出:public com.test.app.Servlet01()
            Object object= constructor.newInstance();
            System.out.println(object);// com.test.app.Servlet01@43556938
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

Servlet01.java

package com.test.app;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;



@WebServlet("/servlet")
public class Servlet01 implements Servlet {
    public Servlet01() {
        System.out.println("Servlet01的无参构造函数,在init之前,肯定是先有对象再去初始化");
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Serverlet init");
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet service");
        servletResponse.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = servletResponse.getWriter();
        writer.write("hello! Client~!");
        writer.write("你好,客户端!");
        String id = servletRequest.getParameter("id");
        writer.write("收到id=" + id);
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("Servlet destroy");
    }
    public static void main(String[] args) {
        // 模拟tomcat创建对象的过程
        // http:localhost:8080/servlet到web.xml一解析拿到全类名,通过反射机制去创建对象
        String str = "com.test.app.Servlet01";
        Class clazz = null;
        try {
            clazz = Class.forName(str);
            Constructor constructor = clazz.getConstructor();
            System.out.println(constructor);//会报错
            // 因为在javaSE环境中加载不了Servlet01 实现的那个implements Servlet报错了
            // 去tomcat解压的目录下找到servlet.jar复制到当前工程下的lib目录下手动导入一下
            // 打印出:public com.test.app.Servlet01()
            Object object= constructor.newInstance();
            System.out.println(object);// com.test.app.Servlet01@43556938
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
7、ServletConfig

该接口是用来描述Servlet的基本信息的。
getServletName()返回Servlet的名称,全类名(带着包名的类名)getlnitParameter(String key)
获取init参数的值(web.xml)
getlnitParameterNames()
返回所有的initParamter的name值,一般用作遍历初始化参数
getServletContext()
返回ServletContext对象,它是Serviet 的上 下又,wl 3eive-。
ServletConfig和ServletContext的区别:
ServletConfig作用于某个Servlet实例,每个Servlet都有对应的ServletConfig,ServletContext作用于整个Web应用,一个Web应用对应一个ServletContext,多个Servlet实例对应一个ServletContext。

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration getInitParameterNames();
}

获取servletName()

在init方法中,即可
String servletName=servletConfig.getServletName();

从web.xml读取参数

web.xml



    
    
    param0
    value0
    

    
    Servlet001
    com.test.app.Servlet01
    
    userName
    admin
    
    
    
    Servlet001
    /servlet
    
    

servlet.java(因为要从web.xml读取初始化参数,所以一定要把@WebServlet注释掉)

//@WebServlet("/servlet") 由于本次演示在web.xml中定义了此servlet的映射,这里先注释掉,否则重复映射了就。
public class Servlet01 implements Servlet {
    public Servlet01() {
        System.out.println("Servlet01的无参构造函数,在init之前,肯定是先有对象再去初始化");
    }

    public String userName = "";

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //1
        String servletName = servletConfig.getServletName();// com.test.app.Servlet01
        //2
        //程序加载的时候可以设定一些初始化的参数,和servletRequest.getParameter()不一样,人家是从浏览器地址栏获取参数的。
        //ServletConfig.getInitParameter()是从web.xml获取参数的
        //基于注解取不到这样的东西,另外它用的很少。
        this.userName = servletConfig.getInitParameter("userName");
        //3.1
        Enumeration enStr = servletConfig.getInitParameterNames();//Enumeration有点类似于set集合,只是过时了抛弃了。
        //3.2
        Enumeration enumeration = servletConfig.getInitParameterNames();
        //4
        //servletConfig倾向于Servlet的实例的配置
        //servletContext倾向于全局的一个配置的信息
        ServletContext servletContext = servletConfig.getServletContext();//servlet上下文,整个servlet的管理者
        String servletContextName = servletContext.getServletContextName();
        String contextPath = servletContext.getContextPath();
        String serverInfo = servletContext.getServerInfo();
        // ServletContext同样有getInitParameter和getInitParameterNames
        //web.xml中
        //    
        //        param0
        //        value0
        //    
        // String xxxx = servletContext.getInitParameter("xxxx");
        //Enumeration initParameterNames = servletContext.getInitParameterNames();
        System.out.println(servletContextName+"n"+contextPath+"n"+serverInfo);

        System.out.println("Serverlet init");
        System.out.println("tServerlet Name:" + servletName);//Serverlet Name:Servlet001
        System.out.println("tServerlet Init Parame:" + this.userName);//Serverlet Init Parame:admin
        System.out.println("tServerlet ParameterName:" + enStr);
        //遍历3.1 Enumeration enStr
        while (enStr.hasMoreElements()) {
            String element = enStr.nextElement();
            System.out.println("tServerlet ParameterName:" + element);
            System.out.println("tServerlet ParameterVlaue:" + servletConfig.getInitParameter(element));
        }
        //遍历3.2 Enumeration enumeration
        while (enumeration.hasMoreElements()) {
            String element = (String) enumeration.nextElement();
            System.out.println("tServerlet ParameterName:" + element);
            System.out.println("tServerlet ParameterVlaue:" + servletConfig.getInitParameter(element));
        }
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet service");
        servletResponse.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = servletResponse.getWriter();
        writer.write("hello! Client~!");
        writer.write("你好,客户端!");
        String id = servletRequest.getParameter("id");
        writer.write("收到id=" + id);
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("Servlet destroy");
    }
    public static void main(String[] args) {
        // 模拟tomcat创建对象的过程
        // http:localhost:8080/servlet到web.xml一解析拿到全类名,通过反射机制去创建对象
        String str = "com.test.app.Servlet01";
        Class clazz = null;
        try {
            clazz = Class.forName(str);
            Constructor constructor = clazz.getConstructor();
            System.out.println(constructor);//会报错
            // 因为在javaSE环境中加载不了Servlet01 实现的那个implements Servlet报错了
            // 去tomcat解压的目录下找到servlet.jar复制到当前工程下的lib目录下手动导入一下
            // 打印出:public com.test.app.Servlet01()
            Object object = constructor.newInstance();
            System.out.println(object);// com.test.app.Servlet01@43556938
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

问题:

 解决方案:

8、Servlet层次结构

 探究HttpServlet

@WebServlet("/servlet02")
public class Servlet02 extends HttpServlet {
    //顶端接口------------------------>底端接口
    //Servlet---->GenericServlet---->HttpServlet

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //地址栏发送的请求是get请求
        resp.getWriter().write("HtteServlet doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如果想要客户端发送post请求,要么写一个表单发送,要么用postman等工具发送post请求
        resp.getWriter().write("HtteServlet doPost");
    }
}

 

//本类:Servlet03=====手动写了一个GenericServlet,让Servlet04去继承,目的是模拟GenericServlet的用法
//@WebServlet("/servlet03")
public class Servlet03 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //在客户端中,无论get请求还是post请求
        //http://localhost:port/servlet03
        //请求的响应都是 hello world,它不会区分post请求和get请求
        servletResponse.getWriter().write("hello world");
    }

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

    @Override
    public void destroy() {

    }
}

@WebServlet("/servlet04")
public class Servlet04 extends Servlet03 {
    
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //获取请求类型
        String method = request.getMethod();//会返回GET或者POST
        System.out.println(method);
        switch (method) {
            case "GET":
                this.doGet(request, response);
                break;
            case "POST":
                this.doPost(request, response);
                break;
        }
    }

    //这里是让父类做个分发
    public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {

    }

    //这里是让父类做个分发
    public void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {

    }


}
@WebServlet("/servlet05")
public class Servlet05 extends Servlet04 {

    @Override
    public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        httpServletResponse.setContentType("text/html;charset=UTF-8");
        httpServletResponse.getWriter().write("山寨版HttpServlet doGet");
    }

    @Override
    public void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        httpServletResponse.setContentType("text/html;charset=UTF-8");
        httpServletResponse.getWriter().write("山寨版HttpServlet doPost");
    }
}

Get请求 

Post请求

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/696514.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号