【Servlet】

Servlet


在学习Servlet之前,先了解一个工具

tomcat

在本地安装下载一个tomcat的安装包,安装以后是这样的

在这里插入图片描述

Servlet项目创建的流程

1、创建项目

在这里插入图片描述

创建一个maven项目

2、引入依赖

从官网添加对应tomcat版本的依赖

下面是3.1.0版本的依赖,对应tomcat8

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
    <build>
        <finalName>hello_servlet</finalName>
    </build>
    <packaging>war</packaging>

3、创建目录

在这里插入图片描述

创建文件夹webapp,文件结果如图

在web.xml中添加

<!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、编写代码

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello ");


        resp.getWriter().write("hello java");
    }
}

5、打包程序

在这里插入图片描述

使用package进行打包成war包

6、部署到tomcat 7、运行程序
在这里插入图片描述

为了实现更简单的启动tomcat,可以在IDEA中添加插件smart tomact

在这里插入图片描述

Servlet中常用的API

HttpServlet

方法名称调用时机
init在 HttpServlet 实例化之后被调用一次
destory在 HttpServlet 实例不再使用的时候调用一次
service收到 HTTP 请求的时候调用
doGet收到 GET 请求的时候调用(由 service 方法调用)
doPost收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/…收到其他请求的时候调用(由 service 方法调用)
init 是在被实例化对象之后被自动调用一次
  @Override
    public void init() throws ServletException {
        System.out.println("我有一些想要重写的init描述");
    }

service是调用其他方法的方法

在这里插入图片描述

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的生命周期

答:
1. 在开始的时候执行init
2. 在收到请求的时候调用service
3. 在结束的时候调用destroy

HttpServletRequest

表示的是http请求

String getProtocol() 返回请求协议的名称和版本。

String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT

String getRequestURI() 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。

String getContextPath() 返回指示请求上下文的请求 URI 部分。

String getQueryString() 返回包含在路径后的请求 URL 中的查询字符串。

Enumeration getParameterNames()返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。

String getParameter(String name) 以字符串形式返回请求参数的值,或者如果参数不存在则返回nullString[]getParameterValues(String name) 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 nullEnumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名。

String getHeader(String name)以字符串形式返回指定的请求头的值。

String getCharacterEncoding() 返回请求主体中使用的字符编码的名称。

String getContentType() 返回请求主体的 MIME 类型,如果不知道类型则返回 nullint getContentLength() 以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1InputStream getInputStream()用于读取请求的 body 内容. 返回一个 InputStream 对象.

使用:

@WebServlet("/showHttpRequest")
public class ShowHttpRequest extends HttpServlet {

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

        StringBuilder stringBuilder = new StringBuilder();

        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>");

        resp.setContentType("text/html");
      
      
        //获取所有header中的名称
        Enumeration<String> headerNames =  req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            stringBuilder.append(headerName+ ":" +req.getHeader(headerName));
            stringBuilder.append("<br>");
        }

        resp.getWriter().write(stringBuilder.toString());

        
    }
}
前端给后端传参

三种前端给后端传递数据的方式

1、GET query string
@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
        //返回响应
        resp.setContentType("text/html");
        resp.getWriter().write("studentId= "+"  "+studentId+"classId= "+classId);
    }
}

如果studentId和classId没有传值,就为null

在这里插入图片描述

2、POST form
<form action="postParameter" method="post">
    <input type="text" name="studentId">
    <input type="text" name="classId">
    <input type="submit" value="提交">
</form>
@WebServlet("/postParameter")
public class PostParameter extends HttpServlet {

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

        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");

        resp.setContentType("text/html");
        resp.getWriter().write("studentId= "+"  "+studentId+"classId= "+classId);
    }
}

form表单一定会触发页面跳转,可以根据key获取value

在这里插入图片描述

详解:

在这里插入图片描述

★★前后端交互基本流程

前端通过form表单构造出请求提交到tomcat服务器,tomcat服务器构造出req和resp对象,值存储在req对象中,然后通过req的getParamerter方法可以拿到req里面的值,再通过resp对象构造响应,把resp写回到tomcat服务器中,tomcat服务器再返回响应给前端

在这里插入图片描述

在Java的Servlet编程中,可以使用 request.getParameter 方法来获取HTTP请求中的参数值。如果请求是通过HTML表单提交的,getParameter 方法将返回表单字段的值。如果请求是通过URL传递的查询参数,getParameter 方法将返回查询参数的值

3、POST json

前端可以通过ajax的方式来进行构造出内容

更简单的可以使用postman

getInputStream()
用于读取请求的 body 内容. 返回一个 InputStream 对象.

