servlet

来源:互联网 发布:域名注册空间商网站 编辑:程序博客网 时间:2024/06/05 11:22

servlet简介及功能

  • Servlet:server applet 运行在服务器端的小程序
    • 概念:
      • 定义了一个类被浏览器访问的规则。是一个接口。
      • 功能:
        • 接受请求
        • 处理请求
        • 作出响应
    • 快速入门:
      0.创建web项目
      1.定义一个Java类,实现Servlet接口
      2.重写所有未实现方法
      3.配置Servlet,在web.xml
<!-- 配置Servlet,为了配置Servlet的访问路径 -->              <servlet>                <servlet-name>demo1</servlet-name>                <servlet-class>cn.itcast.servlet.ServletDemo1</servlet-class>              </servlet>              <servlet-mapping>                <servlet-name>demo1</servlet-name>                <!-- 设置访问路径,以/开头  -->                <url-pattern>/demo</url-pattern>              </servlet-mapping>
    4.发布项目    5.访问/demo路径访问该Servlet    浏览器中:http://127.0.0.1:8080/项目名/web.xml中配置的虚拟路径名* 原理:    * 服务器通过反射的方式 创建Servlet对象,调用其方法* servlet生命周期:    * 被创建:默认情况下,Servlet第一次被访问时,被创建,调用init()方法。              只执行一次。Servlet是单例的。可能会存在线程安全问题,尽量不要定义成员变量。              可以配置Servlet的创建时机。在web.xml的<servlet>标签中配置<l                      <!-- 修改servlet的创建时机:                        * 负整数:默认值 -1,在第一次被访问时创建                        * 非负整数:在服务器启动时创建                            * 数字越小,优先级越高                    -->                    <load-on-startup>0</load-on-startup>    * 提供服务:每一次被访问时,会调用service()方法提供服务    * 被销毁:服务器关闭时,servlet被销毁。              服务器正常关闭是,在销毁Servlet之前,会调用destory()方法* ServletConfig对象:配置对象   ServletConfig是一个接口 在Servlet初始化的时候 有服务器创建其子类对象传递给 init()方法    * 功能        1.获取servlet初始化参数            *  String getInitParameter(String name)              *  Enumeration getInitParameterNames()      例子:    System.out.println(config.getInitParameter("src"));    System.out.println(config.getInitParameter("href"));    Enumeration<String> names = config.getInitParameterNames();    while (names.hasMoreElements()) {        String key = names.nextElement();        System.out.println(key);        System.out.println(config.getInitParameter(key));    }
                初始化参数可在 web.xml中配置<servlet>    <servlet-name>demo3</servlet-name>    <servlet-class>com.click369.servlet.ServletDemo3</servlet-class><!--配置一些初始话参数-->    <init-param>      <param-name>src</param-name>      <param-value>c://a.txt</param-value>    </init-param>    <init-param>      <param-name>href</param-name>      <param-value>d://a.txt</param-value>    </init-param>  </servlet>  <servlet-mapping>    <servlet-name>demo3</servlet-name>    <url-pattern>/demo3</url-pattern>  </servlet-mapping>
        2.获取ServletContext对象   因为 ServletContext对象是由服务器创建出来的 我们要获取其对象 得通过ServletConfig对象中的方法才能获取出来            * ServletContext getServletContext()          3.获取servlet配置的名称 就是在web.xml中给servlet起的名字            * String getServletName()      * Servlet中对应getServletConfig方法。要想使用该方法获取config对象。        则需要提升config对象的作用域。            1.声明成员变量ServletConfig             2.在init方法中赋值            3.在getServletConfig方法中获取* 创建方式:    1. 实现Servlet    2. 继承GenericServlet        1.适配器        2.对ServletConfig进行优化。提升config对象的作用域        3.实现了ServletConfig接口,简化对config对象的使用方式    3. 继承HttpServlet:对http协议的封装        * 重写doGet()和doPost()...方法      注意去掉super.doGet(); 和 super.doPost();* 自动创建Servlet    * 修改模板:        1 D:\MyEclipse\Common\plugins        2 搜索wizards        3.找到.jar 修改templemnts/Servlet.java
  • ServletContext:代表了整个web应用

    • 特点:

      • 由服务器创建
      • 单例
    • 功能:

      • 域对象:在域的范围内共享数据

        • 范围:整个web应用
        • 存储所有用户共享的数据

          • setAttribute():
          • getAttribute():
          • removeAttribute():
        • JavaWeb中四大域对象:

          • ServletContext:代表整个web应用
          • HttpSession:会话域
          • ServletRequest:请求域
          • PageContext:页面域
      • 获取文件mime类型:

        • getMimeType(文件名称):
      • 获取文件运行的真实路径:

        • 真实路径:指服务器路径
        • getRealPath():

          • 1.webRoot下:项目根目录下
          • 2.WEB-INF下: 项目根目录下/WEB-INF
          • 3.src下: 项目根目录下/WEB-INF/classes

          • *注意:如果getRealPath(“/”),获取的路径是项目的根目录

          //根目录
          ServletContext context = this.getServletContext();
          String rootpath = context.getRealPath(“/”);
          //System.out.println(rootpath);
          //1.webRoot
          String b = context.getRealPath(“/b.txt”);
          System.out.println(b);
          //2.WEB-INF
          String c = context.getRealPath(“/WEB-INF/c.txt”);
          System.out.println(c);
          //3.src
          String a = context.getRealPath(“/WEB-INF/classes/a.txt”);
          System.out.println(a);

          • ServletContext只能用于web环境。如果是非web环境,则使用ClassLoader来获取真实路径

            比如我web项目里有一个普通的java工具类 我想获取文件的真实路径 那我就用不了 ServletContext
            //1.获取该类对应的类加载器对象
            ClassLoader loader = this.getClass().getClassLoader();
            //2.获取文件运行的真实路径
            URL url = loader.getResource(“a.txt”);
            String path = url.getPath();
            //注意类加载器来获取路径也有局限性 只能获取src目录下的文件

