【JavaWeb】请求和响应Request&Response
请求
请求对象
关于请求
顾名思义,意思就是请求一个“对象”
请求不到的,别想了
请求,就是使用者希望从服务器端索取一些资源,向服务器发出询问。在B/S架构中,就是客户浏览器向服务器发出询问。在JavaEE工程中,客户浏览器发出询问,要遵循HTTP协议规定。
请求对象,就是在JavaEE工程中,用于发送请求的对象。我们常用的对象就是ServletRequest和HttpServletRequest,它们的区别就是是否和HTTP协议有关。
常用请求对象
常用请求方法
请求对象的使用示例
常用方法一:请求各种路径
/*
获取路径的相关方法
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取虚拟目录名称 getContextPath()
String contextPath = req.getContextPath();
System.out.println(contextPath);
//2.获取Servlet映射路径 getServletPath()
String servletPath = req.getServletPath();
System.out.println(servletPath);
//3.获取访问者ip getRemoteAddr()
String ip = req.getRemoteAddr();
System.out.println(ip);
//4.获取请求消息的数据 getQueryString()
String queryString = req.getQueryString();
System.out.println(queryString);
//5.获取统一资源标识符 getRequestURI() /request/servletDemo01
String requestURI = req.getRequestURI();
System.out.println(requestURI);
//6.获取统一资源定位符 getRequestURL() http://localhost:8080/request/servletDemo01
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
常用方法二:获取请求参数以及封装(非常重要)
我们常常会使用HttpServletRequest对象获取请求参数,然后将其封装到实体类中
/*
获取请求参数信息的相关方法
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.根据名称获取数据 getParameter()
String username = req.getParameter("username");
System.out.println(username);
String password = req.getParameter("password");
System.out.println(password);
System.out.println("--------------------");
//2.根据名称获取所有数据 getParameterValues()
String[] hobbies = req.getParameterValues("hobby");
for(String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("--------------------");
//3.获取所有名称 getParameterNames()
Enumeration<String> names = req.getParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
System.out.println(name);
}
System.out.println("--------------------");
//4.获取所有参数的键值对 getParameterMap()
Map<String, String[]> map = req.getParameterMap();
for(String key : map.keySet()) {
String[] values = map.get(key);
System.out.print(key + ":");
for(String value : values) {
System.out.print(value + " ");
}
System.out.println();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
下面通过实例说明几种封装方式
需求:我们要实现从网页填写学生注册信息,然后把获取请求参数并把相应的信息封装到每一个Student类中。
第一步:编写一个页面html程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<form action="/request/servletDemo08" method="post" autocomplete="off">
姓名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
爱好:<input type="checkbox" name="hobby" value="study">学习
<input type="checkbox" name="hobby" value="game">游戏 <br>
<button type="submit">注册</button>
</form>
</body>
</html>
第二步:编写Student的javabean类,注意其数据成员最好(必须)与html文件表单的name属性一致
public class Student {
private String username;
private String password;
private String[] hobby;
public Student() {
}
public Student(String username, String password, String[] hobby) {
this.username = username;
this.password = password;
this.hobby = hobby;
}
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;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", hobby=" + Arrays.toString(hobby) +
'}';
}
}
第三步:获取参数信息,并封装数据
法一:直接手动封装(简单粗暴)
/*
封装对象-手动方式
*/
@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
//2.封装学生对象
Student stu = new Student(username,password,hobbies);
//3.输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
法二:通过反射封装
PropertyDescriptor
: Describes a Java Bean property hosting validation constraints
调用javabean类的有参构造函数创建对象
构造函数 PropertyDescriptor(String,class);
注意第一个参数是javabean构造函数的第一个形式参数,第二个参数是已经创建的实类的字节码。
/*
封装对象-反射方式
*/
@WebServlet("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap();
//2.封装学生对象
Student stu = new Student();
//2.1遍历集合
for(String name : map.keySet()) {
String[] value = map.get(name);
try {
//2.2获取Student对象的属性描述器
PropertyDescriptor pd = new PropertyDescriptor(name,stu.getClass());
//2.3获取对应的setXxx方法
Method writeMethod = pd.getWriteMethod();
//2.4执行方法
if(value.length > 1) {
writeMethod.invoke(stu,(Object)value);
}else {
writeMethod.invoke(stu,value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//3.输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
法三:BeanUtils工具类封装
BeanUtils.populate(stu,map);
(实类,参数map)
/*
封装对象-工具类方式
*/
@WebServlet("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap();
//2.封装学生对象
Student stu = new Student();
try {
BeanUtils.populate(stu,map);
} catch (Exception e) {
e.printStackTrace();
}
//3.输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
用流的形式读取请求信息
/*
流对象获取数据
*/
@WebServlet("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//字符流(必须是post方式)
/*BufferedReader br = req.getReader();
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}*/
//br.close();
//字节流
ServletInputStream is = req.getInputStream();
byte[] arr = new byte[1024];
int len;
while((len = is.read(arr)) != -1) {
System.out.println(new String(arr,0,len));
}
//is.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求正文中中文编码问题
1.POST方式请求
问题:获取请求正文,会有乱码问题。是在获取的时候就已经乱码了。
解决:是request对象的编码出问题了。设置request对象的字符集
request.setCharacterEncoding("编码方式")
它只能解决POST的请求方式,GET方式解决不了
/*
中文乱码
*/
@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
2.GET方式请求
问题:GET方式:正文在地址栏username=%D5%C5%C8%FD%D5%C5%C8%FD
是已经被编过一次码了
GET方式请求的正文是在地址栏中,在Tomcat8.5版本及以后,Tomcat服务器已经帮我们解决了,所以不会有乱码问题了。
而如果我们使用的不是Tomcat服务器,或者Tomcat的版本是8.5以前,那么GET方式仍然会有乱码问题,解决方式如下:
使用正确的码表对已经编过码的数据进行解码。就是把取出的内容转成一个字节数组,但是要使用正确的码表。(ISO-8859-1)再使用正确的码表进行编码,把字节数组再转成一个字符串,需要使用正确的码表,是看浏览器当时用的是什么码表。
/**
* 在Servlet的doGet方法中添加如下代码
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
byte[] by = username.getBytes("ISO-8859-1");
username = new String(by,"GBK");
//输出到浏览器:注意响应的乱码问题已经解决了
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write(username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
请求转发(与重定向的区别)
重定向特点:两次请求,浏览器行为,地址栏改变,请求域中的数据会丢失
请求转发:一次请求,服务器行为,地址栏不变,请求域中的数据不丢失
请求域的作用范围:当前请求(一次请求),和当前请求的转发之中
请求发送方:
/*
请求转发
*/
@WebServlet("/servletDemo09")
public class ServletDemo09 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置共享数据
req.setAttribute("encoding","gbk");
//获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/servletDemo10");
//实现转发功能
rd.forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求接收方:
/*
请求转发
*/
@WebServlet("/servletDemo10")
public class ServletDemo10 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取共享数据
Object encoding = req.getAttribute("encoding");
System.out.println(encoding);
System.out.println("servletDemo10执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
开启服务器后进入/servletDemo09之后会在控制台输出
encoding
servletDemo10执行了...
而此时浏览器的url依然是/servletDemo09,不会跳转
请求重定向
resp.sendRedirect(req.getContextPath() + "/servletDemo07");
请求发送方:
/*
请求重定向
*/
@WebServlet("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求域数据
req.setAttribute("username","zhangsan");
//设置重定向
resp.sendRedirect(req.getContextPath() + "/servletDemo07");
// resp.sendRedirect("https://www.baidu.com");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求接收方:
/*
请求重定向
*/
@WebServlet("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo07执行了...");
Object username = req.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求包含
需求:把两个Servlet的内容合并到一起来响应浏览器
问题:HTTP协议的特点是一请求,一响应的方式。所以绝对不可能出现有两个Servlet同时响应方式。
解决:把两个Servlet的响应内容合并输出。
/*
请求包含
*/
@WebServlet("/servletDemo11")
public class ServletDemo11 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo11执行了...");
//获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/servletDemo12");
//实现包含功能
rd.include(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
/*
请求包含
*/
@WebServlet("/servletDemo12")
public class ServletDemo12 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo12执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
控制台输出
servletDemo11执行了...
servletDemo12执行了...
而且浏览器的url依然是/servletDemo11,不会跳转
细节
请求转发的注意事项:负责转发的Servlet,转发前后的响应正文丢失,由转发目的地来响应浏览器。
请求包含的注意事项:被包含者的响应消息头丢失。因为它被包含起来了。
响应
响应对象
关于响应
服务器端收到请求,同时也已经处理完成,把处理的结果告知用户。
在B/S架构中,响应就是把结果带回浏览器。
常用响应对象
协议无关的对象标准是:ServletResponse接口
协议相关的对象标准是:HttpServletResponse接口
常用方法介绍
常用状态码:
状态码 | 说明 |
---|---|
200 | 执行成功 |
302 | 它和307一样,都是用于重定向的状态码。只是307目前已不再使用 |
304 | 请求资源未改变,使用缓存。 |
400 | 请求错误。最常见的就是请求参数有问题 |
404 | 请求资源未找到 |
405 | 请求方式不被支持 |
500 | 服务器运行内部错误 |
状态码首位含义:
状态码 | 说明 |
---|---|
1xx | 消息 |
2xx | 成功 |
3xx | 重定向 |
4xx | 客户端错误 |
5xx | 服务器错误 |
响应对象的使用示例
字节流输出中文问题
项目中常用的编码格式是u8,而浏览器默认使用的编码是gbk。导致乱码!
解决方式一:修改浏览器的编码格式(不推荐,不能让用户做修改的动作)
解决方式二:通过输出流写出一个标签:response.getOutputStream().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>")
解决方式三:response.setHeader("Content-Type","text/html;charset=UTF-8");
指定响应头信息
解决方式四:response.setContentType("text/html;charset=UTF-8");
(常用)
/*
字节流响应消息及乱码的解决
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "你好";
resp.setContentType("text/html;charset=UTF-8");
sos.write(str.getBytes("UTF-8"));
sos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
字符流输出中文问题
/*
字符流响应消息及乱码的解决
*/
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "你好";
//解决中文乱码
resp.setContentType("text/html;charset=UTF-8");
//获取字符流对象
PrintWriter pw = resp.getWriter();
//pw.println(str);
pw.write(str);
pw.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
响应图片到浏览器
/*
响应图片到浏览器
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过文件的相对路径来获取文件的绝对路径
String realPath = getServletContext().getRealPath("/img/hm.png");
System.out.println(realPath);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
//获取字节输出流对象
ServletOutputStream sos = resp.getOutputStream();
//循环读写
byte[] arr = new byte[1024];
int len;
while((len = bis.read(arr)) != -1) {
sos.write(arr,0,len);
}
bis.close();
sos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
控制缓存
resp.setDateHeader("Expires",(System.currentTimeMillis()+时间));
/*
缓存
*/
@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String news = "这是一条很火爆的新闻~~";
//设置缓存时间
resp.setDateHeader("Expires",(System.currentTimeMillis()+1*60*60*1000L));
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(news);
System.out.println("aaa");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
定时刷新
resp.setHeader("Refresh","定时时间(秒);URL=/虚拟路径/页面路径");
/*
定时刷新
*/
@WebServlet("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String news = "您的用户名或密码错误,3秒后自动跳转到登录页面...";
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(news);
//设置响应消息头定时刷新
resp.setHeader("Refresh","3;URL=/虚拟路径/login.html");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
文件下载
/*
文件下载
*/
@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.创建字节输入流,关联读取的文件
//获取文件的绝对路径
String realPath = getServletContext().getRealPath("/img/hm.png");
//创建字节输出流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
//2.设置响应头支持的类型 应用支持的类型为字节流
/*
Content-Type 消息头名称 支持的类型
application/octet-stream 消息头参数 应用类型为字节流
*/
resp.setHeader("Content-Type","application/octet-stream");
//3.设置响应头以下载方式打开 以附件形式处理内容
/*
Content-Disposition 消息头名称 处理的形式
attachment;filename= 消息头参数 附件形式进行处理
*/
resp.setHeader("Content-Disposition","attachment;filename=" + System.currentTimeMillis() + ".png");
//4.获取字节输出流对象
ServletOutputStream sos = resp.getOutputStream();
//5.循环读写文件
byte[] arr = new byte[1024];
int len;
while((len = bis.read(arr)) != -1) {
sos.write(arr,0,len);
}
//6.释放资源
bis.close();
sos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
【JavaWeb】请求和响应Request&Response的更多相关文章
- JavaWeb学习笔记四 request&response
HttpServletResponse 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应res ...
- JavaWeb请求与响应 Cookie&Session
1.请求与响应 &Cookie&Session 1.1.请求与响应 HTTP协议 概念:英文全称:HyperText Transfer Protocol 中文全称:超文本传输协议 ...
- Django整理(五) - 请求与响应 - request对象
请求对象 一.客户端传参的几种方式 1. 通过URL路径(path)传递,例如:http://127.0.0.1:8000/news/1/2,两个参数:id和page 2. 通过 query stri ...
- java http接口请求响应 request response
接口类: 1 package org.sunshine.dcda.epg.wechat.controller.niao; 2 3 import javax.servlet.http.HttpServl ...
- Django 请求和响应 request return
request.method 请求方法 request.get get请求信息 request.post post请求信息 request.path 请求路径 方法: requset.get_fu ...
- 过滤器中的chain.doFilter(request,response)
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要 ...
- 03-【request对象获取请求的数据 & request对象存取值】
request概述(封装了客户端所有的请求数据) request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest.在 ...
- 请求头(request headers)和响应头(response headers)解析
*****************请求头(request headers)***************** POST /user/signin HTTP/1.1 --请求方式 文件名 http ...
- Scrapy爬虫入门Request和Response(请求和响应)
开发环境:Python 3.6.0 版本 (当前最新)Scrapy 1.3.2 版本 (当前最新) 请求和响应 Scrapy的Request和Response对象用于爬网网站. 通常,Request对 ...
随机推荐
- 使用IDEA创建Maven项目
一.创建一个普通的Maven项目 1.启动IDEA 2.创建一个Maven项目 3.Maven的目录结构 二.使用模板创建一个MavenWeb项目 1.启动IDEA 2.创建一个MavenWeb项目 ...
- 最短路径问题,BFS,408方向,思路与实现分析
最短路径问题,BFS,408方向,思路与实现分析 继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~ 最短路径问题 说起这个问题,先说个 ...
- 「题解」PA2019 Terytoria
本文将同步发布于: 洛谷博客: csdn: 博客园: 因为简书系统升级,所以本文未在简书上发布. 题目 题目链接:洛谷 P5987.LOJ 3320.官网. 题意概述 在二维平面直角坐标系上,有一个长 ...
- .h5图像文件(数据集)的读取并存储 工具贴(二)
概述 H5文件是层次数据格式第5代的版本(Hierarchical Data Format,HDF5),它是用于存储科学数据的一种文件格式和库文件.由美国超级计算中心与应用中心研发的文件格式,用以存储 ...
- 二、Nginx 服务器升级
1,编译新版本的nginx 软件 [root@client lnmp_soft]# tar -xf nginx-1.12.2.tar.gz -C .. [root@client lnmp_soft ...
- Java Spring boot 多商户入驻 外卖|跑腿|代驾 Uniapp版本
技术说明: 源码下载:https://www.yuanmahy.com/8357.html 开发环境:jdk1.8,mysql5.7,node 9.4,redis6.2,npm6.9 开发工具:前端使 ...
- 【SQLite】教程09-VBA读取SQLite数据之ODBC,及中文乱码问题
VBA使用ODBC Driver for SQLite读SQLite 如下图有这么一个SQlite数据库,我们要读取它 需要先安装ODBC,可以从这里下载: SQLite 3 ODBC Driver ...
- spring boot使用@Async异步注解
1.java的大部分接口的方法都是串行执行的,但是有些业务场景是不需要同步返回结果的,可以把结果直接返回,具体业务异步执行,也有些业务接口是需要并行获取数据,最后把数据聚合在统一返回给前端. 通常我们 ...
- 【题解】Luogu p2014 选课 树型dp
题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...
- Windows内核开发-Windows内部概述-1-
Windows内部概述-1- 进程: 进程是一个程序的运行实例的控制和管理对象.一般的程序员所说进程运行,这样的说法是不对的,因为进程不能运行程序,进程只能管理该程序运行.线程才是真正的执行代码的东西 ...