Web学习笔记1

1. tomcat部署项目的三种方式

  • 直接把项目放到tomcat下的webapps目录下即可(可以把项目打成war包,然后放入到webapp下,tomcat服务器会自动解压war包。如果项目过大的话,这种方式会节省拷贝的时间)。
  • 配置conf目录下的service.xml中的< host>标签体,在标签体中添加< Context docBase=’‘本地路径’’ path=’'虚拟路径" />即可,其中docBase为项目在本地的路径,path为浏览器上访问的虚拟路径。
  • 在 \conf\Catalina\localhost 目录下创建任意名称的xml配置文件,在文件中配置< Context docBase="本地地址’’ />,其中docBase属性为项目的本地路径,而创建的文件名为浏览器访问的虚拟路径名。

2. Servlet

概念: server applet,运行在服务器端的小程序

Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则

在这里插入图片描述

2.1 Servlet的方法
public class Servlet_Methods implements Servlet {
    /**
     * 初始化方法
     *在Servlet被创建时执行,只会执行一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    /**
     * 获取ServletConfig对象
     * ServletConfig:Servlet的配置对象
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 提供服务方法
     * 每一次Servlet被访问,都会执行。执行多次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service");
    }

    /**
     * 获取Servlet的一些信息,版本、作者等
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法
     * 每次服务器被正常关闭时执行,执行一次
     */
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}
2.2 Servlet的生命周期
  • 默认情况下,Servlet在第一次被访问时创建
  • 指定Servlet的创建时间
    • 第一次访问时,创建的值为负数
    • 在服务器启动时,创建的值为0或正整数

Servlet的init方法,只执行一次,说明一个Servlet的内存中只存在一个对象,即Servlet是单例的
多个用户同时访问时,可能存在线程安全问题
解决方法:尽量不要在Servlet中定义成员变量

2.3 Servlet注解配置
  • Servlet3.0版本以上,可以不创建web.xml
  • 可以通过在类上使用@WebServlet(“资源路径”)注解,进行配置
@WebServlet(urlPatterns = "/Servlet_Demo2")
public class Servlet_Demo2 implements Servlet {
...
  • 如果只需要对某个url作出响应,则可以省略urlPatterns名称
@WebServlet("/Servlet_Demo2")
public class Servlet_Demo2 implements Servlet {
...
...
  • 如果是响应多个 url, 用大括号包起来即可
2.4 Servlet_体系结构
  • GenericServlet: 将Servlet接口中其他方法做了默认空实现,只将service()方法作为抽象,故将来定义Servlet类时,即可继承GenericServlet类,这样就只用实现service()方法了

  • HttpServlet: 对http协议的一种封装,可以简化操作

    • 相应流程
      在这里插入图片描述

    其中HttpServlet首先必须读取Http请求的内容,Servlet容器负责创建HttpServlet对象,并把Http请求直接封装到HttpServlet对象中。

    • 创建HttpServlet步骤
      • 继承HttpServlet抽象类
      • 重写HttpServlet的部分方法,如doGet()或doPost()方法

3. HTTP

3.1 HTTP请求信息

请求信息数据格式:

  • 请求行
    • 请求方式 请求url 请求协议/版本
    • 请求方式:
      • HTTP协议有7种请求方式,常用两种
      • GET:请求参数在请求行中,在url后,请求的url长度有限制
      • POST:请求参数在请求体中,请求的url长度没有限制
  • 请求头:客户端浏览器告诉服务器一些信息
    • 请求头名称:请求头值
    • 常见的请求头:
      • User-Agent:浏览器告诉服务器,访问使用的浏览器版本信息(可以在服务器端获取该头的信息,解决浏览器的兼容性问题)
      • Referer:告诉服务器,当前请求从哪里来,可以防盗链和统计工作
  • 请求空行
    • 空行,用来分割POST请求的请求体和请求体的
  • 请求体(正文)
    • 封装POST请求信息的请求参数的
3.2 相应信息

相应信息:服务器端发送给客户端的数据

数据格式:

  • 相应行
    • 组成:协议/版本 响应状态码 状态码描述
    • 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
      • 状态码都是三位数字
      • 分类:
        • 1xx:服务器接收客户端信息,但是没有接收完成,等待一段时间后,发送1xx的状态码
        • 2xx:成功,代表:200
        • 3xx:重定向,代表:302(重定向),304(访问缓存)
        • 4xx:客户端错误,代表:404(请求路径没有对应的资源)、405(请求方式没有对应的doXxx方法)
        • 5xx:服务器端错误,代表:500(服务器内部出现异常)
  • 响应头
    • 格式:头名称:值
    • 常见的响应头:
      • Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
      • Content-disposition:服务器告诉客户端以什么格式打开响应体数据
  • 响应空行
    • 最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头;
  • 响应体
    • 传输的数据

4. Request

Request对象和Response对象的原理

