使用Tomcat搭建一个Servlet项目

  • Post author:
  • Post category:其他




Tomcat

Tomcat是一个HTTP服务器,在TCP服务器的基础上加了一些额外的功能,能够解析请求中的HTTP报文,把请求转换成结构化数据(对象),也能很方便的构造HTTP响应。HTTP服务器提供了一组API,方便程序员直接调用来操作HTTP协议,从而简化程序员的开发工程。servlet程序是一个war后缀的文件,tomcat会自动把war解压缩得到一个目录,每个war其实就对应了一个webapp,一个Tomcat可以部署多个servlet程序,所以可以把Tomcat称为“servlet的容器”。



maven

maven是java世界中非常知名的“工程管理工具”/“构建工具”,核心功能:管理依赖,构建/编译,打包。maven存在的意义就是能够直接把这些操作串起来,一气呵成。

  • 依赖:进行A操作前,先执行B操作
  • 构建/编译:调用jdk
  • 打包:把java代码构造成jar或者war



使用



创建maven项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



管理依赖

在这里插入图片描述

在这里插入图片描述



实践

完成一个servlet的hello world


1.创建一个maven项目



2.引入依赖


需要在代码中引入servlet api,这个api不是jdk内住的,而是第三方tomcat提供的,借助Maven直接引入。

在这里插入图片描述


3.创建目录结构


在这里插入图片描述

在这里插入图片描述

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>


4.编写servlet代码


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


5.打包和部署


使用smart tomcat插件


6.验证程序


在这里插入图片描述

可以这样认为:

一个Tomcat上可以同时部署多个网站,一个网站上又有多个页面,一个请求中的第一级路径用于告诉tomcat要访问的网站是哪个,第二级路径告诉tomcat要访问的页面是这个网站的那个页面。



使用总结

在这里插入图片描述



GET,POST请求应用场景

啥时候浏览器发的是GET请求?

  1. 直接在地址栏里输入URL
  2. 通过a标签跳转
  3. 通过img/link/script
  4. 通过form表单,method指定为GET
  5. 通过ajax,type指定为GET

啥时候浏览器发送的是POST请求?

  1. 通过form表单,method指定为POST
  2. 通过ajax,type类型为POST



Servlet运行原理

在这里插入图片描述



Tomcat伪代码



Tomcat初始化

1)让Tomcat先从指定的目录中找到所有要加载的Servlet类

前面部署的时候是把Servlet代码编译成了.class,然后打包成了war包。然后拷贝到了webapps里面。Tomcat就会从webapps里来找到哪些.class对应的Servlet类,并进行加载。

2)根据刚才类加载的结果,给这些类创建Servlet实例

在这里插入图片描述

3)实例创建好之后,就可以调用当前Servlet实例的init方法了

在这里插入图片描述

4)创建TCP socket,监听8080端口,等待有客户端来连接

在这里插入图片描述

5)如果循环退出了,Tomcat也要结束了就会一次循环调用每个Servlet的destroy方法

在这里插入图片描述



Tomcat处理请求

在这里插入图片描述

1)req司通过读取socket中的数据,然后爱按照HTTP协议的请求格式来解析的,构造成了一个HttpServletRequest对象,resq这里则是相当于new了一个空对象

2)判定当前要的顶球是否是静态文件,如果是静态文件就要读取文件内容,把文件内容够遭到resq对象的body中,并且返回这个resq对象

3)根据请求的URL来获取到使用哪个类来处理

URL里有两个路径。

第一级路径:Context Path,确定一个webapp

第二级路径:Servlet path,确定一个Servlet类

如果没有找到匹配的Servlet类就会返回404

4)根据刚才找到的Servlet对象,来调用service方法,在service方法内部又会进一步调用doGet/doPost,下面是service方法内部

在这里插入图片描述



Servlet的关键API



HTTPServlet

我们写的代码就是通过继承这个类,重写其中的方法来被Tomcat执行

在这里插入图片描述

在这里插入图片描述



HttpServletRequest和HttpServletResponse

在这里插入图片描述

在这里插入图片描述



例子1:

展示请求的响应

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<h3>首行部分</h3>");
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        stringBuilder.append("<h3>header部分</h3>");
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            String headerValue = req.getHeader(headerName);
            stringBuilder.append(headerName + ":" + headerValue + "<br>");
        }

        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write(stringBuilder.toString());
    }
}

在这里插入图片描述



例子2:

展示参数的请求

