Servlet实现常用功能及其他方法

getParameter

获取body或url中指定的key/value值

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

getQueryString

获取请求的所有查询参数key,values1

String queryString=req.getQueryString();

from表单提交

前端通过from表单提交用户名和密码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="Demo4" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit" name="提交"></form>
</body>
</html>

后端通过req.getParameter获取用户名和密码

package Demo;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("/Demo4")
public class Demo4 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf8");String username=req.getParameter("username");String password=req.getParameter("password");if(username.equals("user")&&password.equals("123")){resp.getWriter().write("登录成功!");}else{resp.getWriter().write("用户名或者密码错误!");}}
}

构造json格式

body中的json格式

使用jackson库解析json格式

版本随便一个都可以

拷贝复制

记得刷新

读取从客户端传来的json数据

class Student{public int classId;public int studentId;
}
//        使用jackSon库处理JSON格式ObjectMapper objectMapper=new ObjectMapper();
//        从请求获取body并且解析
//        使用readValue来把json字符串转成java对象
//        第一个对象是String或者InputStream
//        第二个参数是转换的结果对应的java类对象//把JSON字符串转成java对象Student s=objectMapper.readValue(req.getInputStream(),Student.class);resp.getWriter().write("classId="+s.classId+" studentId="+s.studentId);

服务器把json写入到客户端

        //传json时,要用这个类型resp.setContentType("application/json;charset=utf8");//要拿到写数据库操作的类BlogDao blogDao=new BlogDao();String jsonString=objectMapper.writeValueAsString(blogs);//响应resp.getWriter().write(jsonString);

客户端如何解析json格式?

后端设置了application/json格式,并且返回json格式,那么ajax会自动把body中的json格式转换成js对象

function getBlogs(){//构造ajax$.ajax({type:'get',url:'blog',success: function(body){let container=document.querySelector('.container-right');//后端返回的是json数据//如果Content-Type是application/json,jquery ajax会把body转成js对象for(let blog of body){//构造最外层的divlet blogDiv=document.createElement('div');blogDiv.className='blog';//创建博客标题let titleDiv=document.createElement('div');titleDiv.className='title';//把后端传来的json,被jackson解析成blog对象,对象内的标题属性赋值titleDiv.innerHTML=blog.title;//把titleDiv添加在blogDiv内blogDiv.appendChild(titleDiv);

页面自动刷新

设置头部信息Refresh属性 values为秒

package Demo;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("/Demo5")
public class Demo5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf8");resp.setHeader("Refresh","1");resp.getWriter().write("设置页面1秒后自动刷新");}
}

跳转页面

        //跳转页面resp.setStatus(302);//设置状态码 302resp.setHeader("Location","Demo1.html");

N秒后自动跳转页面

        //2秒后,跳转页面resp.getWriter().write("2秒后我将跳转页面");resp.setHeader("refresh", "2;Demo1.html");

自动下载

response.setHeader("content-disposition", "attachment;filename=3.jpg");

对话墙

基本逻辑

前端构造post方法,把数据构造成json格式,发送给后端,后端解析json格式,存储到数据库。

当页面刷新时,前端构造get方法,把数据构造成json格式,发送给后端,后端从数据库读取数据,再构造成json格式,发送给前端。

ajax会自动把body中的json格式解析成js对象,之后前端把数据显示到页面上。

