zoukankan      html  css  js  c++  java
  • javaWeb中 servlet 、request 、response

    1.Servlet

    (1)Servlet是JavaEE的一个动态web资源开发技 术,就是在服务器上运行的小程序,这个小程序是由服务器调用的,服务器为了能调用这个小程序,就要求这样的程序必须实现一个Servlet接口或去继承 Servlet的实现类GenericServlet或HttpServlet、

    (2)在web应用的配置文件web.xml中配置Servlet的对外访问路径,再将整个web应用交给虚拟机管理。

    (3)Servlet的调用过程:

    ①服务器根据请求的包的host找到要访问的虚拟主机

    ②在请求包中需求的web应用资源找到对应的web应用,根据请求资源去查询web.xml 中的 url-pattern 找到对应的Servlet名字,再根据这个名字找到对应的Servlet-Class

    ③服务器调用这个Servlet-Class传递reqeust和response到该类中运行

    ④Servlet类将处理好的信息用response写入缓存中,再给服务器返回,最后交给浏览器

    (4)Servlet的生命周期:从第一次被调用开始就由服务器创建出来,在创建出来后立即调用init方法初始化,直到web应用被虚拟主机移除或者服务器停掉,Servlet才会被销毁,

    (5)Servlet的继承结构:

    Servlet接口:所有Servlet必须实现的接口
      |
       ——GenericServlet:对Servlet接口的一个默认实现,其中包含的service方法为一个抽象方法,并且提供一些常用方法。
          |
           ——HttpServlet:专门增加了对HTTP请求的处理机制,实现了GenericServlet中的service方法,在此方法中会判断请求是以什么请求方式发送的,根据不同的请求方式会去调用响应的doXXX()方法,我们只需要继承HttpServlet,覆写其中的doGet()和doPost()方法就可以处理相应的GetPost请求了了。

    (6)web.xml中配置Servlet
    <web-app>
    //注册一个Servlet
      <servlet>

    //配置Servlet的名字

    <servlet-name>AnyName</servlet-name>

    //配置Servlet的对应类,注意,这里要的是一个类的全路径名,不要写成斜杠分割,也不要带.java或.class后缀名

    <servlet-class>HelloServlet</servlet-class>

    </servlet>

    //映射Servlet的对外访问路径
      <servlet-mapping>

    //配置映射的Servlet名

    <servlet-name>AnyName</servlet-name>

    //配置虚拟访问路径

    <url-pattern>/demo/hello.html</url-pattern>

    </servlet-mapping>
    </web-app>

    (7)web.xml额外功能标签
    ①<load-on-startup>用在<servlet>标签中,来表示服务器启动时就创建该类的实例,其中可以设置一个正整形值,表示启动的顺序
    ②一个servlet的对外访问路径被配置为/,则该Servlet就是一个缺省Servlet,其他Servlet不处理的事情就由缺省Servlet来处理。
    ③<init-param>元素,其中可以配置一些初始化信息,在Servlet里可以通过ServletConfig获得

    (8)线程安全问题

    ①类变量导致线程安全问题或者多个线程同时操作Servlet一会引起线程安全问题。
    ②解决办法,使用同步代码块嵌套可能造成线程安全问题的代码,不过会造成访问延迟和效率低下,避免使用类变量和减少线程阻塞时间和保证同步代码块代码尽量少。
    (9)Context域对象
    ①ServletContext代表整个应用,在整个web应用都能够被看见,利用ServletContext域可以在不同的Servlet之间传递信息。

    <context-param>
        <param-name>contextData1</param-name>
        <param-value>zzzzzz</param-value>
    </context-param>

    ②利用ServletContext获取资源:

    this.getServletContext().getResourceAsStream("虚拟路径");

    this.getSerlvetContext().getRealPath("虚拟路径");//返回资源的真实路径

    ③利用类加载器去获取资源

    loader.getResource("虚拟路径在classes路径算起").getPath();

    //获取资源的真实路径再创建流

     
    2、response
    (1)向浏览器输出一段数据

     //输出中文 没有乱码问题 底层是OutputStream输出
     PrintWriter print = new PrintWriter(response.getOutputStream(),true);
      print.println("happy!!!!!!!你们别玩了");
      
      //设置响应头的编码形式可以防止乱码

      response.setContentType("text/html;charset=utf-8");
      response.getWriter().write("你们别玩了")

    (2)实现文件下载

    //用URL编码防止中文乱码
      String path = URLEncoder.encode("成人脑力训练.zip", "utf-8");
      //设置消息头以附件的形式发布
      response.setHeader("Content-Disposition", "attachment;filename="+path);
      //用Context 流读取对应要下载的文件
      InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/成人脑力训练.zip");
      //关联输出流输出文件
      OutputStream out = response.getOutputStream();
      int len = 0;
      byte[] arr = new byte[1024];
      while ((len = in.read(arr)) != -1) {
       out.write(arr, 0, len);
      }
      in.close();

    (3)设置响应头refresh可以实现页面的定时刷新功能

     //html下 用<meta http-equiv= "" content="">可以模拟头功能
      //定时跳转,登陆成功跳转就用的这个功能
      //response.setHeader("Refresh", "3;url=/web/HelloWorld");

    (4)控制是否缓存资源

    //不缓存0或-1,用的是格林威治时间,用毫秒数表示
      response.setDateHeader("Expires", 0); 

    (5)实现请求重定向

    //重定向,代替了设置响应头的Location和设置状态302
      //response.sendRedirect("/web/HelloWorld");

    (6)验证码的制作

    //设置不缓存
      response.setDateHeader("Expires", 0);
      
      //设置验证码的宽和高
      int width = 150, height = width / 3;
      //获取一个画板并设置宽和高,以及显示的色泽通道
      BufferedImage img = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
      //获取画布
      Graphics2D g = (Graphics2D) img.getGraphics();
      //设置颜色画背景
      g.setColor(Color.WHITE);
      g.fillRect(0, 0, width, height);
      //设置颜色画边框
      g.setColor(Color.BLUE);
      g.drawRect(0, 0, width - 1, height - 1);
      
      //设置常见汉字字符的样本
      String base = "u7684u4e00u4e86u662fu6211u4e0du5728u4ebau4eecu6709u6765u4ed6u8fd9u4e0au7740u4e2au5730u5230u5927u91ccu8bf4u5c31u53bbu5b50u5f97u4e5fu548cu90a3u8981u4e0bu770bu5929u65f6u8fc7u51fau5c0fu4e48u8d77u4f60u90fdu628au597du8fd8u591au6ca1u4e3au53c8u53efu5bb6u5b66u53eau4ee5u4e3bu4f1au6837u5e74u60f3u751fu540cu8001u4e2du5341u4eceu81eau9762u524du5934u9053u5b83u540eu7136u8d70u5f88u50cfu89c1u4e24u7528u5979u56fdu52a8u8fdbu6210u56deu4ec0u8fb9u4f5cu5bf9u5f00u800cu5df1u4e9bu73b0u5c71u6c11u5019u7ecfu53d1u5de5u5411u4e8bu547du7ed9u957fu6c34u51e0u4e49u4e09u58f0u4e8eu9ad8u624bu77e5u7406u773cu5fd7u70b9u5fc3u6218u4e8cu95eeu4f46u8eabu65b9u5b9eu5403u505au53ebu5f53u4f4fu542cu9769u6253u5462u771fu5168u624du56dbu5df2u6240u654cu4e4bu6700u5149u4ea7u60c5u8defu5206u603bu6761u767du8bddu4e1cu5e2du6b21u4eb2u5982u88abu82b1u53e3u653eu513fu5e38u6c14u4e94u7b2cu4f7fu5199u519bu5427u6587u8fd0u518du679cu600eu5b9au8bb8u5febu660eu884cu56e0u522bu98deu5916u6811u7269u6d3bu90e8u95e8u65e0u5f80u8239u671bu65b0u5e26u961fu5148u529bu5b8cu5374u7ad9u4ee3u5458u673au66f4u4e5du60a8u6bcfu98ceu7ea7u8ddfu7b11u554au5b69u4e07u5c11u76f4u610fu591cu6bd4u9636u8fdeu8f66u91cdu4fbfu6597u9a6cu54eau5316u592au6307u53d8u793eu4f3cu58ebu8005u5e72u77f3u6ee1u65e5u51b3u767eu539fu62ffu7fa4u7a76u5404u516du672cu601du89e3u7acbu6cb3u6751u516bu96beu65e9u8bbau5417u6839u5171u8ba9u76f8u7814u4ecau5176u4e66u5750u63a5u5e94u5173u4fe1u89c9u6b65u53cdu5904u8bb0u5c06u5343u627eu4e89u9886u6216u5e08u7ed3u5757u8dd1u8c01u8349u8d8au5b57u52a0u811au7d27u7231u7b49u4e60u9635u6015u6708u9752u534au706bu6cd5u9898u5efau8d76u4f4du5531u6d77u4e03u5973u4efbu4ef6u611fu51c6u5f20u56e2u5c4bu79bbu8272u8138u7247u79d1u5012u775bu5229u4e16u521au4e14u7531u9001u5207u661fu5bfcu665au8868u591fu6574u8ba4u54cdu96eau6d41u672au573au8be5u5e76u5e95u6df1u523bu5e73u4f1fu5fd9u63d0u786eu8fd1u4eaeu8f7bu8bb2u519cu53e4u9ed1u544au754cu62c9u540du5440u571fu6e05u9633u7167u529eu53f2u6539u5386u8f6cu753bu9020u5634u6b64u6cbbu5317u5fc5u670du96e8u7a7fu5185u8bc6u9a8cu4f20u4e1au83dcu722cu7761u5174u5f62u91cfu54b1u89c2u82e6u4f53u4f17u901au51b2u5408u7834u53cbu5ea6u672fu996du516cu65c1u623fu6781u5357u67aau8bfbu6c99u5c81u7ebfu91ceu575au7a7au6536u7b97u81f3u653fu57ceu52b3u843du94b1u7279u56f4u5f1fu80dcu6559u70edu5c55u5305u6b4cu7c7bu6e10u5f3au6570u4e61u547cu6027u97f3u7b54u54e5u9645u65e7u795eu5ea7u7ae0u5e2eu5566u53d7u7cfbu4ee4u8df3u975eu4f55u725bu53d6u5165u5cb8u6562u6389u5ffdu79cdu88c5u9876u6025u6797u505cu606fu53e5u533au8863u822cu62a5u53f6u538bu6162u53d4u80ccu7ec6";
      
      //设置颜色并画干扰线
      g.setColor(Color.BLACK);
      for (int x = 0; x < 10; x++) {
        g.drawLine(getNum(0, width), getNum(0, height), getNum(0, width),
          getNum(0, height));
      }
      
      //设置字体格式并把字体写入画布
      g.setFont(new Font("微软雅黑", Font.BOLD, 20));  for(int x=0; x<4; x++)  {     //获取弧度 ,弧度=角度*PI/180    double d = getNum(-30, 30)*Math.PI/180;    //旋转一定弧度并把字体写在相应的坐标    g.rotate(d, 20+x*30, 30);    g.drawString(base.charAt(getNum(0, base.length()-1))+"", 20+x*30, 30);    g.rotate(-d, 20+x*30, 30);  }    //以jpg格式输出到浏览器中  ImageIO.write(img, "jpg", response.getOutputStream());

    (7)字节流和字符流是互斥的
     
    3、request
    (1)获取request中的各种信息

    OutputStream out = response.getOutputStream();
      response.setContentType("text/html;charset=gb2312");
      
      //获取请求头的请求资源地址 主机地址 和端口
      StringBuffer url = request.getRequestURL();
      String uri = request.getRequestURI();
      String addr = request.getRemoteAddr();
      String host = request.getRemoteHost();
      int port = request.getRemotePort();
      String user = request.getRemoteUser();
      
      out.write((uri+"-->"+url+"-->"+addr+"-->"+host+":"+port+"-->"+user).getBytes());
      
      //获取请求头的方法,长度,类型,和编码形式
      String method = request.getMethod();
      int len = request.getContentLength();
      String type = request.getContentType();
      String path = request.getContextPath();
      String encoding = request.getCharacterEncoding();
      
      out.write("<hr/>".getBytes());
      out.write((method+"-->"+len+"-->"+type+"-->"+path+":"+encoding).getBytes());
      
      //获取请求头的名字和值
      Enumeration<String> e = request.getHeaderNames();
       while((e.hasMoreElements()))   {    String name =  e.nextElement();    String value = request.getHeader(name);    out.write("<hr/>".getBytes());    out.write((name+":"+value).getBytes());   }

    (2)referer防盗链
    
    

      //获取来路的值
      String referer = request.getHeader("Referer");
      //拿来路匹配前面的域名。如果匹配就转发,不匹配就重定向到本域名的首页
      if(referer==null || !referer.startsWith("http://localhost"))
      {
        response.sendRedirect("/web/index.jsp");
      }
      else
        request.getRequestDispatcher("/WEB-INF/miji.html").forward(request, response);

    
    
    (3)处理中文乱码
    
    

       //解决乱码,通用的方法。
       String name = request.getParameter("name");
       name = new String(name.getBytes("ISO8859-1"),"utf-8");

     

      //解决乱码,post的特有方法。
      request.setCharacterEncoding("utf-8");

    (4)request域对象和转发

       //将参数带去其他的servlet,但是流要注意用。不能使用2种流
       request.setAttribute("test", "wow!!");
       request.getRequestDispatcher("/f").forward(request, response);

    (5)include

       //上面的直接转发会导致流被清空然后输出不了数据,
       //使用include可以输出本面页的信息以及要转发的面页信息,可以用组装面页
       request.getRequestDispatcher("/f").include(request, response);

    (6)重定向和转发的区别
    ①重定向:会改变浏览器的地址,2次请求和响应
    ②转发:不会改变浏览器的地址,一次请求和响应
    
    
    (7)缓存区的研究

      OutputStream out = response.getOutputStream();
      
      byte[] arr = new byte[8192];
      
      //缓存区满了会出现 chunked块发送
      //满了后会以16进制数字标识块数据的大小,以0加空内容结束
      out.write(arr);
      
      int size = response.getBufferSize();
      
      out.write(("<hr/>缓冲区满了吗?"+response.isCommitted()+"->缓存区大小:"+size).getBytes());

  • 相关阅读:
    在Windows上搭建Git Server
    Windows环境下Zookeeper 的安装与配置
    错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
    windows环境搭建dubbo服务
    gunicorn 使用
    jQuery 插件autocomplete 应用
    PHP str_replace() 函数详解
    jQuery的deferred对象详解
    Elasticsearch tp5使用
    MySQL explain详解
  • 原文地址:https://www.cnblogs.com/MrzhangKk/p/5334306.html
Copyright © 2011-2022 走看看