A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© fashionkillyou 中级黑马   /  2017-11-23 22:22  /  633 人查看  /  0 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

[Java] 纯文本查看 复制代码
30 第五阶段WEB核心技术
30.1【HTTP协议的概述】
30.2【HTTP抓包】
30.3【HTTP请求响应详解】
Ø 请求部分
* 请求行
    * 提交方式:
        * 提交方式有很多,常用的GET和POST:
        * GET和POST的区别:
            * GET的提交的参数会显示到地址栏上,而POST不显示.
            * GET往往是有大小限制的,而POST没有大小的限制.
            * GET没有请求体,而POST有请求体.
    * 提交路径:
    * 协议版本:
* 请求头
    * 都是键值对的形式显示的.一般一个key对应一个value,也有个别的是一个key对应多个value.
    * User-Agent	:代表浏览器的类型. --- 文件下载:下载中文文件:IE使用URLEncodor进行编码,而Firefox使用Base64编码.
    * Referer	:代表的是网页的来源. --- 防盗链.
    * If-Modified-Since	:通常与响应中的头Last-Modified一起使用查找本地缓存.
* 请求体
    * 就是POST提交方式的提交的参数.
Ø 响应部分
* 响应行:
    * 协议版本
    * 状态码	:
        * 200	:成功
        * 302	:重定向
        * 304	:查找本地缓存
        * 404	:资源不存在
        * 500	:服务器内部错误
    * 状态码描述
* 响应头:键值对,一般一个key对应一个value,也有一个key对应多个value.
    * Last-Modified	:与请求中的If-Modified-Since一起使用查找本地缓存.
    * Content-Dispostion	:文件下载的使用使用的一个头信息.
    * Location	:重定向的跳转的路径.
    * Refresh	:定时刷新/定时跳转.
* 响应体:显示浏览器的页面的内容.
30.4【Servlet的概述】
servlet 就是运行在web服务器上的小的java程序,用来接收和响应客户端发来的请求.
30.4.1【使用ServletRequest接收参数】	234
* String getParameter(String name);	---用于接收一个名称对应一个值的数据.(文本框,单选框)
* String[] getParameterValues(String name);---用于接收一个名称对应多个值的数据.(复选框)
* Map getParameterMap();	---用于接收表单中的所有的数据,Map的key是表单提交的参数名称,Map的value是提交参数的值.
* Enumeration getParameterNames()	---用于获取表单中提交的所有的参数的名称.(Enumeration 枚举类型     
//这是一个servlet的代码案例
public class Servletdemo1 implements Servlet{
 
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//解决res乱码问题
res.setContentType("text/html;charset=UTF-8");
res.getWriter().write("春天来了");
//post 乱码问题的解决办法
req.setCharacterEncoding("utf-8");
//获取单个参数
String name = req.getParameter("name");
//获取一个参数的数组(复选框)
String[] hobby = req.getParameterValues("hobby");
//获取一个参数的map集合
Map<String, String[]> maps = req.getParameterMap();
for (String key : maps.keySet()) {
String[] value = maps.get(key);
System.out.println(key+"  "+Arrays.toString(value));
}
System.out.println(Arrays.toString(hobby));
System.out.println(name);
}
30.5 Servlet的生命周期:(*****)	237
这个是重点,一般面试时会问,  默认情况下servlet是在用户第一次请求的时候,服务器创建的一个servlet实例,然后servlet中的init方法就会执行,任何一次请求都会创建一个新的线程去访问servlet方法中的service的方法,在service方法内部会根据请求的方式不同调用不同的doXXX的方法,(例如get方式就是doGet()post方法就是doPost(方法))当服务器关闭或者项目被充服务器移除掉之后servlet实例就会被销毁,那么destory方法就会执行.   这就是servlet的生命周期.
30.5.1【启动时创建Servlet】	237
在web.xml中在<servlet></servlet>标签中配置:
* <load-on-startup>2</load-on-startup>  --- 传入正整数,整数越小,被创建的优先级就越高.这句话要写在<servlet-class>标签的后面,不然会报错
30.5.2【url-pattern的配置】	237
url-pattern配置方式共有三种:
1.完全路径匹配	:以 / 开始	例如:	/ServletDemo4 , /aaa/ServletDemo5 , /aaa/bbb/ServletDemo6
2.目录匹配	:以 / 开始 需要以 * 结束.	例如: /* ,/aaa/* ,/aaa/bbb/*
3.扩展名匹配	:不能以 / 开始 以 * 开始的. 例如: *.do , *.action
***** 错误的写法	: /*.do
 
有如下的配置:
  <servlet>
    <servlet-name>ServletDemo4</servlet-name>
    <servlet-class>com.itheima.a_servlet.ServletDemo4</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo4</servlet-name>
    <url-pattern>/ServletDemo4</url-pattern>
  </servlet-mapping>
 
  <servlet>
    <servlet-name>ServletDemo5</servlet-name>
    <servlet-class>com.itheima.a_servlet.ServletDemo5</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo5</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
 
  <servlet>
    <servlet-name>ServletDemo6</servlet-name>
    <servlet-class>com.itheima.a_servlet.ServletDemo6</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo6</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
这里需要注意一下:路径如果有包含的关系的话,  完全路径匹配>目录匹配>扩展名匹配
30.6.2【使用ServletContext对象读取WEB项目下的文件】	246
* InputStream getResourceAsStream(String path); --- 根据提供路径读取文件返回一个文件的输入流.   path = “/WEB-INF/classes/db.properties” 这个是服务器路径不需要写项目名,WEB-INF这个路径是对浏览器屏蔽的!在里面写的文件浏览器是访问不到的,因为里面放着是关键的jar包等, 
* String getRealPath(String path); --- 返回一个路径的磁盘绝对路径.
得到了磁盘绝对路径后可以使用普通的文件输入流开始读取文件了
代码实现:
使用getResourceAsStream读取
/**
 * 使用ServletContext中的getResourceAsStream读取.
 * @throws FileNotFoundException
 * @throws IOException
 */
private void test2() throws FileNotFoundException, IOException {
// 获得ServletContext:
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String driverClass = properties.getProperty("driverClass");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driverClass);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
使用getRealPath读取文件:
/**
 * 使用ServletContext中的getRealPath读取.
 * @throws FileNotFoundException
 * @throws IOException
 */
private void test3() throws FileNotFoundException, IOException {
// 获得ServletContext:
ServletContext context = this.getServletContext();
String realPath = context.getRealPath("/WEB-INF/classes/db.properties");
// 获得该文件的磁盘绝对路径.
System.out.println(realPath);
InputStream is = new FileInputStream(realPath);
Properties properties = new Properties();
properties.load(is);
String driverClass = properties.getProperty("driverClass");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driverClass);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
30.6.3ServletContext的功能:	247
【功能一:读取全局初始化参数】
在web.xml配置全局初始化参数:
  <context-param>
  	<param-name>username</param-name>
  	<param-value>root</param-value>
  </context-param>
    <context-param>
  	<param-name>password</param-name>
  	<param-value>123</param-value>
  </context-param>
 
代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = this.getServletContext().getInitParameter("username");
String password = this.getServletContext().getInitParameter("password");
System.out.println(username+"    "+password);
Enumeration<String> e = this.getServletContext().getInitParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
String value = this.getServletContext().getInitParameter(name);
System.out.println(name+"    "+value);
}
}
【功能二:获得文件的MIME的类型】
* 获得文件的MIME的类型.
 
