JavaWeb实验课---4.1Servlet基础---2022.10

相关链接:

4.1.1 tomcat 部署静态资源

步骤:

  1. 目标:浏览器正常访问http://127.0.0.1/test/hello.html
    在tomcat/webapps下创建文件夹test,在test文件夹下创建hello.html
  2. 在终端启动tomcat
  3. 进入网址127.0.0.1:8080,查看tomcat是否启动成功
  4. 进入网址127.0.0.1:8080/test/hello.html,查看是否能正确打开

代码:

win系统只需要在tomcat/bin下找到startup.bat和shutup.bat即可启动/关闭。
mac电脑在终端启动/关闭tomcat:
我用的是方法3

启动的代码:

cd /Library/apache-tomcat-9.0.67/bin 
sudo chmod 755 /Library/apache-tomcat-9.0.67/bin/*.sh
sudo sh startup.sh

在这里插入图片描述
关闭的代码:

cd /Library/apache-tomcat-9.0.67/bin
sudo chmod 755 /Library/apache-tomcat-9.0.67/bin/*.sh
sudo sh shutdown.sh

在这里插入图片描述

实验结果:

在这里插入图片描述
http://127.0.0.1/test/hello.html可正常访问
在这里插入图片描述

4.1.2

步骤:

  1. 测试环境变量是否javac,下图为已配置javac
    在这里插入图片描述
  2. 在终端处输出javac “A.java的地址” -cp “servlet-api.jar文件的地址”

代码:

在这里插入图片描述

实验结果:

在这里插入图片描述

4.1.4 Servlet生命周期

步骤:

我们会发现B.java中没有main方法,也就是说并不是作为普通的java程序执行的,那么这些对象什么时候会被加载、执行呢?
我们可以观测一下它的生命周期。
在方法上打一些输出信息,通过输出信息观察它的生命周期。
Init()方法在程序启动时被调用了一次,Service()方法每访问一次网页都会调用一次,destroy()方法在停掉servlet时会被调用一次。

代码:

@WebServlet("/bbb")
public class B implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("call init()");
    }
    @Override
    public ServletConfig getServletConfig() {
        System.out.println("call getServletConfig()");
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("call service()");
        servletResponse.getWriter().println("hello bbbb3");
    }
    @Override
    public String getServletInfo() {
        System.out.println("call getServletInfo()");
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("call destroy()");
    }
}

实验结果:

有两个方法被调用到了,init()方法和service()方法
在这里插入图片描述
在这里插入图片描述
每刷新一次,service()方法都会得到调用,init()方法只会执行一次
在这里插入图片描述
停掉Servlet执行了destroy()方法
在这里插入图片描述

4.1.5 继承 GenericServlet

代码:

@WebServlet("/ccc")
public class C extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.getWriter().write("hello c");
    }
}

实验结果:

在这里插入图片描述

4.1.6 继承HttpServlet

步骤:

  1. 创建D.java文件
  2. 调用doGet方法,用resp的getWriter()方法输出context的路径
  3. 通过super调用父类里的doGet方法,运行程序,结果会报错405,并且有乱码
  4. 解决乱码:加一句:resp.setContentType(“text/html;charset=utf-8”)

response.setContentType(MIME)例如web浏览器就是通过MIME类型来判断文件是GIF图片。通过MIME类型来处理json字符串。

代码:

@WebServlet("/ddd")
public class D extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        super.doGet(req, resp);
        resp.getWriter().append("Served at: ").append(req.getContextPath());
    }

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

实验结果:

在这里插入图片描述
在这里插入图片描述
解决乱码后:
在这里插入图片描述

4.1.7 Servlet的URL配置

步骤:

  1. 创建ServletA、ServletB、ServletC三个java文件,调用respgetWrite()方法,分别输出<h1>ServletA或B或C</Servlet>
  2. 在web.xml文件中配置URL
  3. ServletA的URL配置语句中
    其中:/a,/aa为准确匹配;/a/*为路径匹配;/*也为路径匹配,代表所有的
  4. ServletB的URL配置语句中
    其中:/b为精确匹配,*.do扩展名匹配(扩展名匹配和路径匹配两者只能选一个)
  5. ServletC的URL配置语句中
    其中:/c为精确匹配,/为默认匹配(如果其他Servlet都不能满足,我们就默认选它)
  6. 在@WebServlet()中配置URL

代码:

ServletA(import部分省略)

//@WebServlet({"/a","/aa"})
public class ServletA extends GenericServlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("# call service A");
        servletResponse.setContentType("text/html;");
        servletResponse.getWriter().write("<h1>ServletA</h1>");
    }
}

web.xml

<servlet>
        <servlet-name>testA</servlet-name>
        <servlet-class>test.mapping.ServletA</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testA</servlet-name>
<!--        <url-pattern>/*</url-pattern>-->
        <url-pattern>/a/*</url-pattern> <!--路径匹配:只要是/a开头的都可以-->
        <url-pattern>/a</url-pattern>
        <url-pattern>/aa</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>testB</servlet-name>
        <servlet-class>test.mapping.ServletB</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testB</servlet-name>
        <url-pattern>*.do</url-pattern> <!-- -->
        <url-pattern>/b</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>testC</servlet-name>
        <servlet-class>test.mapping.ServletC</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testC</servlet-name>
        <url-pattern>/</url-pattern>    <—默认匹配-->
        <url-pattern>/c</url-pattern>   <!--精确匹配-->
    </servlet-mapping>

实验结果:

精确匹配:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其他匹配:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
/a/x.do:路径比配优先级比更高
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
/*打开后:
在这里插入图片描述
在这里插入图片描述
ServletC的/和ServletA的/*都注释掉
在这里插入图片描述
两个都不注释的结果:
在这里插入图片描述
只注释/的结果是ServletC

4.1.8 ServletConfig接口的使用

步骤:

  1. 创建项目ch0403,创建ServletConfigTest.java,实现一个接口Sevrlet,实现接口里的4个抽象方法:init(), getServletConfig(), service(), getServletInfo(), destroy()
  • 通过web.xml配置Servlet的url
  • 在web.xml的中配置三组初始化参数:…
  • 这些参数,如何让程序输出呢?通过init()方法得到参数。Tomcat在调用init()方法时,会把三组参数封装在ServletConfig里面,就可以用config拿到。getInitParamter()拿到参数对应的值,sout输出在控制台。
  1. 定义一个config对象。Init()方法调用时,参数config被tomcat传进来了,就把它保存下来。保存:this.config = config,tomcat传进来的是config,把它赋值到this.config,即我们在外面定义的对象,那么外面的config就有值了。
  • getServlet()方法返回config
  • 程序运行时,想在浏览器页面上输出,就需要在service()里调用getServletConfig()方法拿到config,再用resp的getWrite()方法输出
  1. 通过getInitParameterNames()方法拿到所有参数的名字,接口Enumeration有一个方法hasMoreElements(),它返回true,表示还有下一个元素。用Enumeration接口nextElement()方法取出下个元素。
  • 用config的getInitParamter方法拿到参数对应的值
  • 再输出参数名和值。

代码:

Java代码:

@WebServlet(value = "/config2", initParams = {
        @WebInitParam(name = "user", value = "114"),
        @WebInitParam(name = "pwd", value = "444"),
},loadOnStartup = 2)
public class ServletConfigTest implements Servlet {
    private ServletConfig config;
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.config=servletConfig;

        System.out.println(servletConfig.getServletName());
        System.out.println(servletConfig.getInitParameter("user"));
        System.out.println(servletConfig.getInitParameter("pwd"));
        System.out.println(servletConfig.getInitParameter("maxtimes"));

        Enumeration<String> paramNames = servletConfig.getInitParameterNames();
        while (paramNames.hasMoreElements()){
            String paramName = paramNames.nextElement();
            String value = config.getInitParameter(paramName);
            System.out.println(paramName + "->" + value);
        }
    }
    @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletConfig config = getServletConfig();
        servletResponse.getWriter().println("in servletConfig test, user:" + config.getInitParameter("user"));
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
}

web.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-name>testConfig</servlet-name>
        <servlet-class>ServletConfigTest</servlet-class>
        <init-param>
            <param-name>user</param-name>
            <param-value>zhang3</param-value>
        </init-param>
        <init-param>
            <param-name>pwd</param-name>
            <param-value>333</param-value>
        </init-param>
        <init-param>
            <param-name>maxtimes</param-name>
            <param-value>3</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>testConfig</servlet-name>
        <url-pattern>/config</url-pattern>
    </servlet-mapping>
</web-app>

实验结果:


倒数第三行为null,是因为在@WebServlet()中我们没给maxtimes初始化参数值
在这里插入图片描述
在这里插入图片描述

4.1.9 ServletContext接口的使用

步骤:

实验1目标:作为域对象使用,实现Servlet间共享数据;
实验2目标:读取Web应用路径、资源文件;
实验3目标:获取Web应用程序的初始化参数
Ch0404-1的步骤:
ServletA:

  1. 创建ServletA,继承GeneriServlet
  2. 通过getServletContext()先拿到ServletContext
  3. 往context里写数据
  4. 通过res的getWriter()方法显示:ServletA: ser username
    ServletB:
  5. Service方法中,通过getServletContext()先拿到ServletContext
  6. 通过context调用getAttribute()方法去取数据,它的返回值类型为Object,我们需要的是字符串类型的,所以将它转换为字符串
  7. 用res的getWriter()方法在浏览器上显示ServletB: get username:,然后将得到的字符串输出出来。
    ServletC:
  8. 先拿到context
  9. Context调用removeAttribute(),将username给擦掉
  10. 在浏览器上显示ServletC: remove username
    web.xml中配置ServletA、ServletB、ServletC的url

Ch0404-2的步骤:
11. 先拿到ServletContext
12. 调用getMajorVersion()和getMinorVersion()方法,得到主版本号和次版本号。将其输出,显示到页面上
13. 调用getMimeType()方法,得到文件类型,输出
14. 调用getServerInfo()方法,该方法返回服务器的名称和版本号,输出
15. 调用getServletContextName()方法,得到当前Web应用程序的上下文名称,也就是元素中path属性的斜杆(/)后面的内容,即’demo’
16. 调用getContextPath()方法,得到当前Web应用程序的上下文路径,也就是标签中path属性值,’/demo’
17. 调用getRealPath(hi.html)输出hi.html的真实路径(在电脑里的路径)
创建datal.prop文件放在web—WEB-INF目录下,用getResourceAsStream()方法获得里面的内容,读到输入流InputStream中
18. 新建一个Properties对象,解析输入流里的数据
19. 通过ps.getProperty()方法,用属性名,输出里面的内容

Ch0404-3的步骤:
20. 拿到一个ServletContext对象,一个PrintWriter对象
21. sout()是在控制台上输出,pw.write()是在浏览器上展示,getInitParam()获得原始数据
22. 在web.xml文件中配置参数和参数值### 代码

代码:

ch0404-1

public class ServletA extends GenericServlet { 
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext context = getServletContext();
        context.setAttribute("username","zhang3");
        servletResponse.setContentType("text/html;");
        servletResponse.getWriter().write("<h1>ServletA: set username</h1>");
    }
}
public class ServletB extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext context = getServletContext();
        String userName = "" + context.getAttribute("username");
        servletResponse.setContentType("text/html;");
        servletResponse.getWriter().write("<h1>ServletB: get username:" + userName + "</h1>");
    }
}

public class ServletC extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        ServletContext context = getServletContext();
        context.removeAttribute("username");
        servletResponse.setContentType("text/html;");
        servletResponse.getWriter().write("<h1>ServletC: remove username </h1>");
    }
}
   <servlet>
        <servlet-name>testA</servlet-name>
        <servlet-class>test.mapping.ServletA</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testA</servlet-name>
        <url-pattern>/a</url-pattern>
        <url-pattern>/set</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>testB</servlet-name>
        <servlet-class>test.mapping.ServletB</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testB</servlet-name>
        <url-pattern>/b</url-pattern>
        <url-pattern>/read</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>testC</servlet-name>
        <servlet-class>test.mapping.ServletC</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testC</servlet-name>
        <url-pattern>/c</url-pattern>
        <url-pattern>/remove</url-pattern>
    </servlet-mapping>
</web-app>

ch0404-2

@WebServlet("/x2")
public class ServletContext2 extends GenericServlet {

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext sc = getServletContext();
        int majorV = sc.getMajorVersion();
        int minorV = sc.getMinorVersion();
        PrintWriter pw = servletResponse.getWriter();
        System.out.println("version:" + majorV + ",minorV:" + minorV);
        pw.println("version:" + majorV + ",minorV:" + minorV);

        pw.println("mime type( jpd):" + sc.getMimeType("a.jpg"));
        pw.println("Server Info:" + sc.getServerInfo());
        pw.println("Server getServletContextName:" + sc.getServletContextName());
        pw.println("Server getContextPath:" + sc.getContextPath());
        pw.println("Server realPath:" + sc.getRealPath("hi.html"));

        InputStream in = sc.getResourceAsStream("/WEB-INF/classes/datal.prop");
        Properties ps = new Properties();
        ps.load(in);
        in.close();
        pw.println("read config, db.user:" + ps.getProperty("db.user"));
        pw.println("read config, db.pwd:" + ps.getProperty("db.pwd"));
    }
}
db.user = root
db.pwd = 123456

ch0404-3

@WebServlet("/x3")
public class ServletContext3 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext context = getServletContext();
        PrintWriter pw = servletResponse.getWriter();

        System.out.println("school:" + context.getInitParameter("school"));
        System.out.println("tel:" + context.getInitParameter("tel"));
        pw.write("school:" + context.getInitParameter("school"));
        pw.write("tel:" + context.getInitParameter("tel"));
    }
}
    <context-param>
        <param-name>school</param-name>
        <param-value>cqrk</param-value>
    </context-param>
    <context-param>
        <param-name>tel</param-name>
        <param-value>123456</param-value>
    </context-param>

实验结果:

Ch0404-1的实验结果:

  1. ServletB最开始没有数据

在这里插入图片描述
2. 打开ServletA设置username
在这里插入图片描述
3. 再打开ServletB就可以看到username

在这里插入图片描述
4. 打开ServletC删除数据

在这里插入图片描述
5. 再看ServletB,发现数据空了

在这里插入图片描述
Ch0404-2运行结果:
在这里插入图片描述
Ch0404-3运行结果:

4.1.10.Servlet实践作业(页面及访问次数统计)

步骤:

  • PageServlet
  1. 创建一个Web Project,命名为ch0405。在src目录下创建一个PageServlet.java文件,继承自GenericServlet,重写service()方法
  2. 定义一个int类型的对象pageCount,每次访问本页面,在service方法中pageCount++
  3. 通过ServletResponse输出pageCount的值
  • SiteServlet
  1. 创建SiteServlet1和SiteServlet2,两个class文件
  2. 定义context,
  3. 利用context.getAttribute去获取appCounter对应的值(int类型),用data接受
  4. 如果取出来的data是空值,data=1;否则data+1
  5. 利用context.setAttribute将appCounter写进去
  6. 再用ServletReponse输出appCounter
  7. SiteServlet1、SiteServlet2、PageServlet都复制一份

代码:

@WebServlet("/PageServlet")
public class PagesServlet extends GenericServlet {
    private int pageCount = 0;
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        pageCount++;
        ServletContext context = getServletContext( );
        Object data = context.getAttribute("appCounter");
        if(data == null){
            data = 1;
        } else{
            data = (Integer)data + 1;//强制转化,data类型改为int
        }
        context.setAttribute("appCounter", data);
        servletResponse.getWriter().println("appCounter:" + data);
        servletResponse.getWriter().println("PageCount = " + pageCount);
    }
}
@WebServlet("/site1")
public class SiteServlet1 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        ServletContext context = getServletContext();

        Object data = context.getAttribute("appCounter");
        if(data == null){
            data = 1;
        } else{
            data = (Integer)data + 1;//强制转化,data类型改为int
        }
        context.setAttribute("appCounter", data);
        servletResponse.getWriter().println("appCounter:" + data);
    }
}
public class SiteServlet2 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        ServletContext context = getServletContext();
        Object data = context.getAttribute("appCounter");
        if(data == null){
            data = 1;
        } else{
            data = (Integer)data + 1;//强制转化,data类型改为int
        }
        context.setAttribute("appCounter", data);
        servletResponse.getWriter().println("appCounter:" + data);
    }
}

实验结果:

PageServlet:
在这里插入图片描述
Site页面更新appCounter
在这里插入图片描述
更新后的PageServlet:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值