在这里插入图片描述

编写后端代码:

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过这个方法来处理json的格式
        //把req对象中的body给读取出来
        //通过getInputStream
        //在流对象中读多少字节?取决于Content—Length

        int length = req.getContentLength();
        //开辟数组
      	//根据json字符串的长度来开辟数组
        byte[] buffer = new byte[length];

        //读取字节
        InputStream inputStream = req.getInputStream();
        //读取到数组中
        inputStream.read(buffer);

        //把这个字节数组构造成String
        String body = new String(buffer);
        System.out.println("body= "+body);
        resp.getWriter().write(body);

    }
}

●●在Servlet编程中,当接收到HTTP请求时,服务器会创建一个 HttpServletRequest 对象来表示该请求,其中包含了请求的相关信息,如请求参数、请求头、请求体等。通过调用 getInputStream 方法,可以从该对象中获取请求体的输入流,从而读取请求的内容。

在这里插入图片描述

★使用json

因为用json传参不能够像传html的表单(form)一样,根据key的值来获取到studentId 和 classId中的value

使用jackson第三方库可以更加方便地读取

  1. 引入 Jackson 相关的依赖

  2.  InputStream inputStream = request.getInputStream();
    

    创建 ObjectMapper 对象:ObjectMapper 是 Jackson 库的核心类,用于处理 JSON 数据的序列化和反序列化。创建一个 ObjectMapper 对象来进行后续的 JSON 处理操作

    ObjectMapper objectMapper = new ObjectMapper();
    
  3. 使用 ObjectMapper 进行反序列化:利用 ObjectMapper 对象的 readValue 方法,将输入流中的 JSON 数据反序列化为对象或数据结构。这可以是一个 Java 类、集合、Map 等。

    readValue()是把从request中获取到的字符串转换成一个对象
      这里的类是YourClass readValue的第二个参数就是要转换成的YourClass对象
    YourClass yourObject = objectMapper.readValue(inputStream, YourClass.class);
    
  4. 对反序列化后的对象进行进一步处理:根据您的需求,对反序列化后的对象 yourObject 进行进一步的处理和操作。

●●●readValue的过程:

在这里插入图片描述

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在Servlet编程中,当接收到HTTP请求时,服务器会创建一个 HttpServletRequest 对象来表示该请求,
        // 其中包含了请求的相关信息,如请求参数、请求头、请求体等。通过调用 getInputStream 方法,
        // 可以从该对象中获取请求体的输入流,从而读取请求的内容。
        InputStream inputStream = req.getInputStream();
        //创建这个对象
        ObjectMapper objectMapper = new ObjectMapper();

        //把从请求中得到的字符串构造成一个类对象
        Student student = objectMapper.readValue(inputStream,Student.class);

        System.out.println(student.getStudentId()+","+student.getClassId());
        String jsonString = objectMapper.writeValueAsString(student);
        resp.getWriter().write(jsonString);
        System.out.println(jsonString);
        
    }
}
  • 方法介绍

writeValue 方法用于将 Java 对象或数据结构序列化为 JSON 数据

readValue 方法用于将 JSON 数据反序列化为指定的 Java 对象或数据结构

HttpServletResponse

void setStatus(int sc) 为该响应设置状态码。

void setHeader(String name,String value)设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值.

void addHeader(String name, String value)添加一个带有给定的名称和值的 header. 如果 name 已经存在,
不覆盖旧的值, 并列添加新的键值对

void setContentType(String type) 设置被发送到客户端的响应的内容类型。

void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8void sendRedirect(String location) 使用指定的重定向位置 URL 发送临时重定向响应到客户端。

PrintWriter getWriter() 用于往 body 中写入文本格式数据.

OutputStream getOutputStream() 用于往 body 中写入二进制格式数据.

1、设置字符集

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String studentId = req.getParameter("studentId");
        String classId = req.getParameter("classId");
      
        //返回响应
        resp.setContentType("text/html");
      
     //还可以这样设置字符集
      resp.setContentType("text/html,charset=utf8");
        //设置字符集
        resp.setCharacterEncoding("utf8");
        resp.getWriter().write("学生Id= " +"  "+studentId+"  班级Id= "+classId);
      //如果
    }
}

在这里插入图片描述

2、设置重定向

@WebServlet("/sendRedirect")
public class SendRedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

      //1、设置重定向
      //resp.sendRedirect("https://www.baidu.com");

      //除了直接设置重定向以外,还可以通过设置状态码和设置响应报头(header)里面的Location的值
      //的方式来进行
        //设置状态码
      //2、
        resp.setStatus(302);
        resp.setHeader("Location","https://www.baidu.com");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值