servlet的三个重要的类(httpServlet 、httpServletRequst、 httpServletResponse)

一、httpServlet 

写一个servlet代码一般都是要继承httpServlet 这个类,然后重写里面的方法

但是它有一个特点,根据之前写的代码,我们发现好像没有写main方法也能正常执行。

原因是:这个代码不是直接运行的,而是放到tomcat上运行的

换句话说,tomcat里就有main方法

1.httpServlet的几个主要方法

init方法是初始化操作

service 收到http请求的时候调用(一般会被doGet/doPost替代)

destroy当不在使用httpServlet实例的时候,调用,来销毁实例(释放资源)

        以上三个描述了 servlet的声明周期(经典面试题),就是描述一下这三个方法,什么时间干什么事(调用什么方法)。(在实际开发中,很少会用到,一般都是出现在面试题中)

初始化执行init方法,每次收到http请求调用 service方法,结束前执行destroy方法释放资源

        除了init方法,其他方法都可以在子类中重写,并且重写后,不用手动调用,tomcat会在何时机自动调用

        destroy方法,大概率事执行不到的。一个servlet 不用了,说明tomcat要关闭了

tomcat关闭有两种方式:

        1.直接干掉tomcat 进程(比如直接在任务管理器中 结束任务 , 或者直接点 叉关闭),完全来不及调用destroy。

        2.通过8005 管理端口,给tomcat 发送一个“停机”指令,这个时候是能执行到destroy的。

       但是通常,都是用第一种方式(直接干掉进程)来关闭servlet的。

使用HttpServlet类

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/method") //指定路径
public class MethodServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPost");//控制台中打印resp.getWriter().write("doPost");//http的响应内容,显示在浏览器上}@Overrideprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPut");//控制台中打印resp.getWriter().write("doPut");//http的响应内容,显示在浏览器上}protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doDelete");//控制台中打印resp.getWriter().write("doDelete");//http的响应内容,显示在浏览器上}
}

二、HttpServletRequest类

     可以发现HttpServletRequest的方法里面,都是get方法(读方法),没有set方法(写方法)

        原因是,当前拿到的HttpServletRequest,这里的数据是来自于客户端发来的。这些数据的内容是已经确定下来了,程序员是不应该修改的。

(这种框架做出了限制,避免了程序员不小心把原有的请求修改坏的情况了)

经常将URI 、URL混着用

URI :统一资源标识符(相当于身份证号)

URL:统一资源定位符(相当于住址)

1)使用HttpServletRequest类的方法

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;@WebServlet("/show")
public class ShowRequestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//调用上述api,把得到的结果构造成一个字符串,统一返回给客户端StringBuilder stringBuilder = new StringBuilder();//使用stringBuilder把HTTP请求中的数据记录下来stringBuilder.append(req.getProtocol());//获取HTTP协议版本stringBuilder.append("<br>");//html中的换行stringBuilder.append(req.getMethod());//获取HTTP请求方法(get/post)stringBuilder.append("<br>");stringBuilder.append(req.getRequestURI());//获取链接地址stringBuilder.append("<br>");stringBuilder.append(req.getContextPath());//获取一级地址stringBuilder.append("<br>");stringBuilder.append(req.getQueryString());//获取quary stringstringBuilder.append("<br>");//获取所有的 headerEnumeration<String> headernames = req.getHeaderNames();while(headernames.hasMoreElements()){String key = headernames.nextElement();String value = req.getHeader(key);stringBuilder.append(key + ":" + value + "<br>");}//返回响应是,一定要做的事情,告诉浏览器,当前是啥类型resp.setContentType("text/html;charset=utf8");//将stringBuild中的内容以字符串形式返回到响应中resp.getWriter().write(stringBuilder.toString());}
}

如果不写query string这里的a和b,那么这里就是a=1&b=2这里就是null 

2)获取Patameter(query string)

query string是url中 ?a=1&b=2 这种格式,是以键值对形式存在的

其中a 和 b 就是键值对的key,是由程序员自定的

前后端交互有三种方式:

一种是query string ,form表单,json格式(主流)

三种都差不多,具体用那种看个人习惯,以及公司既定的代码风格

servlet 天然支持 query string 和 form表单,而json本身是不支持的,但是可以引入第三方库

