学习目录
零、互联网通信流程
(一)、设计技术【偏过时】
-
控制浏览器行为技术:HTML、CSS、JavaScript
-
控制硬盘上数据库行为技术:MySql数据库服务器管理使用(SQL重点),JDBC规范
-
控制服务端Java行为技术:Http服务器,Servlet,JSP
-
互联网通信流程开发规则:MVC
(二)、实质
两台计算机通过网络实现文件共享行为
(三)、角色划分
- 客户端计算机:用于发送请求,索要资源文件的计算机
- 服务端计算机:用于接受请求,提供对应的资源文件计算机
(四)、互联网通信模型
1. C/S通信模型:
C:client software:客户端软件
(1)客户端软件专门安装在客户端计算机上
(2)帮助客户端计算机向指定服务端计算机发送请求,索要资源文件
(3)帮助客户端计算机将服务端计算机发送回来 二进制数据 解析为 文字、数字、图片、视频、命令、
S:server software:服务器软件
(1)服务器软件专门安装在服务端计算机上
(2)服务器软件用于接收来自于特定的客户端软件发送请求
(3)服务器软件在接收到请求之后自动的在服务端计算机上定位被访问的资源文件
(4)服务器软件自动的将定位的文件内容解析为 二进制数据 通过网络发送回发起请求的客户端软件上
使用场景
个人娱乐:微信,电商,视频网站;企业办公领域应用少
优缺点
- 优点:
- 安全性较高
- 有效降低服务端计算机工作压力
- 缺点
- 增加客户获得服务的成本
- 更新较为繁琐
2. B/S通信模型
B:browser,浏览器
(1)浏览器,安装在客户端计算机软件
(2)可以向任意服务器发送请求,索要资源文件
(3)可以将服务器返回的 二进制数据 解释为 文字、数字、图片、视频、命令
S:server software 服务器软件
(1)服务器软件专门安装在服务端计算机上
(2)可以接受任何浏览器发送请求
(3)自动的在服务端计算机上定位被访问的资源文件
(4)自动的将定位的资源文件内容以二进制形式发送会发送请求浏览器上
使用场景
既适用于个人,更适用于企业
优缺点
- 优点
- 不会增加用户获得服务的成本
- 几乎不需要更新浏览器
- 缺点
- 几乎无法有效对服务端计算机资源文件进行保护
- 服务端计算机工作压力极大(高并发)
(五)、共享资源文件
1. 定义:
- 可以通过网络进行传输的文件,都被称为共享资源文件
- 所有的文件内容都可以通过网络传输,所有文件都是共享资源文件
2. Http服务器下对共享资源文件分类
(1)静态资源文件
(2)动态资源文件
3. 静态资源文件
(1)如果文件内容是固定的,就被称为静态资源文件
(2)如果文件存放的是命令,这些命令只能在浏览器编译与执行,也被称为静态资源文件(.html、.css、.js)
4. 动态资源文件
- 文件存放命令,并且命令不能在浏览器编译与执行,只能在服务端计算机编译执行,该文件被称为动态资源文件(.class)
5. 静态资源文件与动态资源文件调用的区别
-
静态资源文件被索要时,Http服务器直接通过输出流将静态文件内容或者命令以二进制形式推送给发起请求的浏览器
-
动态资源文件被索要时,Http服务器需要创建当前class文件的实例对象,通过实例对象调用对应的方法处理用户请求,通过输出流将运行结果以二进制形式推送给发起请求的浏览器
(六)、开发人员担任的工作
1. 客户端计算机上(浏览器)
控制浏览器请求行为(三要素)
- 控制浏览器发送的请求地址
- 控制浏览器发送请求的方式
- 控制浏览器发送请求携带的参数
控制浏览器接收结果行为
- 控制浏览器采用对应编译器将接收二进制数据解析为文字、视频、图片、命令
- 控制浏览器将解析内容或者命令进行执行与展示
- 控制用户与浏览器之间交流 js ----> Jquery
2. 服务端计算机
Http服务器上保存静态资源文件和动态资源文件
一、web.xml一点配置
- idea生成的头文件有点过时,不妨改为如下的
<?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>
关于 Mapping 的问题
- 一个Servlet可以对应一个或多个映射路径
- 一个Servlet可以指定通用映射路径(加上通配符*)
<!--通用映射路径(加上通配符*)-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
2.默认请求路径(会把index页面取代,少用)
<!--默认请求路径-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
3.自定义后缀,注意:不能在*前面加上映射路径。
<!--自定义后缀实现映射请求
注意:不能在*前面加上映射路径
例如<url-patten>hello/*.do</url-patten>会报错
但是:项目名/中间乱七八糟的/还是乱七八糟的.do这样还是可以实现映射请求,只要后缀名包含.do即可
写法:<url-pattern>*.EverythingYouWantToWrite</url-pattern>
-->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
4.优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求。
二、ServletContext
简介
ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。
在web容器启动的时候,服务器会为每个web程序创建对应的一个ServletContext,代表当前的web应用。
一个web应用对应一个ServletContext。
对象获取
this.getServletContext();
this.getServletConfig().getServletContext()
常用方法
//添加属性:
setAttribute(String name, Object obj);
//得到值:
getAttribute(String name),这个方法返回Object
//删除属性:
removeAttribute(String name)
//ServletContext中的属性的生命周期从创建开始,到服务器关闭结束。
一般应用
1、多个Servlet可以通过ServletContext对象来实现数据间的共享
(可用Session或者request的方法将其取代)
类似于Session,通过ServletContext对象我们也可以实现数据共享,但值得注意的是,Session是只能在一个客户端中共享数据,而ServletContext中的数据是在所有客户端中都可以实现数据共享的。
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Hello");
resp.setContentType("text/html;utf-8");
//获得当前的ServletContext
//ServletContext可以实现数据共享
ServletContext context = this.getServletContext();
String username = "text";
//在web容器启动的时候,服务器会为每个web程序创建对应的一个ServletContext。代表当前的web应用。一个web应用对应一个ServletContext
//将数据保存在本程序对应的ServletContext中,键值对的形式保存
context.setAttribute("username",username);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
ServletContext context = this.getServletContext();
//获取资源
String username = (String) context.getAttribute("username");
//在页面输出
resp.getWriter().println("<h1>"+"名字"+username+"</h1>");
}
2、0.获取全局初始化参数
//获取初始化参数
public abstract String getInitParameter(String s)
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
ServletContext context = this.getServletContext();
//获得初始化参数
resp.getWriter().println(context.getInitParameter("texturl"));
}
<!--所有的Servlet都可以使用该配置-->
<context-param>
<param-name>texturl</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
2、1.获取当前Servlet的配置参数(局部)
<servlet>
<servlet-name>ServletDemo</servlet-name>
<servlet-class>com.vigil.servlet.ServletDemo</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
String encoding = this.getServletConfig().getInitParameter("encoding");
3、请求转发
(一般用request实现)
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//请求路径
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/Demo0");
//调用forward实现请求转发
requestDispatcher.forward(req,resp);
}
这种转发效果与通过request对象的getRequestDispatcher("/url").forward(req,resp)方法一样
//效果一样的转发方式
request.getRequestDispatcher("/url").forward(req, resp);
//
this.getServletContext().getRequestDispatcher("/url").forward(req, resp)
4、读取资源文件
(尽量用类加载和反射实现这一目的)
如何确定资源地址(getResourceAsStream(url))是一个重点
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这种方法的默认读取路径就是Web应用的根目录
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
// 创建属性对象
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().println(user + ":" + pwd);
}
username=root
password=123456
ServletContext的应用总结
涉及到不同用户共享数据,而这些数据量不大,同时又不希望写入数据库中,我们就可以考虑使用ServletContext实现。
例如:1. 网站计数器 2. 网站的在线用户显示
注意:因为存在ServletContext中的数据在服务器中会长时间,这样就会占用很多内存,因此在使用ServletContext时,建议不要往里面添加过大的数据!
三、HttpServletRequest和HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HTTPServletRequest对象,代表响应的HttpServletResponse
(一)、HttpServletResponse
1. 简单分类
(1)负责像浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
(2)负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int 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);
(3)响应状态码
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. 常见应用
(1)向浏览器输出消息
(2)下载文件
//关于字符串url
1、要获取下载的文件路径
2、下载的文件名
3、设置想办法让浏览器能够支持下载我们需要的东西
4、获取下载的文件输入流
//以下为Java io学习
5、创建缓冲区
6、获取OutputStream对象
7、将FileOutputStream流写入到buffer缓冲区
8、使用OutputStream将缓冲区中的数据输入到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、要获取下载的文件路径(java io 基础,这里写死了一个地址,仅作练习)
String realPath = "D:\\javadownload\\ideaworkplace\\javaweb-02-servlet\\response01\\src\\main\\resources\\1.jpg";
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);
}
// 8、关闭流
in.close();
out.close();
}
(3)验证码功能
前端实现:jsp
后端实现:需要使用Java的图片,产生一个图片
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器5s自动刷新一次
resp.setHeader("refresh","5");
//在内存中创建图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();//笔
//设置图片颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.blue);//换色
g.setFont(new Font(null,Font.BOLD,20));//设置字体
g.drawString(getNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,设置不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader(