Servlet入门

Servlet是什么

 Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

简单的来说,Servlet就是实现了Servlet接口的类,作用就是用来接收浏览器请求并做出相应。

Servlet本身不能独立运行,需要在一个web应用中运行的,而一个web应用是部署在tomcat中的,所以开发一个Servlet需要如下几个步骤

  • 创建web应用项目
  • 编写Servlet代码
  • 部署到tomcat中

Servlet的工作流程

 

  • 浏览器发送请求到服务器
  • 服务器调用Servlet,Servlet根据请求的内容作出响应,并传输回服务器
  • 服务器将响应内容返回给浏览器

用户请求致使Servlet容器调用Servlet的Service方法,并传入一个ServletRequest对象和一个ServletResponse对象。ServletRequest对象和ServletResponse对象都是由Servlet容器(Tomcat)封装好的,可以直接使用。

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

这是我们平时写Servlet继承的HttpServlet类里的service方法的具体实现,主要做的就是判断请求的方式,根据请求的方式来执行相应的方法,而在HttpServlet对这些doGet方法有具体的实现,所以我们在写Servlet的时候要做的,就是根据需求重写这些处理请求的方法,给出响应的信息。

编写第一个Servlet类

package com.zwq.servlet;

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

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        writer.print("Hello Servlet");
    }
}

新建一个类继承自HttpServlet,然后重写他的doGet方法,然后就可以在方法体内执行需要的业务需求了,这里做的是访问时在网页上显示Hello Servlet。

配置工作

我们写好了Servlet类,还需要对它进行一些配置,以便让Tomcat知道,在访问某个路径的时候,要读取哪个类底下的哪一个Servlet。

打开这个web.xml文件,添加两个标签,一个是<servlet>,另一个是<servlet-mapping>。

<?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"
         metadata-complete="true">

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

</web-app>

上下两个servlet-name 里的名字是可以随便取的,但要保持一致。servlet-class是指定编写的Servlet的路径,url-pattern里的/hello的意思是,当我们在浏览器里访问/hello时,会调用这个HelloServlet进行处理。

做完这些后,将项目部署到Tomcat上,运行Tomcat访问localhost:8080/hello,就能看到输出的结果了。

ServletContext对象

web容器在启动的时候,会为每一个web程序分配一个ServletContext对象,它代表着当前web程序,所有Servlet共享一个ServletContext对象,所以可以通过这个对象来实现Servlet之间的数据传输。

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("name","芜湖");
    }
}

修改HelloServlet,获取他的ServletContext对象,往里添加一个名字为name的属性。然后新建一个新的Servlet,做好上文最中的准备工作,继承HttpServlet,重写需要的方法,在XML里注册Servlet,这里重点介绍一下重写的doGet方法。

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String name = (String) servletContext.getAttribute("name");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("通过ServletContext传输的数据:"+name);

    }
}

首先先拿到了当前Servlet的ServletContext对象,这个ServletContext和HelloServlet类里的ServletContext是同一个对象,然后调用getAttribute,传入属性的名字,就能获得之前在HelloSe里传入的属性,最后还需要设置一下编码,否则中文会乱码。然后重启Tomcat,访问localhost:8080/get。

如果直接访问/get的话,会输出一个null,原因是name的值是在HelloServlet里传入的,直接访问/get的话,name属性里是没有值的,自然只能输出一个null,所以要先访问一次localhost:8080/hello,网页上什么都不会显示,但是会传一个值到ServletContext里,这样就能在GetServlet里获取到了。

RequestDispatcher请求转发

请求转发,顾名思义就是将请求转发到另一个另一个Servlet上,就可以在一次访问里同时调用多个Servlet,RequestDispatcher其实是一个接口,里面只定义了两个方法,分别是include和forward。

修改一下HelloServlet里的doGet方法,在HelloServlet里也输出一些文字,然后调用RequestDispatcher,以forward的方式将请求转发至/get。

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("name","芜湖");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().println("我是HelloServlet里的数据!!!!!!");
        servletContext.getRequestDispatcher("/get").forward(req,resp);
    }

重启Tomcat,访问localhost:8080/hello,会发现刚刚设置的文字并没有输出,显示的内容都是GetServlet里的,而且直接输出了具体的值,而不是null,这就是转发请求所导致的。

如果调用的是include方法,就会保留第一个Servlet里的内容。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值