Http
HTTP(超文本传输协议)是一个简单的请求-响应协议,通常运行在TCP上。
- 文本:html,字符串,…
- 超文本:图片,音乐,视频,定位,地图…
- 80
Https:安全的
- 443
Http两个时代
- http1.0
http/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接 - http2.0:
http/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
Http请求
- 客户端—发送请求(Request)-----服务器
词条:
Request URL: https://baike.baidu.com/api/usercenter/login? //请求地址
Request Method: GET //get/post方法
Status Code: 200 OK //状态码
Remote(远程) Address: 111.45.3.101:443
Referrer Policy: unsafe-url
请求行
- 请求行中的请求方式:GET
- 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
get: 请求能够携带的参数较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效。
post: 请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。
消息头
Accept:告诉浏览器,它所支持的数据类型
Accept——Encoding:支持哪种编码格式:GBK UTF-8 GB2312 ISO8859-1
Accept——Language:告诉浏览器,它的语言环境
Cache——Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
Host: 主机…/.
Http响应
- 服务器—响应----客户端
Cache-Control:pricate 缓存控制
Connection: keep-alive 连接
Content-Encoding: gzip 编码
Content-Type: application/x-javascript 类型
Accept:告诉浏览器,它所支持的数据类型
Accept——Encoding:支持哪种编码格式:GBK UTF-8 GB2312 ISO8859-1
Accept——Language:告诉浏览器,它的语言环境
Cache——Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
Host: 主机…/.
Reflush:刷新,告诉客户端多久刷新一次。
Location:让网页重新定位。
响应状态码
200:请求响应成功
3XX:请求重新定向
- 重定向:你重新到我给你新位置去;
4XX:找不到资源
- 资源不存在
5XX:服务器代码错误 500 502 …
常见的面试题
当你在浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
Maven
我们为什么要学习这个工具?
1.在javaWeb开发中,需要使用大量的jar包,我们手动的去导入不现实。
2.如何能让一个东西能够帮我们自动导入这些jar包呢。
由此,Maven诞生了。
Maven项目架构管理工具
我们目前用来就是方便导入jar包!
Maven的核心思想:约定大于配置
- 有约束,不要去违反。
Maven会规定好你该如何去编写我们的java代码,必须要按照这个规范来;
Maven下载
Apache官网:链接
下载完成后,解压即可;
电脑上的所有环境都放在一个文件夹下,方便管理;
配置环境变量
在系统环境变量中
配置如下:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 在系统的path中配置%MAVEN_HOME%/bin
测试Maven是否安装成功,保证必须完成配置!
阿里云镜像
- 镜像:mirrors
作用:加速我们的下载速度 - 国内建议使用阿里云的镜像
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
本地仓库
建立一个本地仓库: localRepository
<localRepository>F:\Maven\apache-maven-3.8.1\maven-repo</localRepository>
新建文件夹:maven-repo
对应上一张图片的操作。
在IDEA中使用Maven
1.启动IDEA
2.创建一个Maven项目
3.
4.
5.观察maven仓库中多了什么东西?
6.IDEA中的Maven设置
注意:IDEA项目创建成功后,看一眼Maven的配置。
7.到这里,Maven在IDEA中的配置和使用就OK了。
创建一个普通的Maven项目
这个只有Web应用下才会有。
标记文件夹功能
在IDEA中配置Tomcat服务
解决警告问题:我们访问一个网站,需要指定一个文件夹名字;必须要。
pom文件
pom.xml是maven的核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--这里就是我们刚才配置的GAV-->
<groupId>com.tian</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!--Package:项目的打包方式
jar:java应用
war:javaWeb应用
-->
<packaging>war</packaging>
<name>javaweb-01-maven Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<!--配置-->
<properties>
<!--项目的默认构建编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--编码版本-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!--项目依赖-->
<dependencies>
<!--具体依赖的jar包位置文件-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--项目构建用的东西-->
<build>
<finalName>javaweb-01-maven</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Maven的高级之处就在于,他会帮你导入这个JAR包所依赖的其他jar包
资源配置解决问题(重要)
maven由于他的约定大于配置,我们之后可能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
在build中配置resources,来防止我们资源导出失败的问题
<build>
.......
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
......
</build>
IDEA操作
目录树
Maven中的jar包联系关联图。
Maven仓库
maven仓库:链接
第一个HelloServlet程序
第一步:
第二步:
Servlet
Servlet简介
- Servlet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet。
- Servlet 就是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
编写一个类实现Servlet接口
把开发好的java类部署到web服务器中。
把实现了Servlet接口的java程序叫做,Servlet
HelloServlet-Maven项目的搭建
1.构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven主工程;
2.关于Maven父子工程的理解:
父项目pom.xml里会有:
<modules>
<module>javaweb-01</module>
</modules>
子项目pom.xml里会有,没有则手动添加:
<!--引入父类的Maven已经导入的包-->
<parent>
<groupId>com.tian</groupId>
<artifactId>javaweb-02-servlet</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的java子项目可以直接使用
son extends father
3.Maven环境优化
修改web.xml为最新的
将maven的结构搭建完整
4.编写helloServlet程序。
重写doGet/doPost方法:
由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");//类型
resp.setCharacterEncoding("utf-8");//设置编码格式
PrintWriter writer = resp.getWriter();//响应流
writer.print("早上好!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
编写Servlet的映射
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,然而浏览器需要连接WEB服务器,所以我们需要再web服务器中注册我们写的Servlet,还需给他一个浏览器能够访问的路径。
- 配置Servlet映射
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
配置Tomcat服务器
- 前面有教程
Servlet原理
这是我去copy来的图片。(狂神说)
- 一个Servlet可以指定一个或者多个路径。
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet2</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用路径。
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet/*</url-pattern>
</servlet-mapping>
- 默认的
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 可以自定义后缀实现请求映射:访问
注意点,*前面不能加项目映射的路径。
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.tian</url-pattern>
</servlet-mapping>
优先级问题
指定固有的映射路径优先级最高,如果找不到就会走默认的处理请求。
<servlet-mapping>
<servlet-name>Error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
web.xml中的配置信息
- web.xml里面的信息最好与Tomcat中的ROOT里的模板是一致的。
- F:\Tomcat\apache-tomcat-9.0.45\webapps\ROOT\WEB-INF
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
数据共享
我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到;
ServletContext context = this.getServletContext();
存入和取出的Servlet类不一致,可以使Servlet类之间相互通信
- 存入
ServletContext context = this.getServletContext();
String a = "某某某";
context.setAttribute("username",a);//将一个数据保存在了ServletContext中,名字为username。值为a
- 取出
ServletContext context = getServletContext();
String a = (String) context.getAttribute("username");//取出key为username的值
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.print("<h1>"+attribute+"</h1>");
- 然后分别配置他们的xml
<servlet>//存入
<servlet-name>TextServlet01</servlet-name>
<servlet-class>com.tian.servlet.TextServlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TextServlet01</servlet-name>
<url-pattern>/TextServlet01</url-pattern>
</servlet-mapping>
<servlet>//取出
<servlet-name>TextServlet02</servlet-name>
<servlet-class>com.tian.servlet.TextServlet02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TextServlet02</servlet-name>
<url-pattern>/TextServlet02</url-pattern>
</servlet-mapping>
获取初始化参数
- 配置一些初始化参数:
<context-param>
<param-name>id</param-name>
<param-value>202001405236</param-value>
</context-param>
ServletContext context = this.getServletContext();//获取上下文对象
String id = context.getInitParameter("id");//获取初始化参数
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.print("<h1>"+id+"</h1>");
请求转发(RequestDispatcher)
public class TextServlet03 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
//RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/TextServlet02");//转发的请求路径
// requestDispatcher.forward(req,resp);//调用forward实现请求转发
servletContext.getRequestDispatcher("/TextServlet02").forward(req,resp);//组合起来的写法
}
}
读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一路径下:class,我们俗称这个路径为classpath:
思路:需要一个文件流;
InputStream resourceAsStream = this.getServletContext().getResourceAsStream(“/WEB-INF/classes/db.properties”);
public class TextServlet04 extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
String name = properties.getProperty("name");
String id = properties.getProperty("root");
resp.getWriter().print(name+":"+id);
}
HttpServletResponse
下载文件
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.要获取下载文件的路径
String realPath = "F:\\20210720\\javaweb-02-servlet\\response\\src\\main\\resources\\img.png";绝对路径
System.out.println("下载文件的路径:"+realPath);
//2.下载的文件是啥名?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3.设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则可能出现乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));//web下载文件的头消息
//4.获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5.创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//6.获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7.将FileOutputStream流写入到buffer缓冲区中 ,//8.使用OutputStream将缓冲区中的数据输出到客户端
while ((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
out.close();//关闭流
in.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
重定向
B一个web资源收到客户端A请求后,他会通知客户端A去访问另一个web资源C,这个过程叫做重定向。
常见的场景;
- 用户登录
void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
resp.setHeader("Location","/r/img");
resp.setStatus(302);
* */
resp.sendRedirect("/response_war/fileservlet");//重定向的目标地址
}
- 重定向与转发的区别
相同点:页面都会跳转
不同点:请求转发的时候,url不会产生变化 307
重定向的时候,url地址栏会发生变化 302
- ${pageContext.request.contextPath}代表当前路径
<html>
<body>
<h2>Hello World!</h2>
<%@page contentType="text/html;charset=UTF-8"%>
<%--这里的提交的路径,需要找到项目路径--%>
<%--${pageContext.request.contextPath}代表当前路径--%>
<form action="${pageContext.request.contextPath}/request" method="get">
账号 <input type="text" name="username"><br>
密码 <input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
public class RequestText extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向的时候一定要注意,路径问题,否则404;
resp.sendRedirect("/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletRequest
获取前端传递的数据,并且请求转发
- req.getParameter(“”);
请求转发
public class RequestText extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//返回乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("=========================");
System.out.println(username+":"+password);
System.out.println(Arrays.toString(hobbys));
System.out.println("=========================");
//重定向的时候一定要注意,路径问题,否则404;
resp.sendRedirect("/success.jsp");
//请求转发
// req.getRequestDispatcher("/success").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}