@WebServlet("/getParameter")
public class getParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userId = req.getParameter("userId");
        String classId = req.getParameter("classId");
        resp.getWriter().write("userId=" + userId + "classId=" + classId);
    }
}



body格式



请求body格式


1.x-www-form-urlencoded


获取参数的方式和GET一样,也是getParameter

在前端构造一个这样格式的请求


1)form表单


userId=1234&classId=5678

<form action="postGetParameter" method="post">
    <input type="text" name="userId">
    <input type="text" name="classId">
    <input type="submit" value="提交">
</form>


2)postman


在这里插入图片描述


3)json

可以使用第三方的库来直接处理json格式数据,主要使用的库叫做Jackson,通过maven把jackson这个库下载到本地并引入到项目中。

在浏览器前端代码中通过js构造json格式的请求

在这里插入图片描述

在这里插入图片描述

在java后端代码中通过jackson来进行出,需要使用jackson把请求body中的数据读取出来并解析成Java中的对象。

在这里插入图片描述

class User{
    public int userId;
    public int classId;
}
@WebServlet("/postJson")
public class PostJsonServlet extends HttpServlet {
    //1.创建一个Json的核心对象
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //2.读取body中的请求,然后使用ObjectMapper来解析成需要的对象
        //readValue就是把Json格式的字符串转成Java的对象
        //第一个参数表示对那个字符串进行转换,这个参数可以填成一个String,也可以填成一个InputStream对象,还可以填一个File
        //第二个参数表示要把这个JSON格式的字符串转成哪个Java对象
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        resp.getWriter().write("userId=" + user.userId + ",classId:" + user.classId);
    }
}

点击提交之后在浏览器控制台中就打印出来了服务器的响应数据,当前使用的是ajax的方式来提交数据,这个操作默认不会产生页面跳转,就和使用form风格差别很大。



响应body格式

在这里插入图片描述


例子1:


服务器返回状态码

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.getWriter().write("hello");
    }
}

在这里插入图片描述


例子2:


实现自动刷新这样的页面效果,给HTTP响应中设置一个header:Refresh即可

@WebServlet("/autoRefresh")
public class AutoRefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh", "1");
        resp.getWriter().write("timestamp:" + System.currentTimeMillis());
    }
}

例子3:

构造一个重定向,构造一个302

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(302);
        resp.setHeader("Location", "https://www.sogou.com");
    }
}



Cookie和Session

Servlet提供的关键API



HttpServletRequest类中的相关方法

HttpSession getSession():在服务器中获取会话,参数如果为true,则当不存在会话时创建会话;参数如果为false,则当不存在会话时返回null

Cookie[] getCookies():返回一个数组,包含客户端发送该请求的所有Cookie对象,会自动把Cookie中的东西解析成键值对。每个Cookie对象又包含了两个属性name和value


在调用getSession的时候具体要做的事情:


1.创建会话

首先现获取请求中cookie里面的sessionId字段(相当于会话的身份标识),判定这个sessionId是否存在当前服务器上存在,如果不存在则进入创建会话逻辑。创建会话,会创建一个HttpSession对象,并且生成一个sessionId(是一个很长的数字,通常是用16进制来表示,能够保证唯一性),接下来就会把这个seesionId作为key,把这个HttpSession对象作为value,把这个键值对给保存到服务器内存的一个“哈希表”这样的结构中。再然后服务器就会返回一个HTTP响应,把sessionId通过Set-Cookie字段返回给浏览器,浏览器就可以保存这个sessionId到cookie中了。

2.获取会话

先获取到请求中的cookie里面的sessionId字段,判定这个sessionId是否存在当前服务器上存在,如果有就直接查询出这个HttpSession对象,并且通过返回值返回回去。


HttpSession


这个对象本质上也是一个键值对的结构,允许程序员往HttpSession对象中,存储人的键值对数据,key必须是String,value是一个Object

在这里插入图片描述

HttpSession里面的每个键值对称为属性。


HttpSession提供了两个方法:


getAttribute取键值对

setAttribute存键值对


Cookie提供的方法:


String getName():该方法返回cookie的名称,名称在创建后不能改变。

String getValue():该方法获取与cookie关联的值

void setValue(String newValue):该方法设置于cookie关联的值



HttpServletResponse类中的相关方法

void addCookie(Cookie cookie):把指定的cookie添加到响应中,响应中就可以根据addCookie这个方法,来添加一个Cookie信息到响应报文中。这里添加进来的键值对就会作为HTTP响应中的Set-Cookie字段来表示。



版权声明:本文为weixin_46429649原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。