1.GET请求

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/getParameter")
public class GetParameterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//此处约定:请求中给定的query string 例如:username=zhangsan&password=123//上述 query string,就会被tomcat 给自动解析成一个 Map 这样的结构//getParameter 就是在查询 Map<String,String>里的内容String username = req.getParameter("username");String password = req.getParameter("password");//就可以拿到这些内容之后,做一些其他的任意处理System.out.println("username =" + username);System.out.println("password =" + password);resp.setContentType("text/html charset=utf-8");resp.getWriter().write("ok");}}

不写string是这里是null 

当写了我们自定义的username和password的时候,这里就能看见显示的query string的内容了

但是有一个需要注意的点:

当传入的query string的时候如果涉及到中文字符,需要用urlencode去进行编码

(如果不进行urlencode编码,有些浏览器可能无法识别,导致一些错误)

encode之后的结果发送给浏览器,浏览器能自动识别并进行urldecode解码

 

2.POST请求

import com.sun.prism.PresentableState;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//约定:前端构造形如这样的请求://POST / postParameter//Content-Type:x-www-form-urlencoded////username=zhangsan&password=123//就需要在后端代码中,把body中的值 给拿到//获取值的方法,仍然是 getParameterString username = req.getParameter("username");String password = req.getParameter("password");System.out.println("username=" + username);System.out.println("password=" + password);resp.setContentType("text/html;charset=utf8");resp.getWriter().write("okk");}
}

3)引入json的第三方库(jackson)

1.json的第三方库有很多,Jackson是spring官方推荐的库,也被spring集成起来了,对于后期学习spring比较方便

版本没有要求(也没有必要太新,稳定就行 选择2.15.0)

将这个代码点击,复制粘贴到pom.xml里,点击maven的刷新键,完成json第三方库安装

2.使用jackson(一个类,两个方法)

一个类:ObjectMapper 对象映射器 
两个方法
1-把json字符串,映射成一个Java对象。readValue
Request request = objectMapper.readValue(req.getInputStream(),Request.class);//Request.class 类对象(反射)
2-把一个Java对象,映射成json字符串 writeValueAsString
String respJson = objectMapper.writeValueAsString(response);

网络传输,使用json字符串。Java代码中各种逻辑,使用Java对象。

站在服务器的角度,收到的请求,就是json字符串,就需要把json字符串,先映射成Java对象,

再进行一系列的业务逻辑处理。处理完之后,可能还需要把得到的Java对象,映射会json字符串,并通过响应来返回。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.org.apache.regexp.internal.RE;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;//把 json格式的字符串请求 映射后的 Java对象
class Request{public String username;public String password;
}
class Response{public boolean ok;
}
@WebServlet("/json")
public class JsonParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//此处的约定请求格式如下://POST /json//Content-Type:application/json////{//  username:"zhangsan",//  password:"123"//}//此处也约定响应的格式(也按照 json 来组织)://{//  ok:true//}//把请求的 body 按照 json 格式解析成java对象ObjectMapper objectMapper = new ObjectMapper();Request request = objectMapper.readValue(req.getInputStream(),Request.class);//Request.class 类对象(反射)System.out.println("username=" + request.username);System.out.println("password" + request.password);Response response = new Response();response.ok = true;//把响应对象转成 json 字符串String respJson = objectMapper.writeValueAsString(response);resp.setContentType("application/json;charset=utf8");//设置字符集resp.getWriter().write(respJson);//返回json格式的字符串}
}

4)总结:如何进行前后端交互?如何获取前端传来的数据?

1.query string ( 使用 getParameter这个方法)

2.form表单  ( 使用 getParameter这个方法)

3.json(实际常用,导入json 的库 jackson,使用objectMapper对象和json方法)

三、HttpServletResponse类

主要方法

 1)setStatus设置状态码 和 sendError 设置状态码同时设置body返回的内容

1.setStatus设置状态码

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/Status")
public class StatusServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setStatus(404);//设置状态码为404 not found 找不到}
}

  

光有状态码,body里面没有内容,是空的,对用户不太友好,浏览器里什么内容也没有,不知道到底出现了什么问题

2.sendError 设置状态码同时设置body返回的内容

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/Status")
public class StatusServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        resp.setStatus(404);//设置状态码为404 not found 找不到resp.sendError(404,"哎呀~网页找不到啦~是不是出现问题啦?");}
}

 可以看到设置了状态码404 同时还设置了 提示内容