前端页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>对话墙</title><style>* {padding: 0;margin: 0;box-sizing: border-box;}.container {width: 800px;margin: 10px auto;}.container h2 {text-align: center;margin: 30px 0px;}.row {height: 50px;display: flex;justify-content: center;margin-top: 5px;line-height: 50px;}.row span {height: 50px;width: 100px;line-height: 50px;}.row input {height: 50px;width: 300px;line-height: 50px;}.row button {width: 400px;height: 50px;color: white;background-color: orange;border: none;border-radius: 10px;}.row button:active {background-color: grey;}</style>
</head>
<body><!-- 这是一个顶层容器, 放其他元素 --><div class="container"><h2>表白墙</h2><div class="row"><span>谁</span><input type="text" id="from"></div><div class="row"><span>对谁</span><input type="text" id="to"></div><div class="row"><span>说什么</span><input type="text" id="message"></div><div class="row"><button>提交</button></div></div><script src="https://code.jquery.com/jquery-3.7.1.min.js"></script><script>let container = document.querySelector('.container');let fromInput = document.querySelector('#from');let toInput = document.querySelector('#to');let messageInput = document.querySelector('#message');let button = document.querySelector('button');button.onclick = function() {// 1. 把用户输入的内容获取到. let from = fromInput.value;let to = toInput.value;let message = messageInput.value;if (from == '' || to == '' || message == '') {return;}// 2. 构造一个 div, 把这个 div 插入到 .container 的末尾let newDiv = document.createElement('div');newDiv.className = 'row';newDiv.innerHTML = from + " 对 " + to + " 说: " + message;// 3. 把 div 挂在 container 里面container.appendChild(newDiv);// 4. 把之前的输入框内容进行清空fromInput.value = '';toInput.value = '';messageInput.value = '';// 5. [新的步骤] 需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器!// JSON格式let messageJson={//kv值 k是我们现在定义的,v是在上面我们自己定义的from:from,to:to,message:message}$.ajax({type:"post",url:"message",contentType:'application/json;charset=utf8',// ajax构造请求发送JSONdata:JSON.stringify(messageJson),//当服务器返回数据时,执行success:function (){alert("提交成功!");},error:function (){alert("提交失败");}})}//这个函数再页面加载时候调用,通过这个函数从服务器获取当前的消息列表//摈弃显示到页面上function load(){$.ajax({type: 'get',url: 'message',contentType:'application/json;charset=utf8',//当服务器返回数据时,才会执行success: function(body){//服务器传来的时JSON格式,但ajax根据Content-Type为//application/json,ajax会帮我们自动类型转换成js数组let container=document.querySelector('.container');//服务器传来的数据都在body里//遍历bodyfor(let message of body){let newDiv=document.createElement('div');newDiv.className='row';newDiv.innerHTML=message.from +" 对 "+message.to+ " 说 "+message.message;//把newDiv加在container的里面container.appendChild(newDiv);}}})}//函数页面写在这代表页面加载/刷新时执行load函数load();</script>
</body>
</html>

后端页面

package org.example;import com.fasterxml.jackson.databind.ObjectMapper;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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;//对应前端的格式
//名字和全都key时一致的
class Message{public String from;public String to;public String message;@Overridepublic String toString() {return "org.example.Message{" +"from='" + from + '\'' +", to='" + to + '\'' +", message='" + message + '\'' +'}';}
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {//因为get、post都会用到这个对象,所以共享出来private ObjectMapper objectMapper=new ObjectMapper();//private List<org.example.Message> messageList=new ArrayList<>();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//报文格式resp.setContentType("application/json;charset=utf8");List<Message> messageList=load();//把messageList对象转成JSON格式String respString=objectMapper.writeValueAsString(messageList);resp.getWriter().write(respString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");//第一个参数从拿哪读,转成什么类型Message message=objectMapper.readValue(req.getInputStream(),Message.class);save(message);System.out.println("message"+message);//把这些数据存储起来//messageList.add(message);//System.out.println("messaage="+message);//返回保存成功响应resp.getWriter().write("{\"ok\":1}");}// 把当前的消息存到数据库中private void save(Message message) {Connection connection = null;PreparedStatement statement = null;try {// 1. 和数据库建立连接connection = DBUtil.getConnection();// 2. 构造 SQL 语句String sql = "insert into message values(?, ?, ?)";//写入sqlstatement = connection.prepareStatement(sql);//填入问号statement.setString(1, message.from);statement.setString(2, message.to);statement.setString(3, message.message);// 3. 执行 SQL 语句int ret = statement.executeUpdate();if (ret != 1) {System.out.println("插入失败!");} else {System.out.println("插入成功!");}} catch (SQLException e) {e.printStackTrace();} finally {// 4. 关闭连接.DBUtil.close(connection, statement, null);}}// 从数据库查询到记录private List<Message> load() {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Message> messageList = new ArrayList<>();try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 构造 SQLString sql = "select * from message";//写入sqlstatement = connection.prepareStatement(sql);// 3. 执行 SQLresultSet = statement.executeQuery();// 4. 遍历结果集while (resultSet.next()) {Message message = new Message();message.from = resultSet.getString("from");message.to = resultSet.getString("to");message.message = resultSet.getString("message");messageList.add(message);}} catch (SQLException throwables) {throwables.printStackTrace();} finally {// 5. 释放资源DBUtil.close(connection, statement, resultSet);}return messageList;}
}

建立连接

完成与数据库建立连接

package org.example;import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;// 期望通过这个类来完成数据库建立连接的过程.
// 建立连接需要使用 DataSource . 并且一个程序有一个 DataSource 实例即可. 此处就使用单例模式来实现.
public class DBUtil {private static DataSource dataSource = null;private static DataSource getDataSource() {if (dataSource == null) {dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/MessageWall?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("monan1946");}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {// 此处还是推荐大家写成分开的 try catch.// 保证及时一个地方 close 异常了, 不会影响到其他的 close 的执行.if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

抓包过程

当页面提交数据时,触发post请求,会把数据提交到服务器,服务器会把数据存储起来。

当刷新页面时,会触发get请求,服务器会把数据回传给页面,页面会把数据继续显示到页面上,所以数据会依据存在

为什么刷新页面时会自动触发get请求呢?

在HTTP协议中,GET请求是用来获取服务器上的资源的。当你在浏览器中输入一个URL并按下回车键或者点击刷新按钮时,浏览器会向服务器发送一个GET请求,请求服务器返回该URL对应的资源。

客户端发起的请求,会自动触发服务器的对应的do方法

服务器返回响应,就会触发客户端的代码,也就是success的回调函数

模拟用户登录

基本逻辑

前端传递用户名和密码

当用户名与密码正确时,后端创建session(cookie),把用户名写进去,并且创建计数器。之后在另一个页面,获取session中的用户名,再把计数器也取出,计数器++,并且两个打印,计数器更新后,再把更新后的计数器写入session

前端

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录页</title>
</head>
<body><!-- action是路径 method是方法 --><form action="login" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit" name="提交"></form>
</body>
</html>

后端

loginServlet

package login;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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/login")
//处理登录请求
public class loginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf8");String username=req.getParameter("username");String password=req.getParameter("password");//数据为空时if(username==null || username.equals("")|| password==null || password.equals("")){//返回到登录页面//resp.sendRedirect("login.html");resp.getWriter().write("用户名或密码错误,请重新登录!");return;}if(username.equals("user")&&password.equals("123")){//创建一个session会话 把用户信息填写到session中//如果会话存在直接获取,根据cookie中的sessionid来查//如果不存在就创建新的//第一次登录时,cookie没有sessionid,就会创建新的会话对象//同时这个getsession还会生成一个sessionid,把这个sessionid作为Set-Cookie中的字段返回//给浏览器保存//一个sessionid对应一个sessionHttpSession sessio=req.getSession(true);sessio.setAttribute("username","user");//设置计数器 用来表示用户访问页面次数Integer visitCount= (Integer) sessio.getAttribute("visitCount");//如果visitCount为空时,就设置0if(visitCount==null){//第二个参数是Object 所以会自动装箱成Integersessio.setAttribute("visitCount",0);}else{//如果已经存在,就不设置为0}resp.sendRedirect("index");}else{resp.getWriter().write("用户名或密码错误,请重新登录!");return;}}
}

indexServlet

package login;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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/index")
public class indexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf8");//false不创建会话,有则有,没有则要求用户重新登录HttpSession session=req.getSession(false);//用户未登录,跳转登录界面,重新登录//当浏览器直接访问这个页面时 并没有先进入login.html页面 就会出现session==null的情况if(session==null){resp.sendRedirect("login.html");return;}//这里就是登录成功//获取会话中的数据//因为getAttribute返回的是Object 所以要强转//获取session中传来的usernameString username= (String) session.getAttribute("username");//session第二个参数是Object,虽然写的是0,但是会自动装箱成Integer,取的时候也是Integer//获取session中传来的计数器Integer visitCount= (Integer) session.getAttribute("visitCount");visitCount=visitCount+1;//加数后,再写回去session.setAttribute("visitCount",visitCount);resp.getWriter().write("当前用户: "+username+"访问次数:"+visitCount);}
}

第一次请求

首次登录,都会触发get方法

第二次请求 

输入用户名密码登录

响应

JSESSIONID就是key(servlet自动生成的key名字) 后面是一传很长的十六进制数字,就是value

value就是服务器生成的sessionid

可以看到已经保存在浏览器内了

HttpSession sessio=req.getSession(true);

就是这个代码,实现创建会话,生成sessionid并且把sessionid通过Set-Cookie返回给浏览器

因为上面重定向了,所以浏览器get了index的页面

这是报文里就有了cookie

响应

这时就会读取请求中的cookie中的username,并且显示出来

上传文件

前端

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- enctype="multipart/form-data"指定了表单数据的编码方式,这样文件上传操作才能正确地执行。 --><form action="upload" method="post" enctype="multipart/form-data"><input type="file" name="MyFile"><input type="submit" value="上传"></form>
</body>
</html>

后端

package upload;import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;@MultipartConfig//servlet上传文件时默认关闭的,写上这个注解,打开
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf8");
//        name要对应前端的name//获取文件Part part=req.getPart("MyFile");//        文件真实名字resp.getWriter().write(part.getSubmittedFileName()+"<br>");//文件大小System.out.println(part.getSize()+"<br>");//文件类型resp.getWriter().write(part.getContentType()+"<br>");//将文件写入磁盘part.write("D:/4k阿狸.jpg");resp.getWriter().write("upload ok");}
}

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

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

相关文章

Java record类用法简介

参考资料 Java 16 新特性&#xff1a;record类新特性Record最全用法总结—动力节点总结Javaのレコードクラス从头学Java17-Stream API&#xff08;二&#xff09;结合Record、Optional 目录 一. 介绍二. 基本语法三. 各种特性示例3.1 准备3.2 创建&#xff0c;属性&#xff0c…

MySQL 社区版 安装总结

很早就安装过MySQL&#xff0c;没有遇到过什么问题&#xff0c;直接next就行了&#xff0c;这次在新电脑上安装却遇到了一些问题&#xff0c;记录一下。 安装的是MySQL社区版&#xff0c;下载地址是www.mysql.com&#xff0c;进入后选择DOWNLOAD页面&#xff0c;选择MySQL Com…

对常见FTP客户端/服务器的调查与分析

前言 主要是想看看常见的服务器和客户端是如何实现协议中要求的功能的&#xff0c;。 比如RF959要求的记录结构&#xff08;Record Structure&#xff09;、页结构&#xff08;Page Structure&#xff09;、Block Mode、Compress Mode&#xff0c;看起来就很抽象。 实测发现…

快速入门深度学习9.1(用时20min)——GRU

速通《动手学深度学习》9.1 写在最前面九、现代循环神经网络9.1 门控循环单元&#xff08;GRU&#xff09;9.1.1. 门控隐状态9.1.1.1. 重置门和更新门9.1.1.2. 候选隐状态9.1.1.3. 隐状态 9.1.3 API简洁实现小结 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 20…

【状态压缩 容斥原理 组合数学】100267. 单面值组合的第 K 小金额

本文涉及知识点 状态压缩 容斥原理 组合数学 二分查找算法合集 LeetCode100267. 单面值组合的第 K 小金额 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给你一个整数 k 。 你有无限量的每种面额的硬币。但是&#xff0c;你 不能 组合使用不同面额的硬币。 返回…

适合刚入门同学做的小程序项目

今天用uniapp做了一个酒桌数字筛子的小程序&#xff0c;因为平时玩的骰子小程序都是骰子的动画效果展示&#xff0c;喝多的时候非常容易看错&#x1f621;&#x1f601;&#xff0c;所以就想着看能不能做一个纯数字显示类型的骰盅&#xff0c;一目了然干净利落。&#x1f44f;&…

数据结构之排序了如指掌(三)

目录 题外话 正题 快速排序 Hoare法 Hoare法思路 Hoare法代码详解 挖坑法 挖坑法思路 挖坑法代码 前后指针法 前后指针法思路 前后指针法代码 小结 题外话 我们接着把没有写完的排序内容完成,快速排序其实大同小异,大家好好把思路整理一下 正题 快速排序 快速排序一…

BTS441RGATMA1 N沟道 43V 17A高侧电源开关芯片 英飞凌

BTS441RGATMA1是一款由Infineon Technologies制造的高侧开关电源芯片。 BTS441RGATMA1具有以下功能&#xff1a; 高端电源开关&#xff1a;BTS441RGATMA1是一种N通道功率场效应晶体管&#xff08;FET&#xff09;&#xff0c;用于高端电源开关应用。 高侧开关&#xff1a;该器件…

数据结构-堆详解

堆 图片&#xff1a; 二叉堆的父节点为这个子树的最值。 如何维护它。 我们发现它是一棵二叉树&#xff0c;那就自然满足若父节点为 x x x 则左儿子节点为 x 2 x\times2 x2 右儿子为 x 2 1 x\times 2 1 x21 这是显然的&#xff0c;但如果写成指针或结构体就太麻烦了&…

MacOS Docker 部署 Solr 搜索引擎

一、简介 Solr 是 Apache 下的一个顶级开源项目&#xff0c;采用 Java 开发&#xff0c;它是基于 Lucene 的全文搜索服务器。Solr 可以独立运行在 Jetty、Tomcat 等这些 Servlet 容器中。Solr 提供了比 Lucene 更为丰富的查询语言&#xff0c;同时实现了可配置、可扩展&#x…

免费使用Kimi的API接口,kimi-free-api真香

今年&#xff0c;随着各大GLM模型的开源和算力的提升&#xff0c;尤其是最近比较火热的月之暗面的Kimi 模型&#xff0c;AI应用场景中的各种智能体如雨后春笋般涌现。许多同学们纷纷表达了加入AI应用的学习和测试的愿望&#xff0c;然而各大模型提供商所提供的API的免费tokens在…

集群管理命令总结

前言 在进行TPC性能测试时用到两个集群管理命令&#xff1a;clush 和 pssh&#xff0c;这俩命令都可以在多台服务器上并发执行相同命令&#xff0c;其中个人比较推荐 clush&#xff0c;因为感觉 clush 比较好用&#xff0c;本文来总结一下 clush 和 pssh 的安装配置和使用。 …