  • request和response对象是由服务器创建的,我们来使用它
  • request对象是来获取请求信息的
  • response对象是用来设置相应信息的
4.1 Request功能

获取请求消息数据

  • 获取请求行数据

    • 举例: GET/tomcat-practice/demo1?name=123 HTTP/1.1
    • 方法:
      • 获取请求方式:GET,String getMethod()
      • 获取虚拟目录:/tomcat-practice,String getContextPath()
      • 获取Servlet路径:/demo1,String getServletPath()
      • 获取get方式的请求参数:name=123,String getQueryString()
      • 获取请求URI:/tomcat-practice/demo1,String getRequestURI()
      • 获取请求URL:http://localhost/tomcat-practice/demo1,StringBuffer getRequestURL()
        (URI:统一资源定位符 URL:统一资源标识符)
      • 获取协议及版本:HTTP/1.1,String getProtocol()
      • 获取客户机的IP地址:String getRemoteAddr()
  • 获取请求头数据

    • 方法:
      • String getHeader(String name):通过请求头的名称获取请求头的值
      • Enumeration< String> getHeaderNames():获取所有的请求头名称
@WebServlet("/RequestGetHeader")
public class RequestGetHeader extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取所有的请求头数据
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String header = request.getHeader(name);
            System.out.println(name + "--" + header);
        }
        System.out.println();
        // 获取单个请求头数据
        String header = request.getHeader("host");
        System.out.println(header);
    }
}
@WebServlet("/RequestDemo2")
public class RequestDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String referer = request.getHeader("referer");
        System.out.println(referer);  //http://localhost:8080/login.html

        //防盗链
        if(referer != null) {
            if(referer.contains("login.html")) {
                //正常访问
                System.out.println("OK");
            } else {
                System.out.println("你是猪头");
            }
        }
    }
}
  • 获取请求体数据
    • 请求体:只要POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
    • 步骤:
      • 获取流对象
        BufferedReader getReader():获取字符输入流,只能操作字符数据
        ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
4.2 Request_获取请求参数

获取请求参数通用方法

  • String getParameter(String name):根据参数名称获取参数值
  • String[] getParameterValues(String name):根据参数名称获取参数值的数据
  • Enumeration< String> getParameterNames():获取所有请求的参数名称
  • Map< String, String[]> getParameterMap():获取所有参数的map集合
@WebServlet("/GetRequestParameters")
public class GetRequestParameters extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // post 获取请求参数

        //根据参数名称获取
        String s = request.getParameter("username");
        System.out.println("post:" + s);
        //根据参数名称获取字符串数组
        String[] hobbies = request.getParameterValues("hobby");
        /*
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        */
        //获取所有参数的请求名称(只能获取参数的一个请求名称)
        Enumeration<String> parameterNames = request.getParameterNames();
        /*
        while (parameterNames.hasMoreElements()) {
            String s1 = parameterNames.nextElement();
            System.out.println(s1);
            String s2 = request.getParameter(s1);
            System.out.println(s2);
            System.out.println("-----------------------");
        }
        */
        //获取所有参数的Map集合(可以获取参数的所有请求名称)
        Map<String, String[]> map = request.getParameterMap();
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            String[] values = map.get(key);
            System.out.println(key);
            for (String value : values) {
                System.out.println(value);
            }
            System.out.println("-----------------");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // get 获取请求参数

        //根据参数名称获取
        /*
        String s = request.getParameter("username");
        System.out.println("get:" + s);
         */
        this.doPost(request, response);
    }
}

中文乱码情况

  • get方式:tomcat8已解决
  • post方式:因为Http请求传输时将url以ISO-8859-1编码,服务器收到字节流后默认会以ISO-8859-1编码来解码成字符流,故会造成中文乱码,需要在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”)
4.3 Request请求转发

请求转发: 一种在服务器内部的资源跳转方式

实现方法: 通过request对象获取请求转发器对象,再使用RequestDispatcher对象进行转发