这个页面就是sendError生成的

2)通过setHeader属性,给响应中设置一些特殊的header

1.设置 refresh:1,让浏览器每秒刷新一次

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setHeader("refresh","1");//refresh浏览器刷新,1为时间,每一秒刷新一次resp.getWriter().write(" "+System.currentTimeMillis());//在浏览器显示当前时间}
}

观察发现好像每次并没有精确1s刷新,可能是一秒多一点

原因是:浏览器响应也需要时间,所以比原有的1s多一些

 2.构造重定向响应

1-状态码是 3开头(例如:302)

2-header 需要有一个Location属性,描述要跳转到哪里

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//方法一resp.setStatus(302);resp.setHeader("Location","http://www.baidu.com");//重定向/redirect这个网页到 www.baidu.com//方法二resp.sendRedirect("http://www.baidu.com");//两者效果一致}
}

(这几个类学完,就可以愉快的进行接下来的简单网站啦~~)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

共模电感饱和电流和额定电流的区别

共模电感饱和电流和额定电流是两个不同的概念&#xff0c;它们的区别如下&#xff1a; 1. 定义不同&#xff1a;共模电感饱和电流是指当通过共模电感的电流超过一定值时&#xff0c;共模电感的磁芯开始饱和&#xff0c;导致电感值下降。额定电流是指共模电感在正常工作条件下…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《应用图论建模输电网的电力现货市场出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

JavaSE图书管理系统实战

代码仓库地址&#xff1a;Java图书管理系统 1.前言 该项目将JavaSE的封装继承多态三大特性&#xff0c;使用了大量面向对象的操作&#xff0c;有利于巩固理解 &#xff08;1&#xff09;实现效果 2.实现步骤 第一步先把框架搭建起来&#xff0c;即创建出人&#xff1a;管理员和…

RocketMQ 02 功能大纲介绍

RocketMQ 02 主流的MQ有很多&#xff0c;比如ActiveMQ、RabbitMQ、RocketMQ、Kafka、ZeroMQ等。 之前阿里巴巴也是使用ActiveMQ&#xff0c;随着业务发展&#xff0c;ActiveMQ IO 模块出现瓶颈&#xff0c;后来阿里巴巴 通过一系列优化但是还是不能很好的解决&#xff0c;之后…

串口通信有哪些常见的应用领域?

串口通信是一种常见的数据通信方式&#xff0c;它使用串行接口在两个设备之间发送和接收数据。这种通信方式由于其简单性和广泛的支持&#xff0c;在多个应用领域中被广泛使用。下面是一些串口通信的常见应用领域&#xff1a; 工业自动化&#xff1a;串口通信在工业自动化中非常…

MySQL底层架构

MySQL底层架构 连接器 验证客户端连接的用户名密码、校验权限、维持和管理连接。 客户端如果超过 wailt_timeout 没有动静&#xff0c;连接器会主动将它断开&#xff0c;此时客户端再次发送请求的话&#xff0c;就会收到错误&#xff1a;lost connection to MySQL server dur…

【Modelsim】保持波形格式重编译and波形的保存与查看

文章目录 保持原波形格式重编译波形的保持与查看保存波形打开工程查看波形 保持原波形格式重编译 Modelsim 仿真设置好波形格式后&#xff0c;若需要修改代码并保持原波形格式重新查看波形&#xff0c;只需将文件重新编译后仿真即可。 1.修改代码后Project页面的代码状态变成…

外网如何访问内网数据库?

在当今信息时代&#xff0c;随着互联网的快速发展&#xff0c;很多企业和个人都面临着外网访问内网数据库的需求。外网访问内网数据库可以实现远程操作&#xff0c;方便用户在任何地点使用移动设备进行数据管理和查询。本文将介绍一种名为【天联】的组网产品&#xff0c;它是一…

数据库-Redis(12)

目录 56.Redis事务中watch是如何监视实现的? 57.为什么Redis不支持回滚? 58.Redis对ACID的支持性理解?

MongoDB聚合运算符:$radiansToDegrees