请求对象和响应对象的原理:

request 和response 对象都是由服务器创建,管理,销毁.  由我们来使用.

继承体系结构:
ServletRequest(接口)<——–继承<——-HttpServletRequest(接口)<——–实现 org.apache.catalina.connector.RequestFacade@6049a827

ServletResponse(接口)<———继承— HttpServletResponse(接口)<————-实现——org.apache.catalina.connector.ResponseFacade@3bec9d4

response:设置响应消息

  设置响应行: HTTP/1.1   200   ok    setStatus(int code);设置响应状态码    重定向  302     特点:1.两次请求,两次响应             2.地址栏发生变化            3.不仅可以访问内部资源,也可访问外部资源          代码:    // 设置状态码 302 重定向    response.setStatus(302);    // 设置响应头 location    response.setHeader("location","http://127.0.0.1:8080/MyServlet/index.jsp");    // 以上两步可以合成一个简便方法    response.sendRedirect("http://www.baidu.com");              设置响应头: 例如:content-type:text/html;charset=utf-8    setHeader(String headName,String headValue); 设置响应头的名称和值    setDateHeader(String name,long date); 设置日期头    setIntHeader(String name,int count); 设置数字头设置响应体:响应体响应的是数据  得通过流的方式                获取输出流写出数据    **PrintWriter getWriter();发送字符数据的对象    // 为了防止乱码,我们设置一下服务器对字符流的编码 默认服务器用的是ISO-8859-1    // 所以在获取流之前告诉服务器用什么编码    response.setCharacterEncoding("utf-8");    //告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码    response.setHeader("content-type","text/html;charset=utf-8");    //以上两个方法可以合二为一    response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码    **ServletOutputStream getOutputStream(); 发送字节数据的对象      // 获取字节流 用流向浏览器写出一张图片    ServletOutputStream sos = response.getOutputStream();    // 获取图片的真实路径    String realPath = this.getServletContext().getRealPath("/302.png");    // 获取输入流读取图片    FileInputStream fis = new FileInputStream(new File(realPath));    byte[] by = new byte[1024];    int len = 0;    while ((len = fis.read(by)) != -1) {        sos.write(by, 0, len);    }    //第三方jar包可以进行一个流的对拷    IOUtils.copy(fis,sos);

