Request和Response
前言
这一节主要讲的是Request和Response还有一些实例
1. 介绍
就是这两个参数
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//使用request对象,获取请求数据 输入网址就是getString name = req.getParameter("name");//url?name=zhangsan//使用response对象,设置响应数据resp.setHeader("content-type", "text/html;charset=UTF-8");resp.getWriter().write("<h1>" + name+",欢迎你" + "</h1>");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
2. requset
2.1 request继承体系
前面两个我们都用过了
RequestFacade实现的方法都是前面两个接口的
requset对象是由Tomcat创建的
2.2 request请求数据
请求行:请求方式+请求资源路径+请求协议+版本号
虚拟目录就是我们项目的目录
URL就是问号前面的
问号后面的是get方式的请求参数
URI:短的路径
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();//获取请求方式System.out.println(method);//GETString contextPath=req.getContextPath();//获取虚拟目录,就是项目的访问路径System.out.println(contextPath);//没有设置项目的访问路径,那么返回的默认就是这个模块的名称StringBuffer url=req.getRequestURL();System.out.println(url.toString());//获取URLString uri=req.getRequestURI();//获取uriSystem.out.println(uri);String queryString=req.getQueryString();//获取请求参数System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
拿着请求参数,切割就可以得到很多个键值对了
在把等号切割就OK了
获取客户端使用的浏览器的版本信息
只有post请求才有请求体
比如提交表单参数,就会把表单的参数放在请求体里面
上传图片文件就用字节流
上传的文本就用字符流
String agent=req.getHeader("User-Agent");//User-Agent是获取浏览器版本的请求头System.out.println(agent);
获取请求体要post请求,我们写个表单
<!--form的action就是虚拟路径的名称,就是项目加资源路径,这个就会把你表单提交的数据,通过post提交到demo7就是dopost-->
<form action="/Tomcat-demo1/demo7" method="post" ><input type="text" name="username"><input type="password" name="password"><input type="submit"></input></input>
</form>
@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post的请求体:请求参数,通过流的方式来获取//表单里面的数据都是字符串,所以我们用字符流BufferedReader br = req.getReader();//写完req.getReader(),alt加enter就会自动添加局部变量。// table补齐,或者enter也可以补齐String line=br.readLine();//参数只有一行System.out.println(line);//流不用关闭,因为req被销毁的时候,流就自动关闭了}
注意要关闭@WebServlet(urlPatterns = “/”)这个哦,上一节说过的
2.2 request通用方式获取请求参数
这里要使用两种方式获取请求参数,要写两份,很麻烦,能够统一就好了
因为获取请求参数,后面执行的代码都是一样的,如果不同意就要写两份,统一的话,互相调用就可以了,因为代码是一样的
但是不能删post的,因为有post请求咋办,但是post和get代码一样,所以互相调用
params就长这个样子了
这三个方法就是通用方式
<!--form的action就是虚拟路径的名称,就是项目加资源路径,这个就会把你表单提交的数据,通过get提交到demo7就是dopost-->
<form action="/Tomcat-demo1/demo7" method="get" ><input type="text" name="username"><br><input type="password" name="password"><br><input type="checkbox" name="hobby" value="1" >游泳<input type="checkbox" name="hobby" value="2" >爬山<br>
<!-- 因为hobby是一个复选框 选第一个值,提交过来的就是1,-->
</br><input type="submit"></input></input>
</form>
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("get.....");//1.获取所有参数的map集合Map<String, String[]> map = req.getParameterMap();for (String key : map.keySet()) {//这个是遍历map集合//username:zhangsan lisiSystem.out.print(key+":");//获取值String[] values = map.get(key);for (String value : values) {System.out.print(value+" ");}System.out.println();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.doGet(req, resp);}
}
变成get了,因为参数在地址那里
System.out.println("---------------------------");//2.根据可以获取参数值,数组,,,意思就是根据一个key来获取对应的值,因为一个key可能会对应多个值,所以用的数组//我们明确知道hobby对应多个值String[] hobbies = req.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println(hobby);}
重启服务器,刷新表单页面
这里的密码是空字符串
//3.根据key来获取单个参数值,意思是这个键对应的值只有一个String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(password);System.out.println(username);
然后我们把代码原封不动的复制给dopost
然后表单提交方式改为post
这里建议要刷新一下,不然可能一直是get,如果刷新不行,就关了重新来
既然get和post写的一模一样了,那就不要写两遍了
this.doGet(req, resp);
这样就会去调用doget,然后对应的参数也是一样的,就可以正常使用了,因为doget和dopost参数一模一样所以可以相互调用
我们还是post的提交方式
这个的反应就是post
然后打印出来,其实走的是doget
2.4 idea模版创建servlet
我们点击设置,编辑器,文件和代码模版,其他,web,Java代码模版,点Servlet Annotated Class.java
改造一下,修改dopost,和webservlet就可以了
如果新建里面没有servlet的话,要到设置里面,编辑器,文件和代码模版,文件,新建一个servlet
这样就有了
第一个选项可以不用选
就这样我们就创建好了
下面分享一下里面的模版内容
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")#if ($JAVAEE_TYPE == "jakarta")
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
#else
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
#end
import java.io.IOException;@WebServlet("/${Entity_Name}")
public class ${Class_Name} extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request,response);}
}
2.5 请求参数中文乱码-post解决方案
我们先演示一下乱码
改成get和demo8
这样就乱码了,其实post也会乱码
改成post
服务器后退一下,就可以访问了,只有servlet的代码没有变,就没有必要重启代码
也是乱码
//2.解决乱码:post,getReader()--->读中文数据的时候不是utf-8,所以会出错request.setCharacterEncoding("UTF-8");//设置字符输入流的编码、、、但是要先设置在获取//1.获取一下usernameString username = request.getParameter("username");System.out.println(username);
下面来get
2.6 请求参数中文乱码-get解决方案
产生get乱码的原因就是解码与编码不一样,但是getQueryString解码方式写死了,所以我们要了解URL编码才行
这里就是URL编码了
Java里面也有URL编码
选第一个
String username="张三";//1.url编码String encode=URLEncoder.encode(username,"utf-8");System.out.println(encode);
//url解码String decode = URLDecoder.decode(encode, "utf-8");System.out.println(decode);
String decode = URLDecoder.decode(encode, "ISO-8859-1");
Tomcat就是这样处理的
所以会这样
注意乱码和张三的字节是一样的
所以可以把乱码转换成二进制数据,在用UTF-8变成张三
//3.转换成字节数据byte[] bytes = decode.getBytes("ISO-8859-1");for (byte b : bytes) {System.out.print(b+" ");}
6个字节
//3.转换成字节数据byte[] bytes = decode.getBytes("ISO-8859-1");//转换为字符串String s = new String(bytes, "utf-8");System.out.println(s);
所以我们只需要干第三步和第四步
//1.获取一下usernameString username = request.getParameter("username");System.out.println("乱码前"+username);//3.get getParameter针对post用的流,针对get用的字符串,所以不一样,,所以get//get获取参数的方式;getQueryString,没有走流,所以不一样//乱码原因//tomcat用的是ISO-8859-1解码//先对乱码数据编码byte[] bytes = username.getBytes("ISO-8859-1");
// byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);//这个也是一样的
// String s = new String(bytes, "utf-8");username = new String(bytes, StandardCharsets.UTF_8);System.out.println("乱码后"+username);
//合二为一username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
这句代码还可以解决post的
因为我们当前的tomcat只到了7版本所以会出错
2.7 request请求转发
创建两个demo
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("demo9");//请求转发request.getRequestDispatcher("/demo10").forward(request, response);}
资源跳转,那么我们就要共享数据,数据就要存在一个地方,这个地方就是request
//存储数据request.setAttribute("msg", "hello");//这个数据就会放在request,随着转发而转发
//获取数据Object msg = request.getAttribute("msg");System.out.println(msg);
修改了servlet代码就要重启服务器
第一虽然资源转变了但是路径并没有变
只能在同一个服务器里边,不能跑到百度那里去了
3. response
3.1 设置响应数据功能介绍
http是协议和版本号,200是状态码,OK是状态码的描述
3.2 完成重定向
302是告诉我们要重定向,location是告诉重定向的位置在哪里
System.out.println("resp1");//重定向//1. 设置响应状态码response.setStatus(302);//2,。设置响应头//response.setHeader("Location", "http://localhost:8080/resp2");//或者response.setHeader("Location", "/Tomcat-demo1/resp2");//这个路径要加虚拟目录名称
重启服务器,反退输入resp1
我们发现重定向的302和location都固定,所以可以优化
response.sendRedirect( "/Tomcat-demo1/resp2");
因为请求资源是通过浏览器发出的,所以可以到任意的资源
response.sendRedirect( "https://www.itcast.cn");
这个就是外部资源
两次请求就有两个requset域,就不能在多个资源中使用request共享数据
3.3 资源路径问题
重定向要加上虚拟目录,资源转发不需要
要访问远的,浏览器使用,就加上虚拟目录,近的,服务端使用,就不需要加上虚拟目录
href是超链接,浏览器发出的,远的
form表单浏览器发出请求,提交到服务器的某一个资源
转发–》服务器内部
注意虚拟目录的这个值我们可以动态的配置,
path那里就可以动态的配置
但是这里改的话,其他地方的虚拟目录就写死了
所以可以让虚拟目录的值动态的获取
String contextPath = request.getContextPath();//获得虚拟目录response.sendRedirect(contextPath+"/resp2");
这样和前面也是一样的
3.4 response响应字符数据
//响应字符数据,设置字符数据的响应体PrintWriter writer = response.getWriter();//字符输出流writer.write("aaaa");
writer.write("<h1>aaaa</h1>");
但是这样却原模原样的展示了
因为没有告诉我们响应的是html的,这里默认的就是纯文本的形式
//响应字符数据,设置字符数据的响应体PrintWriter writer = response.getWriter();//字符输出流//设置头response.setHeader("content-type", "text/html");//告诉浏览器,将来我响应的数据格式是html格式,不是纯文本writer.write("aaaa");writer.write("<h1>aaaa</h1>");
但是真正响应的数据还是原来的样子,只不过用了html的解析
第一writer不用关闭,这个流不用关闭
第二中文数据也可以响应,但是会乱码,因为这个字符输出流还是上面那个,不是UTF-8
所以要设置流的编码
就是对 response.setHeader(“content-type”, “text/html”);简化书写格式
setContentType这个方法不仅可以设置tContentType这个头,还可以设置流的编码,但还是要先设置,在获取流的编码
response.setContentType("text/html;charset=utf-8");//要的是html的数据格式,;charset=utf-8就可以支持中文了PrintWriter writer = response.getWriter();//字符输出流writer.write("你好");writer.write("<h1>aaaa</h1>");
3.5 response响应字节数据
为了响应字节数据,我们用一张图片来
//读取文件FileInputStream fis = new FileInputStream("E:\\JavaWeb\\java-web\\Tomcat-demo1\\src\\main\\resources\\pin\\a.png");//获取字节输出流ServletOutputStream os = response.getOutputStream();//目的地就是页面的响应数据体//完成流的copybyte[] b = new byte[1024];int len = 0;while ((len = fis.read(b)) != -1) {os.write(b, 0, len);}fis.close();//关闭流。os不用关
我们一般不这样实现流的对拷,我们一般使用工具类,引个坐标
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.17.0</version></dependency>
选第三个,如果没有就刷新Maven
//读取文件FileInputStream fis = new FileInputStream("E:\\JavaWeb\\java-web\\Tomcat-demo1\\src\\main\\resources\\pin\\a.png");//获取字节输出流ServletOutputStream os = response.getOutputStream();//目的地就是页面的响应数据体IOUtils.copy(fis,os);//参数就是一个输入,一个输出,就可以拷贝了
4. 案例
4.1 环境准备与用户登录
先准备页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--注意将请求提交给loginServlet-->
<form action="/web_demo_war_exploded/loginServlet" method="post">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" value="登录">
</form>
</body>
</html>
mabatis环境准备
数据库的
-- 创建数据库
CREATE DATABASE db1;USE db1;-- 创建用户表
CREATE TABLE tb_user(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(20) UNIQUE,PASSWORD VARCHAR(32)
);-- 添加数据
INSERT INTO tb_user(username,PASSWORD) VALUES('zhangsan','123'),('lisi','234');SELECT * FROM tb_user;
OK这样我们就创建好了
现在在创建user的实体类
package pojo;public class User {private Integer id;private String username;private String password;public User() {}public User(Integer id, String username, String password) {this.id = id;this.username = username;this.password = password;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
现在导入mybatis坐标,mysql驱动坐标
原来
现在导入mybatis坐标
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency>
mysql驱动坐标
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.34</version></dependency>
现在创建mybatis核心配置文件,UserMapper.xml映射文件,和UserMapper接口
mybatis核心配置文件
在resources底下新建
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 起别名--><typeAliases><package name="pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- db1数据库,useSSL=false关闭安全链接,性能更高,useServerPrepStmts=true,预编译功能&就是and--><property name="url" value="jdbc:mysql://localhost:13306/db1?useSSL=false&useServerPrepStmts=true"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers>
<!-- 扫描mapper,是从java开始的--><package name="mapper"/></mappers>
</configuration>
在新建一个接口
UserMapper.xml映射文件,
在resources底下新建目录,这个目录,和java对应,和mapper的目录必须要一模一样
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.UserMapper">
<!-- 这里的接口名称就是全路径名,就是不写java目录的接口的路径名--></mapper>
public interface UserMapper {//查询用户的,根据用户名和密码,返回user对象@Select("select * from tb_user where username = #{username} and password = #{password}")User select(String username, String password);//接下来对这个接口的方法,声明一个sql来对应,因为sql语句简单,所以用注解
}
还不够,因为有多个参数,所以还要加上param注解
public interface UserMapper {//查询用户的,根据用户名和密码,返回user对象@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username,@Param("password") String password);////@Param("username")这个username要和#{username}里面的一一对应//接下来对这个接口的方法,声明一个sql来对应,因为sql语句简单,所以用注解
}
所以mabatis的工作就做完了
<form action="/web_demo_war_exploded/loginServlet" method="post">
在login.html中,action还要改一下
要加上虚拟目录
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--注意将请求提交给loginServlet-->
<!--虚拟地址中的Tomcat-demo1,就是项目名称,loginServlet就是资源-->
<form action="/Tomcat-demo1/loginServlet" method="post" id="form"><h1 id="loginMsg">LOGIN IN</h1><p>Username:<input type="text" name="username" id="username"></p><p>Password:<input type="password" name="password" id="password"></p><div id="subDiv"><input type="submit" class="button" value="login up"><input type="reset" class="button" value="reset"><a href="register.html">没有账号?点击注册</a></div>
</form>
</body>
</html>
下面写一个login的servlet
我们在response底下创建
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");//2.调用mabatis来完成查询//2.1 获取SqlSessionFactory对象------》直接官网粘贴String resource = "mybatis-config.xml";//mybatis-config.xml这个直接就在resources下,所以直接写名字就可以了InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//Mapper的类型就是UserMapper.class//2.4 调用方法User user = userMapper.select(username, password);//2.5 释放资源sqlSession.close();//3.判断user是否null,为null登录失败//获取字符输出流,并设置content typeresponse.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();//用来响应数据,响应的是中文数据,所以还要设置if (user != null) {//登录成功writer.write("登录成功");}else {//登录失败writer.write("登录失败");}}
这样我们就写完了,我们先访问login.html
先故意输错密码
但是我这样运行不了,我修改一下
这里加个cj,因为我是mysql8版本的
然后就是我修改了一下目录
然后就是这里,我们应该写3306,或者不写locallhost
<property name="url" value="jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true"/>
ok,经过我的仔细检查,发现错误最终在
<property name="url" value="jdbc:mysql://localhost:3306/db1?allowPublicKeyRetrieval=true&useSSL=false"/>
就是这个url没写对,害得我网页一直是500错误,可以把网页的错误给ai看一下,就可能知道是什么错误了
在修改一下
<property name="url" value="jdbc:mysql://localhost:3306/db1?allowPublicKeyRetrieval=true&useSSL=false&useServerPrepStmts=true"/>
其实没什么大的错误,就是cj,还有mysql版本,还有就是这个url问题
具体细节和代码,可以看我的gitee
gitee
下面我们就直接运行了
4.2 用户注册
UserMapper
//根据用户名,查询用户对象@Select("select * from tb_user where username = #{username}")
// User selectByUsername(@Param("username") String username);User selectByUsername(String username);//只有一个参数,不需要写Param注解//添加用户@Insert("insert into tb_user values(null,#{username},#{password})")//因为主键是自增长的,所以不用写出来,写个null就可以了void add(User user);
下面开始写注册页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div class="reg-content"><h1>欢迎注册</h1><span>已有账号?</span><a href="login.html">登录</a>
</div><form action="/Tomcat-demo1/registerServlet" method="post" id="reg-form"><table><tr><td>用户名:</td><td class="inputs"><input type="text" name="username" id="username"><br>
<!-- <span id="username_err" class="err-msg" style=".err-msg">用户名不太受欢迎</span>--></td></tr><tr><td>密码:</td><td class="inputs"><input type="password" name="password" id="password"><br>
<!-- <span id="password_err" class="err-msg" style="color: red; font-size: 12px;">密码格式有误</span>--></tr></table><div class="button"><input value="注册" type="submit" id="reg-btn"></div><br class="clear">
</form>
</body>
</html>
下面开始创建servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收用户数据String username = request.getParameter("username");String password = request.getParameter("password");//分装用户对象,因为void add(User user);,参数就是用户对象User user = new User();user.setUsername(username);user.setPassword(password);//2.调用mapper,根据用户名查询用户对象//直接复制过来String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用方法User u = userMapper.selectByUsername(username);//3.判断用户对象是否为nullif (u == null) {//不存在就添加userMapper.add(user);//因为这个是增删改的操作,所以还要一定要提交事务sqlSession.commit();//释放资源sqlSession.close();}else {//存在就添加response.setContentType("text/html;charset=utf-8");response.getWriter().write("用户名已存在");//中文的话,就要设置一下编码}}
OK,我们就这样水淋淋的写完了
先访问登录页面,因为登录页面可以跳转到注册页面
点击注册
就这样我们就成功了
4.3 SqlSessionFactory工具类抽取
SqlSessionFactory这个对象我们在两个servlet中都创建了一次,相当于创建了两次,所以有点问题
第一就是重复了
第二就是SqlSessionFactory工厂对象创建一个就可以了,因为这是一个链接池,创建一个就好了
一般来说,重复代码,抽取一个工具类就可以了
连包带类的创建的话,直接就创建java类就可以了
public class SqlSessionFactoryUtils {private static SqlSessionFactory sqlSessionFactory;//将那三行代码写在静态代码块里面,就只会执行一次了,随着类的加载而自动执行,只会一次,但是静态代码块不能抛异常,所以我们要try catchstatic {try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory() {//这样我们只需要在这个方法里面放回静态代码块里面的工厂就可以了//如何用静态代码块里面的局部变量呢,提升一下作用域就可以了---》设置一个private变量return sqlSessionFactory;}
}
这样我们就写完了工具类
我们在doget里面添加这个代码就可以了
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
然后我们发现sqlSession也是重复的
但是这个不需要共享同一个
因为这只是一个对象,不同用户之间最好不要共享,连接池共享就可以了
欧克,我们还是可以运行的
总结
最好再提供一下gitee
gitee
下一次讲JSP
相关文章:

Request和Response
前言 这一节主要讲的是Request和Response还有一些实例 1. 介绍 就是这两个参数 WebServlet("/demo7") public class ServletDemo7 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExcepti…...

【青牛科技】GC8549替代LV8549/ONSEMI在摇头机、舞台灯、打印机和白色家电等产品上的应用分析
引言 在现代电子产品中,控制芯片的性能直接影响到设备的功能和用户体验。摇头机、舞台灯、打印机和白色家电等领域对控制精度、功耗和成本等方面的要求日益提高。LV8549/ONSEMI等国际品牌的芯片曾是这些产品的主要选择,但随着国内半导体技术的进步&…...

(十二)JavaWeb后端开发——MySQL数据库
目录 1.数据库概述 2.MyQSL 3.数据库设计 DDL 4.MySQL常见数据类型 5.DML 1.数据库概述 数据库:DataBase(DB),是存储和管理数据的仓库 数据库管理系统:DataBase ManagementSystem(DBMS),操纵和管理数据库的大型软件 SQL&a…...

pnpm管理多工作区依赖
pnpm是一个支持多包仓库的一个包管理工具,那么怎么可以在项目根目录下执行pnpm install的时候,也能同步让所有的工作区都能够通安装依赖呢? 方式一,在执行pnpm install指令的时候,添加recursive参数: pnpm install --recursive 方式二,在项目的根目录下通过pnpm的配置文件p…...

如何在本地Linux服务器搭建WordPress网站结合内网穿透随时随地可访问
文章目录 前言1. 安装WordPress2. 创建WordPress数据库3. 安装相对URL插件4. 安装内网穿透发布网站4.1 命令行方式:4.2. 配置wordpress公网地址 5. 配置WordPress固定公网地址 前言 本文主要介绍如何在Linux Ubuntu系统上使用WordPress搭建一个本地网站,…...

二、应用层,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》
文章目录 零、前言一、应用层协议原理1.1 网络应用的体系结构1.1.1 客户-服务器(C/S)体系结构1.1.2 对等体(P2P)体系结构1.1.3 C/S 和 P2P体系结构的混合体 1.2 进程通信1.2.1 问题1:对进程进行编址(addressing)&#…...

面粉直供系统|基于java和小程序的食品面粉直供系统设计与实现(源码+数据库+文档)
面粉直供系统 目录 基于java和小程序的食品面粉直供系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&#x…...

十四:java web(6)-- Spring Spring MVC
目录 Spring MVC 1.1 Spring MVC 概述 1.1.1 什么是 MVC 模式 1.1.2 Spring MVC 工作原理 1.2 Spring MVC 核心组件 1.2.1 DispatcherServlet 1.2.2 控制器(Controller) 1.2.3 请求映射(RequestMapping) 1.2.4 视图解析器…...

Java代码实现策略模式处理支付付款业务
1.需求:因为付款功能集成的第三方支付SDK越来越来多不好维护,改用策略模式实现,来代替代码中多余的if else 判断。 2.什么是策略模式? 策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时选择算法的行为。该模式将不同的算法封装成独立的策略类,并使这些…...

unity3d————四元数概念
一、定义与表示 四元数是由一个实数部分和三个虚数部分组成,通常表示为q w xi yj zk,其中w是实数,x、y、z是实数系数,i、j、k是虚数单位,满足以下关系: i j k -1ij k,ji -kjk i&…...

spring相关的面试题
Spring 框架是 Java 开发中最常用的框架之一,因此在面试中经常会被问到与 Spring 相关的问题。以下是一些常见的 Spring 面试题及其答案。 基础概念 什么是 Spring 框架? Spring 框架是一个开源的 Java 平台,用于构建企业级应用程序。它提供…...

STM32外设之SPI的介绍
### STM32外设之SPI的介绍 SPI(Serial Peripheral Interface)是一种高速的,全双工,同步的通信总线,主要用于EEPROM、FLASH、实时时钟、AD转换器等外设的通信。SPI通信只需要四根线,节约了芯片的管脚&#x…...

二十三、Mysql8.0高可用集群架构实战
文章目录 一、MySQL InnoDB Cluster1、基本概述2、集群架构3、搭建一主两从InnoDB集群3.1、 安装3个数据库实例3.2、安装mysqlrouter和安装mysqlshell3.2.1、安装mysql-router3.2.2、安装mysql-shell 3.3、InnoDB Cluster 初始化3.3.1、参数及权限配置预需求检测3.3.2、初始化I…...

docker file 精简规则
在编写 Dockerfile 时,精简规则不仅有助于减小镜像大小,还能提高构建速度和可维护性。以下是一些常见的精简 Dockerfile 规则: 1. 尽量合并 RUN 指令 每个 RUN 指令会产生一个新的镜像层,因此多个命令可以合并为一个 RUN 指令&a…...

前端加密方式详解与选择指南
在当今数字化时代,前端数据安全的重要性日益凸显。本文将深入探讨前端加密的多种方式,为你提供选择适合项目加密方式的实用策略,并分享一些实际案例及相应代码。 一、前端加密方式汇总 (一)HTTPS 加密 HTTPS 是在 H…...

【React】条件渲染——逻辑与运算符
条件渲染——逻辑与&&运算符 你会遇到的另一个常见的快捷表达式是 JavaScript 逻辑与(&&)运算符。在 React 组件里,通常用在当条件成立时,你想渲染一些 JSX,或者不做任何渲染。 function Item({ nam…...

MATLAB中eig函数用法
目录 语法 说明 示例 矩阵特征值 矩阵的特征值和特征向量 排序的特征值和特征向量 左特征向量 不可对角化(亏损)矩阵的特征值 广义特征值 病态矩阵使用 QZ 算法得出广义特征值 一个矩阵为奇异矩阵的广义特征值 eig函数的功能是求取矩阵特征值…...

Chrome(谷歌浏览器中文版)下载安装(Windows 11)
目录 Chrome_10_30工具下载安装 Chrome_10_30 工具 系统:Windows 11 下载 官网:https://chrome.google-zh.com/,点击立即下载 下载完成(已经下过一遍所以点了取消) 安装 解压,打开安装包 点击下一步…...

Linux 配置JDK
文章目录 一、下载Oracle-JDK1.1、如何正确的下载JDK 二、配置JDK环境变量2.1 环境变量配置2.1.1、修改vim /etc/profile 添加jdk的路径 一、下载Oracle-JDK 1.1、如何正确的下载JDK 首先我要安装的是oracle-jdk,这个时候什么地方都不要去,就去oracle的…...

目前主流的人工智能学习框架有哪些?
随着人工智能(AI)技术的蓬勃发展,越来越多的AI学习框架相继推出,成为开发者、研究人员和企业构建机器学习(ML)和深度学习(DL)模型的首选工具。AI学习框架不仅提供了丰富的工具库和函…...

100种算法【Python版】第57篇——贝叶斯优化算法
本文目录 1 算法说明2 贝叶斯优化的步骤3 算法应用1:目标函数最大值4 算法应用2:确定最佳试验参数1 算法说明 贝叶斯优化是一种旨在优化黑箱目标函数的策略,通常适用于评估代价高昂或时间消耗长的函数。它利用贝叶斯统计方法来构建目标函数的概率模型,进而指导下一步的采样…...

在Ubuntu 上实现 JAR 包的自启动
在 Ubuntu 上实现 JAR 包的自启动,可以通过以下几种方法: 方法一:使用 systemd 创建一个服务文件: 在 /etc/systemd/system/ 目录下创建一个新的服务文件,例如 myapp.service: sudo nano /etc/systemd/sys…...

【智能算法应用】哈里斯鹰算法优化二维栅格路径规划问题
摘要 本文研究了基于哈里斯鹰优化算法(Harris Hawks Optimization, HHO)的二维栅格路径规划方法。HHO算法模拟哈里斯鹰的猎食行为,通过迭代搜索过程找到从起点到终点的最优路径,避开栅格中的障碍物。实验结果表明,HHO…...

单品年销10亿!看麻辣王子是如何布局软文营销为品牌赋能的?
说到辣条,除了大家熟知的卫龙之外,还有一个不得不提的品牌就是——麻辣王子。 作为来自辣条发源地湖南平江的老牌辣条企业,麻辣王子近几年通过打造品牌,积极破圈,2023年凭借一款单品狂揽超10亿年销售额,稳…...

【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
博主说明:本文项目编号 T 062 ,文末自助获取源码 \color{red}{T062,文末自助获取源码} T062,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...

C++:模拟实现STL的string
目录 一.实现string类 1.string的构造及析构 2.string类的遍历 3.string类的插入和删除 4.string类的空间处理 5.string类的查找 6.string类的输出和输入 7.string类的常用判断 二.整体代码 1.string.h 2.string.cpp 一.实现string类 在前一节中我们了解了STL中stri…...

【Python TensorFlow】入门到精通
TensorFlow 是一个开源的机器学习框架,由 Google 开发,广泛应用于机器学习和深度学习领域。本篇将详细介绍 TensorFlow 的基础知识,并通过一系列示例来帮助读者从入门到精通 TensorFlow 的使用。 1. TensorFlow 简介 1.1 什么是 TensorFlow…...

数据结构:七种排序及总结
文章目录 排序一插入排序1直接插入排序2希尔排序二选择排序3直接选择排序4堆排序三 交换排序5冒泡排序6快速排序四 归并排序7归并排序源码 排序 我们数据结构常见的排序有四大种,四大种又分为七小种,如图所示 排序:所谓排序,就是…...

【安当产品应用案例100集】030-使用企业微信登录Windows,实现工作电脑与业务系统登录方式统一
随着越来越多的企业信息系统从intranet开放到internet,企业员工的办公接入方式也越发多样,信息系统面临的数据安全问题也呈现爆发的趋势。一些大企业,比如Google、Microsoft、Huawei有强大的开发能力、IT能力,可以构建出自己的零信…...

大数据数据存储层MemSQL, HBase与HDFS
以下是对 MemSQL、HBase 和 HDFS 的详细介绍,这些工具在分布式数据存储和处理领域有着重要作用。 1. MemSQL MemSQL(现称为 SingleStore)是一种分布式内存数据库,兼具事务处理(OLTP)和分析处理(OLAP)的能力,专为高性能实时数据处理设计。 1.1 核心特点 内存优先存储…...