MongoDB聚合运算符&#xff1a;$radiansToDegrees 文章目录 MongoDB聚合运算符&#xff1a;$radiansToDegrees语法使用举例 $radiansToDegrees将以弧度为单位的输入值转换为度。从版本4.2开始支持。 语法 { $radiansToDegrees: <expression> }<expression>是能被解…

Unity的ScriptableObject

数据持久化&#xff1a;指将数据长期存储在持久性存储介质中&#xff0c;即使在程序结束或者系统重启后&#xff0c;数据依然可以被访问和使用。这与内存存储不同&#xff0c;内存存储是临时的。一旦程序结束或系统重启,数据就会丢失。 实现数据持久化的常见方式包括: 关系型数…

MetaGPT:一个多智能体框架,将不同的GPT模型分配到不同的角色中,形成一个协作的软件实体

MetaGPT是一个多智能体框架,旨在通过将不同的GPT模型分配到不同的角色中,形成一个协作的软件实体,以解决复杂任务3。它由中国团队开发,主要应用于软件开发等场景,利用标准作业程序(SOP)来协调基于大语言模型的多智能体系统,实现元编程技术5。MetaGPT的架构分为两层:基…

阿里云服务器公网带宽“按使用流量”如何计费的?

阿里云服务器宽带按使用流量怎么收费的&#xff1f;先使用后付费&#xff0c;根据云服务器实际公网出方向产生的流量来计费&#xff0c;一般流量价格为0.8元每GB&#xff0c;结算单位按照GB计费&#xff0c;每小时扣费&#xff0c;地域不同流量价格也不同。可以在阿里云CLUB中心…

SkyWalking 为所有的API接口增加 tag

背景胡扯 线上接口报错&#xff0c;接着被 SkyWalking 抓到&#xff0c;然后 SkyWalking 触发告警&#xff0c;最后老板你&#xff0c;让你辛苦一下&#xff0c;在明早上班前把这个bug 改了&#xff0c;并告诉你你是全公司的希望。谁说不是呢&#xff1f;为公司业务保驾护航&a…

C语言 | 自定义类型:struct结构体(详解)

目录&#xff1a; --前言 1. 结构体类型的定义与基础结构 2. 结构体的使用 3. typedef相关 4. 结构体的自引用 5. 结构体内存对齐 6. 结构体传参 7. 结构体实现位段 --前言&#xff1a; c语言中内置类型&#xff0c;也有自定义的类型。 例如&#xff1a;内置类型 in…

windows应急响应基础知识

一、系统排查 1、系统详细信息 systeminfo2、网络链接 netstat -ano LISTENING 服务启动后首先处于侦听 ESTABLISHED 建立连接。表示两台机器正在通信。 CLOSE_WAIT 对方主动关闭连接或者网络异常导致连接中断&#xff0c;这时我方的状态会变成CLOSE_WAIT 此时我方要调用…

golang实现windows提权

golang实现windows提权 package mainimport ("fmt""syscall""unsafe""github.com/shirou/gopsutil/process""golang.org/x/sys/windows" )const (TOKEN_ALL_ACCESS 0x000F01FFSE_PRIVILEGE_ENABLED 0x00000002TOKEN_…

【计算机考研】408网课汇总+资源分享

408王道的视频就比较通俗易懂 王道的教材非常契合408的大纲&#xff0c;是专门为408大纲而编写的&#xff0c;而教材是方方面面都讲解的透彻。 建议王道为主&#xff0c;网络搜索为辅&#xff01; 王道中讲解不清楚&#xff0c;看不懂的知识点&#xff0c;可以尝试在网络上进…

LeetCode 热题 100 Day03

普通数组 常见的题型有&#xff1a; 取模、区间合并、最大子序列和、最长非0子序列等。 一些解题思路很巧妙&#xff0c;多练多总结。 Leetcode 53. 最大子数组和 [dp动态查找最大值] 题目理解&#xff1a; 给定一个整数数组, 求一个连续的子序列 该子序列满足和最大 要求返回最…

基于openssl实现TCP双向认证

文章参考 深入探索 OpenSSL&#xff1a;概念、原理、开发步骤、使用方法、使用场景及代码示例 c使用OpenSSL基于socket实现tcp双向认证ssl(使用TSL协议)代码实现 SSL握手通信详解及linux下c/c SSL Socket代码举例(另附SSL双向认证客户端代码) SSL/CA 证书及其相关证书文件(pem…