代码实现:
/**
 * 获得文件的MIME的类型
 */
private void test2() {
String type = this.getServletContext().getMimeType("1.html");
System.out.println(type);
}
【功能三:作为域对象存取数据】
范围:整个web项目.而且全局的对象.
创建:服务器启动的时候,服务器为每个web项目创建一个单独的ServletContext对象.
销毁:服务器关闭的时候销毁ServletContext.
【功能四:读取web项目下的文件】
30.6.5【Response的概述】	249
Ø Response:代表响应的对象.从服务器向浏览器输出内容.
【Response的常用的API】在api中查找HttpServletResponse
部分api
void setStatus(int sc)     设置状态码
ServletOutputStream    getOutputStream()  获得输出流
void    setHeader(String name,String value)   设置头信息
30.6.6中文文件的下载:	251
//首先在页面点击文件的时候传递过来文件名称
//由于中文会有乱码问题,servlet的request的缓冲区是ISO-8859-1编码,而现实的时候需要用到的是UTF-8编码,所以要将传过来的数据用iso-8859-1转成二进制字节,然后根据utf-8转成字符串,就可以得到中文了
//然后文件下载要设置两个头一个流
//setHead("Content-Type",文件类型);
//setHead("Content-Disposition","attachment;filename="+文件的非中文名);//这里的非中文名是根据不同的浏览器编码将文件名进行编码的(因为头信息是不能有中文的,所以这个地方要进行编码的)
//然后获得一个文件的输入流再获得文件的输出流