小案例:验证码
int width = 100;
int height = 50;
//1.创建图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    //2.修饰图片    //2.1设置背景色    Graphics g = image.getGraphics();//获取画笔    g.setColor(Color.PINK);//设置颜色    g.fillRect(0, 0, width, height);//填充背景色    //2.2画边框    g.setColor(Color.BLUE);    g.drawRect(0, 0, width - 1, height - 1);    //2.3写入验证码    g.setColor(Color.RED);    /*    g.drawString("A", width/5 * 1, height/2);    g.drawString("C", width/5 * 2, height/2);    g.drawString("I", width/5 * 3, height/2);    g.drawString("D", width/5 * 4, height/2);    */    String msg = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789";    Random ran = new Random();    for (int i = 1; i <= 4; i++) {        int index = ran.nextInt(msg.length());//获取msg的随机角标        g.drawString(String.valueOf(msg.charAt(index)), width/5 * i, height/2);    }    //2.4画干扰线    g.setColor(Color.GREEN);    //g.drawLine(0, 0, width, height);    for (int i = 0; i < 5; i++) {        int x1 = ran.nextInt(width);        int x2 = ran.nextInt(width);        int y1 = ran.nextInt(height);        int y2 = ran.nextInt(height);        g.drawLine(x1, y1, x2, y2);    }    //3.将图片数据写入response输出流中    ImageIO.write(image, "jpg", response.getOutputStream());

request 对象

          获取请求消息1.获取请求行: GET     /MyServlet/index.jsp?name=zhangsan&age=23  HTTP/1.1        request.getMethod();//获取请求方式        request.getContextPath();//获取项目名称        request.getRequestURI();//获取URI        request.getRequestURL();//获取URL        request.getRemoteAddr();//获取IP地址        request.getQueryString();//获取请求参数        request.getProtocol();//获取协议版本2.获取请求头:        request.getHeader("user-agent");//获取请求头的值        request.getDateHeader(name);//获取日期头        request.getIntHeader(name)//获取数字头3.获取请求体: 请求体:专门用于封装Post请求的 请求参数    获取字符数据: getReader(); 返回一个高效的字符流 我们通过一次读取一行的 方法来获取请求参数数据  然后 拆分字符串获取我们想要的数据    获取字节数据:getInputStream(); 后期上传文件时讲解4. 通用的方式来获取 请求参数        request.getParameter(name);  通过请求参数的名称来获取值         request.getParameterValues("hobby"); 通过请求参数的名称,来获取值的数组 一般用于复选框        request.getParameterMap();  获取所有参数的map集合        request.getParameterNames(); 获取所有参数的名称 枚举 不常用 了解5. 处理中文乱码问题        //通用处理方式:处理get post 请求提交中文数据乱码问题        String username = request.getParameter("username");        byte[] bytes = username.getBytes("ISO-8859-1");//将字符串还原成字节 相当于解码        username=new String(bytes,"utf-8");//将字节重新编码        post 请求特有的方式 处理中文乱码            request.setCharacterEncoding("utf-8");6.请求转发:     转发的特点:        1.一次请求一次响应        2.地址栏不发生变化        3.只能访问内部站点资源    代码:        request.getRequestDispatcher("/myservlet2").forward(request, response);7.域对象: 请求域的范围中共享数据    在一次请求的多个资源之间共享数据            request.setAttribute("name","zhangsan");            request.getAttribute("name");            request.removeAttribute("name");    什么时候使用重定向?什么时候使用转发?        1.如果需要在请求的多个资源中共享数据,则使用转发        2.如一次性的数据存入请求域中8.路径的书写:     建议以/开头    服务器内部跳转路径 不需要加项目名称  request.getRequestDispatcher("/myservlet2").forward(request, response);    页面上的路径和重定向 需要加上 项目名称    <img src="/MyServlet/mydemo4" id="img1"></img>    一般来说我们写相对路径