zoukankan      html  css  js  c++  java
  • JavaWeb之Servlet总结

    今天上班居然迟到了,昨天失眠了,看完吐槽大会实在不知道做些什么,刚好朋友给我发了两个JavaWeb的练习项目,自己就又研究了下,三四点才睡,可能周日白天睡的太多了,早上醒来已经九点多了,立马刷牙洗脸头都没洗打车到公司,到公司都十点半了,还好领导不错没有追究,谢谢老板谢谢陈工和同事们。下面开始今天正题。

    上一篇博客介绍了Tomcat的工作流程以及Servlet的生命周期,偏重理论,今天这一篇博客介绍下Servlet的应用,偏重实验,由于内容比较多,打算每天在家写一点,争取这周把这一篇完成。

    一、编写第一个Servlet

    学习任何一门语言都是从HelloWorld开始,今天学习Servlet也是从HelloWorld开始。打开Eclipse,File->New->Dyanmic Web Project新建一个名为HelloWorld的项目。在src下新建一个Package,这里我命名为test。在包下新建一个命名为HelloWorld的Servlet.如下图,左图是新建右图是新建完成的目录结构。

    在Servlet中写入几行简单的程序,来运行一下整体感知一下。

    package com.test.cyw;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    
    @WebServlet("/HelloWorld")
    public class HelloWorld extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
             try 
             {
                 out.println("<html>");
                 out.println("<head>");
                 out.println("<title>HelloWorld</title>");
                 out.println("</head>");
                 out.println("<body>");
                 out.println("<h2>HelloWorld</h2>");
                 out.println("</body>");
                 out.println("</html>");
                 
             } 
             finally 
             {
                 out.close();
                 
             }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
        }
    }
    View Code

    在浏览器中输入:http://localhost:8088/HelloWorld/HelloWorld,会显示下面的页面。

    二、@WebServlet注解

    假如输入小写的http://localhost:8088/HelloWorld/helloWorld,会出现错误的页面,如下图,这里可能会有疑问:为什么输入大写的就显示正常而输入小写的就报错呢?而且也没有和上一篇博客写的在web.xml中配置ServletName等这些参数也能运行。这是什么原因呢?

    其实这主要是@WebServlet注解在起作用。Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述,简化开发流程。开发Servlet3的程序需要一定的环境支持。Servlet3是Java EE6规范的一部分,MyEclipse10和Tomcat7都提供了对Java EE6规范的支持。Tomcat需要Tomcat7才支持Java EE6,Tomcat7需要使用JDK6。关于注解以后有机会会专门写一博客来研究它,这里主要是@WebServlet注解的使用。

    使用@WebServlet将一个继承于javax.servlet.http.HttpServlet的类定义为Servlet组件。
    @WebServlet有很多的属性:
      asyncSupported:声明Servlet是否支持异步操作模式。
      description:    Servlet的描述。
      displayName:     Servlet的显示名称。
      initParams:        Servlet的init参数。
        name:        Servlet的名称。
      urlPatterns:    Servlet的访问URL。
      value:          Servlet的访问URL。
      Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。

    这里我们对上面的代码稍作修改就可以实现大小写都支持。

    package com.test.cyw;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    
    /*@WebServlet("/HelloWorld")*/
    @WebServlet(name = "HelloWorld", urlPatterns = {"/helloWorld","/HelloWorld"})
    public class HelloWorld extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
             try 
             {
                 out.println("<html>");
                 out.println("<head>");
                 out.println("<title>HelloWorld</title>");
                 out.println("</head>");
                 out.println("<body>");
                 out.println("<h2>HelloWorld</h2>");
                 out.println("</body>");
                 out.println("</html>");
                 
             } 
             finally 
             {
                 out.close();
                 
             }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
        }
    }
    View Code

    三、参数配置

    1.Servlet的参数配置

    上面使用@WebServlet注解来实现映射,不过要Servlet3.0以后才支持,在web.xml中配置是一比较常见的方式。还是以HelloWrold项目为demo,在web.xml中进行如下配置,也能达到@WebServlet注解的效果。配置在xml中的参数修改只需要重启下服务器就好,不用再修改Servlet类.

      <servlet>
          <servlet-name>HelloWorld</servlet-name>
          <servlet-class>com.test.cyw.HelloWorld</servlet-class>
          <init-param>
              <param-name>encoding</param-name>
              <param-value>UTF-8</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>HelloWorld</servlet-name>
          <url-pattern>/helloWorld</url-pattern>
          <url-pattern>/helloWorld.aspx</url-pattern>
      </servlet-mapping>
    View Code

    <servlet></servlet>是Servlet配置的开始和结束标记。

    <servlet-name>指定一个变量,主要是为了配置<servlet-mapping>时使用。

    <servlet-class>指定Servlet对应的类。

    <init-param></init-param>配置初始化参数开始结束标记。

    <param-name>参数名,主要是为以后获取提供name

    <param-value>参数值,设置初始化参数的值

    <servlet-mapping></servlet-mapping>Servlet映射关系配置开始结束标记,用户输入的url怎么找到对应的Servlet-Class就要靠它。

    <servlet-name>HelloWorld</servlet-name>与上面<Servlet>配置的<servlet-name>一致。

    <url-pattern>用户输入的url格式,可以使用通配符*或?。从javaee5开始可以配置多个,上面的代码中添加了一个后缀名为aspx的,这样也可以映射。

    2.上下文的参数配置

    由于<init-param>是用配置在Servlet的参数,只能供对应的一个Servlet使用。要想配置的参数是全局的可以供所有的Servlet使用,可以使用上下文参数。例如像控制用户上传图片的类型,只允许用户上传jpg或png类型的图片。可以在web.xml中做下面的配置。

      <context-param>
          <param-name>ImageType</param-name>
          <param-value>.jpg,.png</param-value>
      </context-param> 
    View Code

    四、请求与响应

    在编程中请求与响应很常见,不仅仅是JavaWeb,其他语言也都有。先不说JavaWeb的请求响应,先从字面理解下。

    请求:谁请求谁?客户端发起请求,客户端请求服务端。

    响应:谁响应谁? 服务端做出响应,服务端响应客户端的请求。服务端是属于被动的。

    一般是用户发起请求,服务端根据请求做出响应,发起是用户的操作,编程一般不关心,根据请求做出对应的响应是编程需要做的。在Toamcat接到请求后,servlet 容器创建 HttpServletRequest、HttpServletResponse对象,并将该对象作为参数传递给该 servlet 的 service 方法.具体使用由于内容比较多这里就不一一列举,可以下载api查看,在本博客中我也会附上链接,供大家下载。

    五、web.xml参数读取

    上面配置了一些初始化的参数,配置参数就是为了读取使用,如果不提供读取的方法,配置参数基本没啥用。

    1.Servlet参数读取

    获取Servlet初始化参数有两种方法。一是直接调用Servlet的getInitParameter("name")二是通过getServletConfig()获取ServletConfig再使用getInitParameter("name")方法获取

    2.上下文参数读取

    获取全局上下文参数可以先通过getServletContext()获取ServletContext对象,再使用getInitParameter("name")方法获取。

    3.资源注射

    上面的获取参数都是需要在Servlet中调用方法获取参数,有没有不编写程序获取的呢?答案是有。不然我也不会问这个。JavaEE5提供了一个解决方案叫做资源注射@Resource.不过只能配置java.lang包下的标准类型的数据。

    下面的web.xml中分别配置Servlet初始化参数、全局上下文参数和注射参数。在Servlet中获取这些参数显示出来。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>HelloWorld</display-name>
      <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-name>HelloWorld</servlet-name>
          <servlet-class>com.test.cyw.HelloWorld</servlet-class>
          <init-param>
              <param-name>encoding</param-name>
              <param-value>UTF-8</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>HelloWorld</servlet-name>
          <url-pattern>/helloWorld</url-pattern>
          <url-pattern>/helloWorld.aspx</url-pattern>
      </servlet-mapping>
      <env-entry>
          <env-entry-name>resourceStringA</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
          <env-entry-value>hello,resourceStringA</env-entry-value>
      </env-entry>
        <env-entry>
          <env-entry-name>resourceStringB</env-entry-name>
          <env-entry-type>java.lang.String</env-entry-type>
          <env-entry-value>hello,resourceStringB</env-entry-value>
      </env-entry>
      <context-param>
          <param-name>ImageType</param-name>
          <param-value>.jpg,.png</param-value>
      </context-param> 
    </web-app>
    View Code
    package com.test.cyw;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.annotation.*;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    
    /*@WebServlet("/HelloWorld")*/
    /*@WebServlet(name = "HelloWorld", urlPatterns = {"/helloWorld","/HelloWorld"})*/
    public class HelloWorld extends HttpServlet {
    
        private @Resource(name="resourceStringA") String resourceString1;
        private @Resource(name="resourceStringB") 
        String resourceString2;
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
             try 
             {
                 //直接获取
                String servletParam=this.getInitParameter("encoding");
                 //通过ServletConfig对象获取
                //servletParam=this.getServletConfig().getInitParameter("encoding");
                 //通过获取ServletContext对象获取
                 String contextParam=this.getServletContext().getInitParameter("ImageType");
                 out.println("<html>");
                 out.println("<head>");
                 out.println("<title>HelloWorld</title>");
                 out.println("</head>");
                 out.println("<body>");
                 out.println("<h2>HelloWorld</h2>");
                 out.println("<h2>ServletParam:"+servletParam+"</h2>");
                 out.println("<h2>ContextParam:"+contextParam+"</h2>");
                 out.println("<h2>ResourceString1:"+resourceString1+"</h2>");
                 out.println("<h2>ResourceString2:"+resourceString2+"</h2>");
                 out.println("</body>");
                 out.println("</html>");
                 
             } 
             finally 
             {
                 out.close();
                 
             }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
        }
    }
    View Code

    六、Servlet生命周期

    关于生命周期上一博客也写的比较清楚,这里主要介绍下@PreDestroy和@PostConstruct。

    JavaEE5增加了两个影响生命周期的注解:@PreDestroy和@PostConstruct。被用来修饰非静态void()类型的不能抛出异常声明的方法。

        public @PostConstruct void PostConstruct()
        {
            System.out.println("构造函数后ini前");
        }
        @PreDestroy
        public  void PreDestory()
        {
            System.out.println("destory后Servlet卸载前");
        }
    View Code

    七、Servlet间跳转

    1.转向

    在WebContent目录下新建一个test.jsp文件,在HelloWorld的Servlet中放入下面的代码,会跳转到test.jsp页面。

            RequestDispatcher dispatcher= request.getRequestDispatcher("/test.jsp");
            dispatcher.forward(request, response);
    View Code

    2.重定向

    转向是通过request来实现的,那重定向是通过response来实现。

            response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
            response.setHeader("Location", "http://www.cnblogs.com/5ishare/");
    View Code

    3.自动刷新

    response.setHeader("Refresh", "2000;URL=http://www.cnblogs.com/5ishare/");
    View Code

    八、Servlet线程安全

    关于线程安全想必大家都练习过这样一个多线程取钱的练习。多线程操作一个变量会导致数据异常,最好不要在Servlet中声明全局变量。

    九、遇到的问题

    1.端口号问题

    在创建完Servelt运行时不管是大写的HelloWorld还是小写的helloWorld,始终报错,这个仔细检查才发现是端口错误,由于自己在公司配置的环境Tomcat端口是8080,自己也习惯了直接输的也是8080,导致出错,自己查看了下本机Tomcat的端口号发现是8088,改过来之后能运行成功。

     

  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/5ishare/p/6545396.html
Copyright © 2011-2022 走看看