注:之前学过,再次进行复习与巩固
javaWeb
1.基本概念:
1.1 简单介绍
静态web:html、css,提供给所有人看的数据始终不会发生改变
动态的web:提供给所有人的数据始终发生变化,每个人不同时间,不同地点看到也不同,技术有Servlet/jsp,ASP,PHP
1.2 web应用程序
可以提供浏览器访问的程序,资源存放在某一个ip之上,使用URL进行访问,使用tomcat将应用程序放在服务器上。
一个web应用包含有:html、css、js、jsp、servlet、jar包、配置文件
1.3 静态web
*.htm *.html 直接使用浏览器访问的静态页面
静态web的缺点:Web页面无法动态更新,所有用户看到同一个页面,使用前端技术js等伪动态,并且无法与数据库交互
1.4 动态web
缺点是:动态资源出错需要系统重新更新和维护
优点是:可以与数据库交互,页面数据动态,用户界面显示不同
2.web服务器
ASP:微软,国内最早流行的 在html中嵌入VB脚本,可以放在IIS服务器上运行
PHP:开发速度快,功能强,代码简单,但无法承载大的访问量
jsp/servlet:基于java语言的,可以承担三高问题
服务器Tomcat:服务器是一种被动的操作,用来处理用户的一些请求和用户一些响应信息。(安装前需要有jdk环境)
3.Tomcat
3.1下载地址:官方地址
3.2 tomcat目录结构:
bin:脚本目录
启动脚本:startup.bat
停止脚本:shutdown.bat
conf:配置文件目录 (config /configuration)
核心配置文件:server.xml
用户权限配置文件:tomcat-users.xml
所有web项目默认配置文件:web.xml
lib:依赖库,tomcat和web项目中需要使用的jar包
logs:日志文件.
localhost_access_log..txt tomcat记录用户访问信息,星表示时间。
例如:localhost_access_log.2016-02-28.txt
temp:临时文件目录,文件夹内内容可以任意删除。
webapps:默认情况下发布WEB项目所存放的目录。
work:tomcat处理JSP的工作目录。
4.Http协议
4.1 简单介绍:
HTTP,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的 一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为 了提供一种发布和接收HTML页面的方法
4.2 http协议的组成
Http协议由Http请求和Http响应组成,当在浏览器中输入网址访问某个网站时, 你的浏览器会将你的请求封装成一个Http请求发送给服务器站点,服务器接收到请 求后会组织响应数据封装成一个Http响应返回给浏览器。即没有请求就没有响应。
4.3http请求
请求行、请求头、空行、请求体
请求行:
请求方式:POST、GET
请求的资源:/DemoEE/form.html
协议版本:HTTP/1.1
HTTP/1.0,发送请求,创建一次连接,获得一个web资源,连接断开。
HTTP/1.1,发送请求,创建一次连接,获得多个web资源,保持连接。
请求头:是一种键值对形式表示的客户端信息
常见请求头 | 描述 |
---|---|
Referer | 浏览器通知服务器,当前请求来自何处。 |
Cookie | 与会话有关技术,用于存放浏览器缓存的cookie信息 |
User-Agent | 浏览器通知服务器,客户端浏览器与操作系统相关信息 |
Connection | 保持连接状态。Keep-Alive 连接中,close 已关闭 |
Host | 请求的服务器主机名 |
Content-Type | 如果是POST请求,会有这个头,默认值为application/x-www-form-urlencoded,表示请求体内容使用url编码 |
Accept | 浏览器可支持的MIME类型。文件类型的一种描述方式 |
Accept-Encoding | 浏览器通知服务器,浏览器支持的数据压缩格式 |
Accept-Language | 浏览器通知服务器,浏览器支持的语言。 |
请求体:
当请求方式是post的时,请求体会有请求的参数;如果请求方式为get,那么请求参数不会出现在请求体中,会拼接在url地址后面
4.4 http响应
响应行 : http协议、状态码、状态信息
常见状态码:
200 :请求成功 302 :请求重定向 304 :请求资源没有改变,访问本地缓存
404 :请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除
500 :服务器内部错误。通常程序抛异常
响应头:键值对形式的信息
常见请求头 | 描述 |
---|---|
Location | 指定响应的路径,需要与状态码302配合使用,完成跳转 |
Content-Type | 响应正文的类型(MIME类型) |
Content-Disposition | 通过浏览器以下载方式解析正文取值:attachment;filename=xx.zip |
Set-Cookie | 与会话相关技术。服务器向浏览器写入cookie |
响应体:响应体是服务器回写给客户端的页面正文,浏览器将正文加载到内存,然后解析渲染,显示页面内容
5.Servlet(web核心技术)
5.1 简介:
Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API 动态的向客户端输出内容
5.2 Servlet使用
1.创建类实现Servlet接口
2.覆盖尚未实现的service方法
3.在web.xml中进行servlet的相关配置
(注:实际开发中的自定义的Servlet不会实现Servlet接口,因为其中需要实现的方法过多,一般继承HttpServlet类)
1.创建类继承HttpServlet接口
2.覆盖doGet和doPost方法
3.在web.xml中进行servlet的相关配置
5.3 Servlet的API
Servlet接口中的方法有:init、service、destory
init(ServletConfig config)方法:第一次创建Servlet对象的时候执行
service(ServletRequest request,ServletResponse response)每次有请求时都会执行
destory():servlet销毁时执行
HttpServlet类中的方法:
init()、doGet(HttpServletRequest req ,HttpServletResponse req)、doPost(HttpServletRequest req ,HttpServletResponse rep)、destory()
Servlet的生命周期:
何时创建? 默认第一次访问时创建
何时销毁?服务器关闭时销毁
每次必须执行的方法是:service(ServletRequest req,ServletResponse rep)方法
5.4 Servlet的配置
配置文件web.xml中servlet配置
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>全类名</servlet-class>
</servlet>
<servlet-mapping>
<servler-name>abc</servler-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
其中url-pattern的配置方式:
1.完全匹配
/helloServlet 2.目录匹配
/aaa/bbb/* 3.扩展名匹配
*.abc
不可混用
服务器启动实例化Servlet配置:servlet默认第一次访问时创建
缺省Servlet:当所有访问的资源都不匹配时,在配置中的/匹配为缺省的Servlet,不匹配的访问有其负责
欢迎页面配置:
5.5 ServletContext对象
1.什么是ServletContext对象?
ServletContext代表是一个web应用的环境(上下文)对象,ServletContext对象 内部封装是该web应用的信息,ServletContext对象一个web应用只有一个
2.ServletContext对象的生命周期?
创建:该web应用被加载、销毁:web应用被卸载
3.怎样获得ServletContext对象?
1)ServletContext servletContext = config.getServletContext();
2)ServletContext servletContext = this.getServletContext();
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//this.getInitParameter(name); 初始化参数
//this.getServletConfig(); servlet配置
//this.getServletContext(); 上下文描述
}
ServletContext的作用域
- xml中配置全局初始化参数
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
java程序获取全局的信息
ServletContext context = getServletContext();
String param = context.getInitParameter("driver");
- 获取web应用资源的绝对路径(重点)
String path = context.getRealPath(路径地址);
- ServletContext是一个域对象(重点)
域对象就是存储数据的区域。ServletContext的作用范围是:整个Web应用(整个web资源都可以向servletcontext中存取数据,数据可以共享、获取初始化参数、请求和转发、读取配置文件)
域对象的通用方法:
ServletContext.setAttribute(String name, Object obj);
ServletContext.getAttribute(String name);
ServletContext.removeAttribute(String name);
ServletContext.getRequestDispatcher(path);
//转发,url地址不会发生改变,区别于重定向
ServletContext读取配置文件:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// this.getInitParameter(name); 初始化参数
// this.getServletConfig(); servlet配置
// this.getServletContext(); 上下文描述
// 响应文件类型
response.setContentType("text/html");
// 响应编码类型
response.setCharacterEncoding("utf-8");
// 设置上下文内容
this.getServletContext().setAttribute("name", "星仔");
// 获取配置文件的内容,可以是类路径也可以是java的路径
InputStream resourceAsStream = this.getServletContext()
.getResourceAsStream("/WEB-INF/classes/com/itxing/hello/db.properties");
Properties prop = new Properties();
prop.load(resourceAsStream);
String username = prop.getProperty("username");
String password = prop.getProperty("password");
// 输出信息
response.getWriter().print("<h1>Hello:</h1>" + username + "您的密码是:" + password);
}
5.6 maven项目的创建
之前介绍过一个idea创建maven的项目记录,今天再使用eclipse进行创建项目:
1.maven与eclipse配置
1.创建一个maven项目
2.跳过骨架,否则创建的项目目录结构不完整
3.填写项目信息
出错记录:
解决办法:创建文件时,将工作空间选中
创建项目后,手动在webapp目录下创建文件夹WEB-INF并添加web.xml
web项目需要注意的有,添加pom文件时:将javax.servlet的范围指定为provided,否则会与服务器端冲突
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!--maven由于约定大于配置,有可能maven项目的配置文件无法被导出或者生效,需要配置builder-->
<build>
<resources> <resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include> <include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include> <include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
创建一个servlet,继承HttpServlet,重写doGet和doPost方法:
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public HelloServlet() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 响应文件类型
response.setContentType("text/html");
// 响应编码类型
response.setCharacterEncoding("utf-8");
// 输出信息
response.getWriter().print("<h1>Hello</h1>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
web.xml文件中的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!--配置默认的首页-->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--配置servlet映射-->
<servlet>
<description></description>
<display-name>hello</display-name>
<servlet-name>hello</servlet-name>
<servlet-class>com.itxing.hello.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
5.7 HttpServletResponse
创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大
类中定义了常用的类方法(是一个接口)和状态码常量
//设置响应行的状态码
setStatus(int sc)
//设置response响应头
setDateHeader(String name, long date);
addDateHeader(String name, long date);
setHeader(String name, String value);
addHeader(String name, String value);
setIntHeader(String name, int value);
addIntHeader(String name, int value);
ServletOutputStream getOutputStream();//响应头设置字节
//设置响应体
setContentLength(int len);
setCharacterEncoding(String charset);
setContentType(String type);
getWriter()
实际开发中解决中文乱码问题使用的是
response.setContentType("text/html;charset=UTF-8");
常用应用:下载文件
步骤:
1.获取下载文件的路径 2. 下载文件名
3.设置让浏览器能够支持下载 4. 获取下载文件的输入流
5.创建缓冲区 6.获取OutputStream对象
7.将FieldOutputStream流写入到buffer缓冲区
8.使用OutputStream将缓冲区数据输出到客户端
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取下载文件的路径
// String path = "G:\\Leisure\\Callname\\img\\dog.jpg";
String path = getServletContext().getRealPath("G:\\Leisure\\Callname\\img\\dog.jpg");
System.out.println(path);
// 文件名
String filename = path.substring(path.lastIndexOf("\\") + 1);
// 设置下载文件的头
resp.setHeader("Content-disposition", "attachment;filename" + URLEncoder.encode(filename, "utf-8"));
// 创建文件的输入流
FileInputStream in = new FileInputStream(path);
// 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 获取outputStream对象
ServletOutputStream out = resp.getOutputStream();
// 将文件输出流写入缓冲区
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
// 使用输出流将缓冲区中的数据输出到客户端
in.close();
// out.close(); response获得流不需要手动关闭
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
下载文件的相关问题:
如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况, 原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐 浏览器是Base64编码方式。
//以下agent就是请求头User-Agent的值
String agent = request.getHeader("User-Agent");
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
response验证码功能,用到java的图片类,产生一个图片,主要是为了理解响应(非重点)
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 让浏览器自动3秒刷新一次
resp.setHeader("refresh", "3");
// 在内存中创建一张图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
// 得到图片
Graphics2D graphics = (Graphics2D) image.getGraphics();
// 设置图片背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0, 0, 80, 20);
// 给图片写数据
graphics.setColor(Color.BLUE);
graphics.setFont(new Font(null, Font.BOLD, 20));
graphics.drawString(makeNum(), 0, 20);
// 告知浏览器,这个请求使用图片方式代开
resp.setDateHeader("expires", -1);
// 网站存在缓存,不让浏览器缓存
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Progma", "no-cache");
// 把图片写给浏览器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
private String makeNum() {
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
Response重定向(地址会变化):
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("Location", "/mavenWeb/hello");
// resp.setStatus(302);
resp.sendRedirect("/mavenWeb/hello");
}
面试题:转发与重定向的相同点与不同点
相同点:
页面都会实现跳转
不同点:
请求转发时,url页面不会变化
重定向时url地址栏会变化
5.8 HttpServletRequest
service方法中的request的类型是ServletRequest,而doGet/doPost方法的request的类型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加强大
request的相关方法
1.请求行:
获得客户端请求:String getMethod()
获得请求资源: String getRequestURI() ;String getRequestURI();
String getContextPath()Web应用的名称
String getQueryString() 获取get请求提交的url地址后的参数字符串
request.getRemoteAddr()获取客户的ip地址
2.请求头:
long getDataHeader(String name) String getHeader(String name)
Enumeration getHeaderNames() Enumeration getHeaders(String name)
int getIntHeader(String name)
3.请求体
String getParameter(String name) String[] getParameterValues(String name)
get提交与post提交时解决乱码问题:
post提交乱码:request.setCharacterEncoding(“UTF-8”);
get提交乱码:parameter = new String(parameter.getbytes(“iso8859-1”),”utf-8”);
获取前端参数
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 接收参数中文乱码进行处理
req.setCharacterEncoding("utf-8");
String name = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobby");
// 后台接收参数中文乱码问题
System.out.println(name + " " + password + " " + Arrays.toString(hobbys));
req.getRequestDispatcher("/index.html").forward(req, resp);
// 响应编码处理
resp.setCharacterEncoding("utf-8");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
前端:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
2.request是一个能够存储数据的域对象,因此有如下方法:
setAttribute(String name,Object o) get Attribute(String name) removeAttribute(String name)
2.request完成请求转发
RequestDispatcher getRequestDispatcher(String path) 转发的是地址
requestDispatcher.forward(ServletRequest req,ServletResponse resp)
面试题:
ServletContext域与Request域的生命周期比较
ServletContext | Request |
---|---|
创建:服务器启动时;销毁:;服务器关闭;域的作用范围:整个web应用 | 创建:访问时创建;销毁:响应结束request销毁;域的作用范围:一次请求总 |
再谈转发和重定向:
1.重定向两次求情,转发一次请求
2.重定向地址栏地址变化,转发地址不变
3.重定向可以访问外部网站,转发只能访问内部资源
4.转发的性能要优于重定向