@WebServlet("/ForwardRequest")
public class ForwardRequest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ForwardRequest被访问");
        /*
        RequestDispatcher requestDemo4 = request.getRequestDispatcher("/RequestDemo4");
        requestDemo4.forward(request, response);
        */
        request.getRequestDispatcher("RequestDemo4").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("RequestDemo4被访问了");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

特点:

  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器内部资源中
  • 转发只执行一次请求
4.4 Request共享数据(域对象)

域对象: 一个有作用范围的对象,可以在范围内共享数据

request域: 代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:

  • setAttribute(String name, Object obj):存储数据
  • getAttitude(String name):通过键获取值
  • removeAttribute(String name):通过键移除键值对
4.5 获取ServletContext

方法:
ServletContext getServletContext()

5. Response

功能:设置响应消息

  • 设置响应行
    • 格式:HTTP/1.1 200 ok
    • 设置状态码:setStatus(int sc)
  • 设置响应头:setHeader(String name, String value)
  • 设置响应体
    • 步骤
      • 获取输出流
      • 使用输出流将数据输出到客户端浏览器
5.1 重定向

重定向:资源跳转的方式

/*
重定向
访问responseDemo1资源会自动跳转到responseDemo2资源
 */
@WebServlet("/responseDemo1")
public class responseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo1");

        /*
        // 1. 设置状态码为302
        response.setStatus(302);
        // 2. 设置响应头location
        response.setHeader("location", "/responseDemo2");
        */

        // 简单的重定向方法(可以访问别的站点的资源)
        response.sendRedirect("https://www.bilibili.com/");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

重定向(redirect)的特点

  • 地址栏地址发生变化
  • 重定向可以访问其它站点(服务器)的资源
  • 是两次请求,不能使用request对象来共享数据

转发(forward)的特点:

  • 转发地址栏路径不变
  • 转发只能访问当前服务器下的资源
  • 转发是一次请求
5.2 路径的写法
1. 路径_相对路径
  • 通过相对路径不可以确定唯一资源
  • 不以/开头,以.开头的路径
  • 规则:需要找到当前资源和目标资源之间的相对位置关系
    • ./:当前目录
    • …/:后退一级目录
2. 路径_绝对路径
  • 通过绝对路径可以确定唯一资源
  • 以/开头的路径
  • 规则:
    • 给客户端浏览器使用:需要加虚拟目录
    • 给服务器使用:不需要加虚拟目录

虚拟目录建议使用request.getContextPath()动态获取

5.3 输出字符数据

步骤:

  • 获取字符输出流
  • 输出数据

注意: 乱码问题

@WebServlet("/OutPutChar")
public class OutPutChar extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 防止中文乱码方法
        // 1. 需要在获取流之前设置默认编码为浏览器使用的解码方式,例如
        //response.setCharacterEncoding("utf-8");

        // 2. 浏览器使用的解码方式不一定是utf-8,故需要告诉浏览器,服务器发送的信息体的编码方式,让服务器使用该编码方式解码
        //response.setHeader("content-type", "text/html;charset=utf-8");
        // 方法2的简单写法
        response.setContentType("text/html;charset=utf-8");

        // 获取字符输出流
        PrintWriter pw = response.getWriter();
        // 输出数据
        pw.write("你好,学习人");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
5.4 输出字节数据
@WebServlet("/OutPutByte")
public class OutPutByte extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        // 获取字节输出流
        ServletOutputStream sos = response.getOutputStream();
        // 输出数据
        sos.write("hello,打工人".getBytes("utf-8"));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

6. ServletContext

概念: 代表整个web应用,可以和程序的容器(服务器)来通信

功能:

  1. 获取MIME类型
  2. 域对象:共享数据
  3. 获取文件的真实(服务器)路径
6.1 获取该对象
  • 通过request对象获取,request.getServletContext();
  • 通过HttpServlet获取,this.getServletContext();
6.2 功能
1. 获取MIME类型

MIME类型: 在互联网通信过程中定义的一种文件数据类型

格式: 大类型/小类型
例:text/heml、image/jpeg

获取: String getMimeType(String file)

@WebServlet("/Demo1")
public class Demo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String fileName = "a.jpg";
        //获取a.jpg的MIME类型
        String mimeName = context.getMimeType(fileName);
        System.out.println(mimeName);  //image/jpeg
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
2. 域对象
  • setAttribute(String name, Object value)
  • getAttribute(String name)
  • removeAttribute(String name)

ServletContext对象范围:所有用户所有请求的数据

3. 获取文件服务器路径

方法:String getRealPath(String path)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值