JavaWeb
1、基本概念
1.1、前言
- web开发:
web,网页的意思 , www.baidu.com
- 静态web
html,css
提供给所有人看的数据始终不会发生变化!
- 动态web
在Java中,动态web资源开发的技术统称为JavaWeb;
1.2、web应用程序
web应用程序:可以提供浏览器访问的程序;
web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理;
1.3、静态web
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-duIYP5WM-1606011633283)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201024211544056.png)]
- 静态web存在的缺点
- Web页面无法动态更新,所有用户看到都是同一个页面
- 它无法和数据库交互(数据无法持久化,用户无法交互)
1.4、动态web
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STr8UBh5-1606011633284)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201024215544081.png)]
缺点:
-
加入服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布;
- 停机维护
优点:
- Web页面可以动态更新,所有用户看到都不是同一个页面
- 它可以与数据库交互 (数据持久化:注册,商品信息,用户信息…)
2、web服务器
2.1 技术讲解
ASP:
PHP:
JSP/Servlet :
B/S:浏览和服务器
C/S: 客户端和服务器
3、Tomcat
3.1 安装tomcat
tomcat官网:http://tomcat.apache.org/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CxwGIe6F-1606011633285)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025100426862.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2clPmPMt-1606011633288)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025100454366.png)]
3.2 Tomcat启动和配置
文件夹作用:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pYCLd9OG-1606011633291)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025100547733.png)]
启动,关闭Tomcat :
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UxLsyk8X-1606011633292)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025100617292.png)]
访问测试:http://localhost:8080/
可能遇到的问题:
- Java环境变量没有配置
- 闪退问题:需要配置兼容性
- 乱码问题:配置文件中设置
3.3 配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hGQv1fDa-1606011633293)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025155239977.png)]
可以配置启动的端口号
- tomcat的默认端口号为:8080
- mysql:3306
- http:80
- https:443
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主机的名称
- 默认的主机名为:localhost->127.0.0.1
- 默认网站应用存放的位置为:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
参考:https://www.cnblogs.com/kismetv/p/7228274.html#title3
高难度面试题:
请你谈谈网站是如何进行访问的!
-
输入一个域名;回车
-
检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射;
有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
127.0.0.1 activation.guitar-pro.com
没有:去DNS服务器找,找到的话就返回,找不到就返回找不到;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEMDNlyd-1606011633293)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025155720751.png)]
- 可以配置一下环境变量(可选性)
3.4 发布一个web网站
不会就先模仿
- 将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了
网站应该有的结构
--webapps :Tomcat服务器的web目录
-ROOT
-kuangstudy :网站的目录名
- WEB-INF
-classes : java程序
-lib:web应用所依赖的jar包
-web.xml :网站配置文件
- index.html 默认的首页
- static
-css
-style.css
-js
-img
-.....
4、Http
4.1、什么是HTTP
HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。
-
文本:html,字符串,~ ….
-
超文本:图片,音乐,视频,定位,地图…….
-
80
Https:安全的
- 443
4.2、两个时代
- http1.0
- HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
- http2.0
- HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。‘
4.3、Http请求
- 客户端—发请求(Request)—服务器
百度:
Request URL:https://www.baidu.com/ 请求地址
Request Method:GET get方法/post方法
Status Code:200 OK 状态码:200
Remote(远程) Address:14.215.177.39:443
Accept:text/html
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9 语言
Cache-Control:max-age=0
Connection:keep-alive
1、请求行
- 请求行中的请求方式:GET
- 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不
安全,但高效 - post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内
容,安全,但不高效。
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不
2、消息头
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
4.4、Http响应
服务器—响应-----客户端
百度:
Cache-Control:private 缓存控制
Connection:Keep-Alive 连接
Content-Encoding:gzip 编码
Content-Type:text/html 类型
1.响应体
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;
2、响应状态码
200:请求响应成功 200
3xx:请求重定向
- 重定向:你重新到我给你新位置去;
4xx:找不到资源 404
- 资源不存在;
5xx:服务器代码错误 500 502:网关错误
5、Maven
5.1 Maven项目架构管理工具
Maven的核心思想:约定大于配置
- 有约束,不要去违反
Maven会自动帮助导入和配置jar包;
Maven会规定好你该如何去编写我们的Java代码,必须要按照这个规范来;
5.2 下载安装Maven
官网:https://maven.apache.org/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5KAN74Vv-1606011633294)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201017144646474.png)]
下载完成直接解压即可
5.3 配置环境变量
在我们的系统环境变量中
配置如下配置:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 在系统的path中配置 %MAVEN_HOME%\bin
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DghmPVQC-1606011633295)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201017144847101.png)]
mvn -version命令测试Maven是否安装成功
5.4 阿里云镜像
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGq3KPxv-1606011633295)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201017145127437.png)]
- 镜像: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>
5.5 本地仓库
在本地的仓库,远程仓库;
建立一个本地仓库:localRepository
<localRepository>D:\Environment\apache-maven-3.6.2\mavenrepo</localRepository>
5.6、在IDEA中使用Maven
- 启动IDEA
- 创建一个MavenWeb项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LyJtzv0u-1606011633296)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161506849.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rt04wsuy-1606011633298)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161527760.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5inAMjA-1606011633299)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161557646.png)]
- 等待项目初始化完毕
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yJsDzc7i-1606011633300)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161632464.png)]
- IDEA中的Maven设置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EIOqg5YJ-1606011633301)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161724552.png)]
5.7、创建一个普通的Maven项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QXTF0tYs-1606011633301)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161817100.png)]
这个只有在Web应用下才会有!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fVEAM5Uh-1606011633302)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161832109.png)]
5.8 标记文件夹功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4N3i4sF-1606011633302)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161852048.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s0JsFyso-1606011633303)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161907128.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y2JI7wmk-1606011633304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025161943762.png)]
5.9 在 IDEA中配置Tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wiYoFHYe-1606011633304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025162019675.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjAIIFG0-1606011633305)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025162036489.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lyI3kNm6-1606011633305)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201025162053110.png)]
解决警告问题
必须要的配置:为什么会有这个问题:我们访问一个网站,需要指定一个文件夹名字;
6、Servlet
6.1、Servlet简介
Servlet就是sun公司开发动态web的一门技术
Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小
步骤:
-
编写一个类,实现Servlet接口
-
把开发好的Java类部署到web服务器中。
-
把实现了Servlet接口的Java程序叫做,Servlet
6.2、HelloServlet
Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
-
构建一个普通的Maven项目,删掉里面的src目录,这个空的工程就是Maven主工程;
-
关于Maven父子工程的理解:
父项目会有:
<modules> <module>servlet-01</module> </modules>
子项目会有:
<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.kuang</groupId> <version>1.0-SNAPSHOT</version> </parent>
子项目可以共享父项目的jar包,父项目管理真个项目的jar包版本
-
Maven环境优化
-
修改web.xml为最新的
-
将maven的结构搭建完整
-
-
编写一个Servlet程序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3ZeFdw0-1606011633307)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201027144941594.png)]
- 编写一个普通类
- 实现Servlet接口,这里我们直接继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream =
resp.getOutputStream();
PrintWriter writer = resp.getWriter(); //响应流
writer.print("Hello,Serlvet");
}
@Override
protected void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException{
doGet(req, resp);
}
}
- 编写Servlet的映射
<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 配置Tomcat
注意:配置项目发布的路径就可以了 - 启动测试,OK!
6.3、Servlet原理
Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WNehPBZd-1606011633308)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201027145613823.png)]
6.4、Mapping问题
-
一个Servlet可以指定一个映射路径
-
一个Servlet可以指定多个映射路径
-
一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
- 默认请求路径
<!--默认请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
-
自定义指定一些后缀或者前缀等等….
-
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
6.5、ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的
web应用;
1、共享数据
我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//this.getInitParameter() 初始化参数
//this.getServletConfig() Servlet配置
//this.getServletContext() Servlet上下文
ServletContext context = this.getServletContext();
String username = "秦疆"; //数据
context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字"+username);
}
}
2、获取初始化参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
3、请求转发
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了ServletDemo04");
//RequestDispatcher requestDispatcher =
context.getRequestDispatcher("/gp"); //转发的请求路径
//requestDispatcher.forward(req,resp); //调用forward实现请求转发;
context.getRequestDispatcher("/gp").forward(req,resp);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iOcUDsmn-1606011633309)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201027172340202.png)]
4、读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:
思路:需要一个文件流;
username=root12312
password=zxczxczxc
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEBINF/classes/com/kuang/servlet/aa.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
}
6.6、HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对
象,一个代表响应的HttpServletResponse对象;
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
1、简单分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
响应的状态码
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
2、下载文件
- 向浏览器输出消息
- 下载文件
- 要获取下载文件的路径
- 下载的文件名是啥?
- 设置想办法让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端!
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1. 要获取下载文件的路径
String realPath = "F:\\班级管理\\西开【19525】\\2、代码\\JavaWeb\\javaweb-
02-servlet\\response\\target\\classes\\秦疆.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"));
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
while ((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
3、实现重定向
B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向
常见场景:
- 用户登录:
void sendRedirect(String var1) 1 throws IOException;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
/*
resp.setHeader("Location","/r/img");
resp.setStatus(302);
*/
resp.sendRedirect("/r/img");//重定向
}
面试题:请你聊聊重定向和转发的区别?
相同点
- 页面都会实现跳转
不同点
- 请求转发的时候,url不会产生变化 307;
- 重定向时候,url地址栏会发生变化 302;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5llgmIF0-1606011633310)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201027172340202.png)]
4、简单实现登录重定向
<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
<input type="submit">
</form>
@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("/r/success.jsp");
}
<servlet>
<servlet-name>requset</servlet-name>
<servlet-class>com.kuang.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>requset</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
6.7、HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封
装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X2Q8HXko-1606011633310)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103145246569.png)]
//通过请求转发
//这里的 / 代表当前的web应用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
7、Cookie、Session
7.1、会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之
为会话;
7.2、保存会话的两种技术
cookie
- 客户端技术 (响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在Session
中!
常见:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!
7.3、Cookie
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2JxzvI4C-1606011633311)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103150216313.png)]
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName(); //获得cookie中的key
cookie.getValue(); //获得cookie中的vlaue
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie
cookie:一般会保存在本地的 用户目录下 appdata;
-
一个网站cookie是否存在上限!聊聊细节问题
-
一个Cookie只能保存一个信息;
-
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
-
Cookie大小有限制4kb;
-
300个cookie浏览器上限;
删除Cookie;
- 不设置有效期,关闭浏览器,自动失效;
- 设置有效期时间为 0 ;
编码解码:
URLEncoder.encode("秦疆","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")
7.4、Session(重点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AgHkt0z3-1606011633312)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103150439233.png)]
什么是Session:
- 服务器会给每一个用户(浏览器)创建一个Seesion对象;
- 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
- 用户登录之后,整个网站它都可以访问!–> 保存用户的信息;保存购物车的信息……
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1GS5l07r-1606011633313)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103150612766.png)]
Session和cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
- Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资
源的浪费) - Session对象由服务创建;
使用场景:
- 保存一个登录用户的信息;
- 购物车信息;
- 在整个网站中经常会使用的数据,我们将它保存在Session中;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("秦疆",1));
//获取Session的ID
String sessionId = session.getId();
//判断Session是不是新创建
if (session.isNew()){
resp.getWriter().write("session创建成功,ID:"+sessionId);
}else {
resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
}
//Session创建的时候做了什么事情;
// Cookie cookie = new Cookie("JSESSIONID",sessionId);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
//得到Session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销Session
session.invalidate();
会话自动过期:web.xml配置
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后Session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
8、MVC三层架构
什么是MVC: Model view Controller 模型、视图、控制器
8.1、早些年
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLPu8Mn7-1606011633317)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103151137613.png)]
用户直接访问控制层,控制层就可以直接操作数据库;
servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
程序猿调用
|
JDBC
|
Mysql Oracle SqlServer ....
8.2、MVC三层架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUOKtXDR-1606011633318)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103151348469.png)]
Model
- 业务处理 :业务逻辑(Service)
- 数据持久层:CRUD (Dao)
View
- 展示数据
- 提供链接发起Servlet请求 (a,form,img…)
Controller (Servlet)
- 接收用户的请求 :(req:请求参数、Session信息….)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,
password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用
户名和密码是否正确-->数据库
9、Filter (重点)
Filter:过滤器 ,用来过滤网站的数据;
处理中文乱码
登录验证….
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IyCK8JRj-1606011633319)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103152545904.png)]
Filter开发步骤:
-
导包
-
编写过滤器
1、导包不要错(javax.servlet)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SpsVMbDi-1606011633319)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103152623112.png)]
实现Filter接口,重写对应的方法即可
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现!
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//Chain : 链
/*
1. 过滤中的所有代码,在过滤特定请求的时候都会执行
2. 必须要让过滤器继续同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前....");
chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁:web服务器关闭的时候,过滤会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
2、在web.xml中配置 Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.kuang.filter.CharacterEncodingFilter</filterclass>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是 /servlet的任何请求,会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
<!--<url-pattern>/*</url-pattern>-->
</filter-mapping>
10、JDBC
什么是JDBC : Java连接数据库!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuHvNKhr-1606011633320)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103152752909.png)]
需要jar包的支持:
java.sql
javax.sql
mysql-conneter-java… 连接驱动(必须要导入)
实验环境搭建
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','zs@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(2,'李四','123456','ls@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(3,'王五','123456','ww@qq.com','2000-01-01');
SELECT * FROM users;
导入数据库依赖
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
IDEA中连接数据库:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lSqRkzv4-1606011633321)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201103152855772.png)]
JDBC 固定步骤:
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement : CRUD
- 编写SQL (根据业务,不同的SQL)
- 执行SQL
- 关闭连接
public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException,SQLException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url="jdbc:mysql://localhost:3306/jdbc?
useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username,
password);
//3.向数据库发送SQL的对象Statement,PreparedStatement : CRUD
Statement statement = connection.createStatement();
//4.编写SQL
String sql = "select * from users";
//5.执行查询SQL,返回一个 ResultSet : 结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
//6.关闭连接,释放资源(一定要做) 先开后关
rs.close();
statement.close();
connection.close();
}
}
事务
要么都成功,要么都失败!
ACID原则:保证数据的安全。
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
Junit单元测试
依赖
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
简单使用
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!
@Test
public void test(){
System.out.println("Hello");
}
搭建一个环境
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(40),
money FLOAT
);
INSERT INTO account(`name`,money) VALUES('A',1000);
INSERT INTO account(`name`,money) VALUES('B',1000);
INSERT INTO account(`name`,money) VALUES('C',1000);
@Test
public void test() {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url="jdbc:mysql://localhost:3306/jdbc?
useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
Connection connection = null;
//1.加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
connection = DriverManager.getConnection(url, username,
password);
//3.通知数据库开启事务,false 开启
connection.setAutoCommit(false);
String sql = "update account set money = money-100 where name =
'A'";
connection.prepareStatement(sql).executeUpdate();
//制造错误
//int i = 1/0;
String sql2 = "update account set money = money+100 where name =
'B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上两条SQL都执行成功了,就提交事务!
System.out.println("success");
} catch (Exception e) {
try {
//如果出现异常,就通知数据库回滚事务
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
**狂神说JAVA B站个人空间:
https://space.bilibili.com/95256449?from=search&seid=842697730049080**