zoukankan      html  css  js  c++  java
  • 15、Servlet

    servlet 是运行在 Web 服务器中的小型 Java 程序 ( 服务器端的小应用程序 ) 。servlet 通常通过 HTTP(超文本传输协议) 接收和响应来自 Web 客户端的请求

     三大作用

    1、获取表单数据

    2、处理业务逻辑

    3、分发转向

    注意
    修改了类名之后要在web.xml中修改一下servlet-name标签中的完整类名
    <url-pattern >/ servlet/demo4 </ url-pattern>:第一个/代表当前应用根目录
    每次修改完之后要重新运行服务器或者redeploy
    在Windows下复制的目录为反斜杠,正反都支持,但是需要转义,故一般使用正斜杠/
     

    一、编写一个servlet程序

    (1)写一个java类,实现servlet接口

    1 public class ServletTest implements Servlet{
    2     // 接收用户请求并作出相应
    3     public void service(ServletRequest req, ServletResponse res)
    4             throws ServletException, IOException {
    5         // TODO Auto-generated method stub
    6         res.getWriter().write("hello");
    7     }
    8 }

    (2)修改web.xml文件,给servlet提供一个可访问的URI地址

     1 <!-- 创建一个servlet实例 -->
     2 <servlet>
     3     <servlet-name>servletDemo</servlet-name>
     4     <servlet-class>cn.guojie.servlet.ServletTest</servlet-class>
     5 </servlet>
     6 
     7 <!-- 给servlet提供(映射)一个可访问的URI地址 -->
     8 <servlet-mapping>
     9     <servlet-name>servletDemo</servlet-name>
    10     <url-pattern>/demo1</url-pattern>
    11 </servlet-mapping>

    servletDemo:servlet的名字,自定义,和mapping中要相同

    url-pattern:/demo1代表测试的时候用的

    (3)部署应用到tomcat服务器

    (4)测试:http://locahost:8080/servlet/demo1 --> servlet-mapping标签中的/demo1,通过servlet名servletDemo  --> servlet标签中servletDemo的servlet名 -->cn.guojie.servlet.ServletTest相当于实例化cn.guojie.servlet.ServletTest类,类是服务器实例化的,service方法也是服务器调用的

     javax是javaEE的,以后不再是Swing的

    二、执行过程

    三、Servlet生命周期

    实例化(构造)-->初始化(init)-->服务(service,多线程)->销毁(destory)
    实例化-->初始化:第一次访问Servlet就出生(默认情况下)
    服务:应用活着,servlet就活着(每次访问都被调用)
    销毁:应用卸载了servlet就销毁
     
    deploy部署
    undeploy卸载
     
    让servlet在服务器启动时就创建
    1 <servlet>
    2         <servlet-name>servletDemo</servlet-name>
    3         <servlet-class>cn.guojie.servlet.ServletTest</servlet-class>
    4         <load-on-startup>2</load-on-startup>  <!-- 数值越高,优先级越高,不要写0,让servlet在服务器启动时就创建 -->
    5     </servlet>

    四、Servlet的三种创建方式

    1、实现javax.servlet.Servlet接口
    2、继承javax.servet.GenericServlet类(适配器模式)插座,实现多个接口,重写了多个方法
    3、继承javax.servlet.http.HttpServlet类(模板方法设计模式)(开发中常用方式)
     1 // 不要在重写父类的service方法
     2 @Override
     3 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     4         throws ServletException, IOException {
     5     System.out.println("doget");
     6 }
     7 
     8 @Override
     9 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    10         throws ServletException, IOException {
    11     System.out.println("dopost");
    12 }
    继承的HttpServlet中service方法,调用service方法判断是get还是post请求,之后再根据请求用doGet还是doPost方法处理
    右键创建servlet就是创建的HttpServlet的实现类。
     
    模板设计思想(多态)
    接口Servlet s = new ServletDemo();
    s.service()是调用ServletDemo的service方法,ServletDemo没有,则找其父亲HttpServlet的service方法,HttpServlet重写了service方法,里面doGet或是doPost判断是get还是post请求,而ServletDemo中重写了doPost和doGet方法,执行ServletDemo中的这两个方法,要是在ServletDemo中重写了doPost和doGet方法,模板设计模式就无效了,无法区分doGet或是doPost
     
    继承图
     HttpServlet (继承HttpServlet) --> GenericServlet --> Servlet (小到大)
     
    使生成的servlet更清新一些
    找到:MyEclipseCommonplugins目录
    把com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar复制到上面目录
     
    改了web.xml之后要在服务器中重新部署应用
     
    带三角的是继承过来的,不带的是自己的

     xml配置信息写错报错,检查配置文件是否写错

     

    servlet映射细节

    1、只要servlet-name相同,url-pattern不同也可以通过url-pattern中不同的地址访问同一servlet,多个映射路径
    2、通配符* 代表任意字符串
    url-pattern: *.do 以*.字符串的请求都可以访问 注:不要加/
    url-pattern: /* 任意字符串都可以访问
    url-pattern: /action/* 以/action开头的请求都可以访问
     
    匹配规则:
    优先级:从高到低
    绝对匹配> /开头匹配 >扩展名方式匹配
    如果url-pattern的值是/,表示执行默认映射。所有资源都是servlet
    在tomcat的conf配置文件中的web.xml中配置为/
    1 <servlet-mapping>
    2     <servlet-name>default</servlet-name>
    3     <url-pattern>/</url-pattern>
    4 </servlet-mapping>

    五、Servlet的线程安全

    单实例:每次访问多线程
    解决线程安全问题的最佳办法,不要写全局变量,而写局部变量(每次进去都是初始化为1,分页的时候有用)
    SingleThreadModel会每次访问一次建一个;用线程会造成线程不安全
     

    六、Servlet获取配置信息

    ServletConfig的使用

    作用一:可以获取servlet配置信息

    方式1:重写父类GenericServlet的init方法初始化
    1 // web.xml中的配置信息
    2 <servlet>
    3   <servlet-name>ServletConf</servlet-name>
    4   <servlet-class>cn.guojie.servletConf.ServletConf</servlet-class>
    5   <init-param>
    6       <param-name>encoding</param-name>
    7       <param-value>GBK</param-value>
    8   </init-param>
    9 </servlet>
     1 private ServletConfig config;
     2 
     3 // 重写父类GenericServlet的init方法初始化得到ServletConfig对象,此对象由服务器创建
     4 @Override
     5 public void init(ServletConfig config) throws ServletException {
     6     // TODO Auto-generated method stub
     7     this.config = config;
     8 }
     9 
    10 public void doGet(HttpServletRequest request, HttpServletResponse response)
    11         throws ServletException, IOException {
    12     String parameter = config.getInitParameter("encoding");  // 获取配置文件信息
    13     System.out.println(parameter);;
    14 }

    方式2:(常用)

    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     // 通过祖先Servlet的getServletConfig方法获得ServletConfig
    4     this.getServletConfig().getInitParameter("encoding");
    5 }
    方式3:
    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     // HttpServlet已经实现了ServletConfig接口
    4     String parameter = this.getInitParameter("encoding");
    5     System.out.println(parameter);
    6 }

    作用二:可以获得ServletContext对象

     

     七、ServletContext (重要

     ServletContext: 代表的是整个应用,一个应用只有一个ServletContext对象,单实例,服务器启动的时候创建,服务器关闭或者应用卸载时销毁
     

    作用:

    1、域对象
    在一定范围内(当前应用),使多个Servlet共享数据。
    ServletContext 维护一个map存储键值对
    常用方法:
    1 void setAttribute(String name,object value);  // 向ServletContext对象的map中添加数据
    2 Object getAttribute(String name);  // 从ServletContext对象的map中取数据
    3 void rmoveAttribute(String name);  // 根据name去移除数据
    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     // 调用GenericServlet的方法得到
    4     ServletContext application = this.getServletContext();
    5     // 向ServletContext对象的map中添加数据
    6     application.setAttribute("name", "guo");
    7     // 通过反射获取对象所属类名
    8     application.getClass().getName();
    9 }
    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     // 从ServletContext对象的map中取数据
    4      String name = (String) this.getServletContext().getAttribute("name");
    5      System.out.println(name);
    6 }
    2、获取全局配置信息
    修改web.xml文件:
    getInitParameter ( String name) //根据配置文件中的key得到value
    1 <context-param>
    2     <param-name>encoding</param-name>
    3     <param-value>UTF-8</param-value>
    4 </context-param>
    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     // 获取全局配置信息
    4     String encoding = this.getServletContext().getInitParameter("encoding");
    5     System.out.println(encoding);
    6 }
     3、获取资源路径
    String getRealPath(String path);  //根据资源名称得到资源的绝对路径.
    可以得到当前应用任何位置的任何资源(properties、xml...)
    ResourceBundle只能取到src目录下的class(myeclipse和服务器中相对应)
    不要忘了当前路径的/
    1 // 获取在web-info文件夹下的文件
    2 private void test1() throws IOException, FileNotFoundException {
    3     String realPath = this.getServletContext().getRealPath("/WEB-INF/a.properties");  // /是当前应用根目录,部署在服务器上,故目录要是服务器上的目录,而不是myeclipse的
    4     System.out.println(realPath);
    5     Properties p = new Properties();
    6     p.load(new FileInputStream(realPath));
    7     String value = p.getProperty("name");
    8     System.out.println(value);
    9 }
    1 // 获取src目录下的b.properties
    2 private void test2() throws IOException, FileNotFoundException {
    3     String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/b.properties");
    4     System.out.println(realPath);
    5     Properties p = new Properties();
    6     p.load(new FileInputStream(realPath));
    7     String value = p.getProperty("name");
    8     System.out.println(value);
    9 }
    1 // 获取包下面的b.properties
    2 private void test3() throws IOException, FileNotFoundException {
    3     String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/cn/guojie/servletContext/c.properties");
    4     System.out.println(realPath);
    5     Properties p = new Properties();
    6     p.load(new FileInputStream(realPath));
    7     String value = p.getProperty("name");
    8     System.out.println(value);
    9 }
    4、实现Servlet的转发
    RequestDispatcher getRequestDispatcher ( String path) ;//参数表示要跳转到哪去

    1 public void doGet(HttpServletRequest request, HttpServletResponse response)
    2         throws ServletException, IOException {
    3     
    4     ServletContext application = this.getServletContext();
    5     // 像下传递,将应用转发到/servlet/Demo6应用,在web.xml中可看到
    6     application.getRequestDispatcher("/servlet/demo5").forward(request, response);
    7 }
     

    八、Servlet相关对象

    Servlet                         接口javax.servlet.Servlet  
    GenericServlet              抽象类javax.servlet.GenericServlet    
    HttpServlet                  抽象类javax.servlet.http.HttpServlet   
    ServletConfig               接口javax.servlet.ServletConfig 
    ServletContext             接口javax.servlet.ServletContext     
    ServletRequest             接口javax.servlet.ServletRequest   
    ServletResponse           接口javax.servlet.ServletResponse     
    HttpServletRequest      接口javax.servlet.http.HttpServletRequest  
    HttpServletResponse    接口javax.servlet.http.HttpServletResponse  
     
    RequestDispatcher       接口javax.servlet.RequestDispatcher  
     
    UML
    如果是通过参数传过来的对象,就叫依赖
    通过方法得到的对象,就叫关联
     
     
     
    有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
  • 相关阅读:
    TP3.2框架,实现空模块、空控制器、空操作的页面404替换||同步实现apache报错404页面替换
    调用支付宝PHP接口API实现在线即时支付功能(UTF-8编码)
    JQuery实现的 checkbox 全选;<select>下拉框功能
    使用PHP做移动端 api接口开发方法(适用于TP框架)
    Eclipse jvm启动参数在哪设置
    对 META标签 的一点点了解
    Java反射在整个程序运行中的位置
    Java 为什么要使用反射(通俗易懂的举例)
    粗略介绍Java AQS的实现原理
    Java并发包中线程池的种类和特点介绍
  • 原文地址:https://www.cnblogs.com/1989guojie/p/6132460.html
Copyright © 2011-2022 走看看