以下是代码实例:
Ø IE浏览器下载中文文件的时候采用的URL的编码.   URLEncoser
Ø Firefox浏览器下载中文文件的时候采用的是Base64的编码.  Base64
/**
 * 文件下载的Servlet
 */
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.接收参数
String filename = new String(request.getParameter("filename").getBytes("ISO-8859-1"),"UTF-8");
System.out.println(filename);
// 2.完成文件下载:
// 2.1设置Content-Type头
String type = this.getServletContext().getMimeType(filename);
response.setHeader("Content-Type", type);
// 2.3设置文件的InputStream.
String realPath = this.getServletContext().getRealPath("/download/"+filename);
// 根据浏览器的类型处理中文文件的乱码问题:
String agent = request.getHeader("User-Agent");
System.out.println(agent);
if(agent.contains("Firefox")){
filename = base64EncodeFileName(filename);
}else{
filename = URLEncoder.encode(filename,"UTF-8");
}
// 2.2设置Content-Disposition头
response.setHeader("Content-Disposition", "attachment;filename="+filename);
InputStream is = new FileInputStream(realPath);
// 获得response的输出流:
OutputStream os = response.getOutputStream();
int len = 0;
byte[] b = new byte[1024];
while((len = is.read(b))!= -1){
os.write(b, 0, len);
}
is.close();
}
public static String base64EncodeFileName(String fileName) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
return "=?UTF-8?B?"
+ new String(base64Encoder.encode(fileName
.getBytes("UTF-8"))) + "?=";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
 
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
 
}
30.6.7response输出响应内容的方法:	253
* 输出中文乱码的处理:
    * 字节流:
        * 设置浏览器默认打开的编码:
            * resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
        * 设置中文字节取出的时候编码.
            * “中文”.getBytes(“UTF-8”);
    * 字符流:
        * 设置浏览器打开的时候的编码
            * resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
        * 设置response的缓冲区的编码
            * response.setCharacterEncoding(“UTF-8”);
 
        ***** 简化的写法:response.setContentType(“text/html;charset=UTF-8”);
30.7.1【Request的API】	254
常用的api
功能一:获得客户机相关的信息
String getMethod()    获得请求方式
String getRequestURL()    获得请求路径  Ø URL获得是全路径,就是http://一直往后
StringBuffer getRequestURI()    获得请求路径Ø URI获得是从工程名往后的路径
String getRemoteAddr()    获得客户机相关信息
String getContextPath()    获得工程名
功能二:获得从页面中提交的参数:
String  getParameter(String name)
Map getParameterMap()
Enumeration getParameterNames()
String[] getParameterValues(String name)
功能三:作为域对象存取数据:
void removeAttribute(String name)
void setAttribute(String name,Object o)
Object getAttribute(String name)

30.7.2处理request接收参数的中文乱码的问题:	256
Ø POST的解决方案:
* POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-8859-1编码.
* 设置request的缓冲区的编码:
    * request.setCharacterEncoding(“UTF-8”);  --- 一定要在接收参数之前设置编码就OK.
代码:
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
Ø GET的解决方案:
* 1.修改tomcat的字符集的编码.(不推荐)
* 2.使用URLEncoder和URLDecoder进行编码和解码的操作.
* 3.使用String的构造方法: 
代码:
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
30.7.3Request作为域对象存取数据:	256
使用request对象存取数据:
setAttribute(String name,String value);
Object getAttribute(String name);
作用范围就是一次请求的范围.
创建和销毁:
    * 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象.
    * 销毁:当服务器对这次请求作出了响应之后.
30.7.4重定向和转发的区别:(redirect和forward的区别)	257
重定向是两次请求两次响应,转发是一次请求一次响应
重定向的地址栏会发生变化,转发的地址栏不变
重定向的路径要加上工程名,转发的路径不需要加工程名
重定向可以跳转到任意的网站,转发只能在服务器内部进行转发

实例:
重定向: 
    response.setStatus(302);
    response.setHeader("location","/工程名/路径");
    简写  request.sendRedirect("/工程名/路径");

转发:request.getRequestDispatcher("/路径").forword(request,response);
30.8 Cookie&Session	257
Cookie :将数据保存到客户端端浏览器
Ø 向浏览器保存数据:
HttpServletResponse有一个方法:
* void addCookie(Cookie cookie);
Ø 获得浏览器带过来的Cookie:
HttpServletRequest有一个方法:
* Cookie[] getCookies();
Ø 创建一个Cookie对象:
* Cookie(String name,String value);
Session :将数据保存到服务器端
30.8.2Cookie的常用API:	260
*getName();
*getValue();
*setDomain(String domain); --设置Cookie有效域名
*setpath(String path);  --设置Cookie的有效路径  设置后只有匹配的路径才能传过去cookie
*setMaxAge(int maxAge);  --设置Cookie的有效时间.

Cookie的分类:
会话级别的Cookie:默认的cookie 关闭浏览器Cookie就会销毁.
持久级别的cookie:可以设置Cookie的有效时间,那么关闭浏览器Cookie还会存在.手动销毁持久性Cookie, setMaxAge(0)--前提是路径必须一致
    销毁步骤:1创建一个和原来cookie名字一样的cookie
                   2设置cookie与原来cookie一致的有效路径
                    3设置cookie的有效时间为0
                    4回写到浏览器.

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马