<!DOCTYPE html>




  



<html class="theme-next pisces use-motion" lang="zh-Hans">

<head>

  <meta charset="UTF-8"/>

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>

<meta name="theme-color" content="#222">










<meta http-equiv="Cache-Control" content="no-transform" />

<meta http-equiv="Cache-Control" content="no-siteapp" />

















  

  

  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />








<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />


<link href="/css/main.css?v=5.1.3" rel="stylesheet" type="text/css" />



  <link rel="apple-touch-icon" sizes="180x180" href="/p_w_picpaths/apple-touch-icon-next.png?v=5.1.3">



  <link rel="icon" type="p_w_picpath/png" sizes="32x32" href="/p_w_picpaths/favicon-32x32-next.png?v=5.1.3">



  <link rel="icon" type="p_w_picpath/png" sizes="16x16" href="/p_w_picpaths/favicon-16x16-next.png?v=5.1.3">



  <link rel="mask-icon" href="/p_w_picpaths/logo.svg?v=5.1.3" color="#222">






  <meta name="keywords" content="java," />






  <link rel="alternate" href="/atom.xml" title="×××散尽13141" type="application/atom+xml" />







<meta name="description" content="个人剖析,不喜勿喷">

<meta name="keywords" content="java">

<meta property="og:type" content="article">

<meta property="og:title" content="深入理解struts的运行机制">

<meta property="og:url" content="https://zxhtom.oschina.io/2016/10/26/Java/深入理解struts的运行机制/index.html">

<meta property="og:site_name" content="×××散尽13141">

<meta property="og:description" content="个人剖析,不喜勿喷">

<meta property="og:locale" content="zh-Hans">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20161031125322526">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20161025200046888">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20161025200249781">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20161026185137212">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20161031125335637">

<meta property="og:p_w_picpath" content="https://img-blog.csdn.net/20170425212847159?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzEzMjA1MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">

<meta property="og:updated_time" content="2017-10-31T06:20:23.193Z">

<meta name="twitter:card" content="summary">

<meta name="twitter:title" content="深入理解struts的运行机制">

<meta name="twitter:description" content="个人剖析,不喜勿喷">

<meta name="twitter:p_w_picpath" content="https://img-blog.csdn.net/20161031125322526">




<script type="text/javascript" id="hexo.configurations">

  var NexT = window.NexT || {};

  var CONFIG = {

    root: '/',

    scheme: 'Pisces',

    version: '5.1.3',

    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},

    fancybox: true,

    tabs: true,

    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},

    duoshuo: {

      userId: '0',

      author: '博主'

    },

    algolia: {

      applicationID: '',

      apiKey: '',

      indexName: '',

      hits: {"per_page":10},

      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}

    }

  };

</script>




  <link rel="canonical" href="https://zxhtom.oschina.io/2016/10/26/Java/深入理解struts的运行机制/"/>





<script>

    (function(){

        if(''){

            if (prompt('请输入文章密码') !== ''){

                alert('密码错误!');

                history.back();

            }

        }

    })();

</script>

  <title>深入理解struts的运行机制 | ×××散尽13141</title>

  






  <script type="text/javascript">

    var _hmt = _hmt || [];

    (function() {

      var hm = document.createElement("script");

      hm.src = "https://hm.baidu.com/hm.js?709c2dde1f61f5e589ff3ed31ba52411";

      var s = document.getElementsByTagName("script")[0];

      s.parentNode.insertBefore(hm, s);

    })();

  </script>





</head>


<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">


  

  

    

  


  <div class="container sidebar-position-left page-post-detail">

    <div class="headband">

      <a href="https://github.com/zxhTom"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>

    </div>


    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">

      <div class="header-inner"><div class="site-brand-wrapper">

  <div class="site-meta ">

    


    <div class="custom-logo-site-title">

      <a href="/"  class="brand" rel="start">

        <span class="logo-line-before"><i></i></span>

        <span class="site-title">×××散尽13141</span>

        <span class="logo-line-after"><i></i></span>

      </a>

    </div>

      

        <p class="site-subtitle">慢慢的学习,慢慢的进步</p>

      

  </div>


  <div class="site-nav-toggle">

    <button>

      <span class="btn-bar"></span>

      <span class="btn-bar"></span>

      <span class="btn-bar"></span>

    </button>

  </div>

</div>


<nav class="site-nav">

  


  

    <ul id="menu" class="menu">

      

        

        <li class="menu-item menu-item-home">

          <a href="/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />

            

            首页

          </a>

        </li>

      

        

        <li class="menu-item menu-item-about">

          <a href="/about/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />

            

            关于

          </a>

        </li>

      

        

        <li class="menu-item menu-item-tags">

          <a href="/tags/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />

            

            标签

          </a>

        </li>

      

        

        <li class="menu-item menu-item-categories">

          <a href="/categories/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />

            

            分类

          </a>

        </li>

      

        

        <li class="menu-item menu-item-archives">

          <a href="/archives/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />

            

            归档

          </a>

        </li>

      

        

        <li class="menu-item menu-item-schedule">

          <a href="/schedule/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />

            

            日程表

          </a>

        </li>

      

        

        <li class="menu-item menu-item-sitemap">

          <a href="/sitemap.xml" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />

            

            站点地图

          </a>

        </li>

      

        

        <li class="menu-item menu-item-commonweal">

          <a href="/404/" rel="section">

            

              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />

            

            公益404

          </a>

        </li>

      


      

        <li class="menu-item menu-item-search">

          

            <a href="javascript:;" class="popup-trigger">

          

            

              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />

            

            搜索

          </a>

        </li>

      

    </ul>

  


  

    <div class="site-search">

      

  <div class="popup search-popup local-search-popup">

  <div class="local-search-header clearfix">

    <span class="search-icon">

      <i class="fa fa-search"></i>

    </span>

    <span class="popup-btn-close">

      <i class="fa fa-times-circle"></i>

    </span>

    <div class="local-search-input-wrapper">

      <input autocomplete="off"

             placeholder="搜索..." spellcheck="false"

             type="text" id="local-search-input">

    </div>

  </div>

  <div id="local-search-result"></div>

</div>




    </div>

  

</nav>




 </div>

    </header>


    <main id="main" class="main">

      <div class="main-inner">

        <div class="content-wrap">

          <div id="content" class="content">

            


  <div id="posts" class="posts-expand">

    


  


  

  

  


  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">

  

  

  

  <div class="post-block">

    <link itemprop="mainEntityOfPage" href="https://zxhtom.oschina.io/2016/10/26/Java/深入理解struts的运行机制/">


    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">

      <meta itemprop="name" content="张新华">

      <meta itemprop="description" content="">

      <meta itemprop="p_w_picpath" content="http://avatar.csdn.net/E/8/5/2_u013132051.jpg">

    </span>


    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">

      <meta itemprop="name" content="×××散尽13141">

    </span>


    

      <header class="post-header">


        

        

          <h1 class="post-title" itemprop="name headline">深入理解struts的运行机制</h1>

        


        <div class="post-meta">

          <span class="post-time">

            

              <span class="post-meta-item-icon">

                <i class="fa fa-calendar-o"></i>

              </span>

              

                <span class="post-meta-item-text">发表于</span>

              

              <time title="创建于" itemprop="dateCreated datePublished" datetime="2016-10-26T20:02:00+08:00">

                2016-10-26

              </time>

            


            


            

          </span>


          

            <span class="post-category" >

            

              <span class="post-meta-divider">|</span>

            

              <span class="post-meta-item-icon">

                <i class="fa fa-folder-o"></i>

              </span>

              

                <span class="post-meta-item-text">分类于</span>

              

              

                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">

                  <a href="/categories/编程/" itemprop="url" rel="index">

                    <span itemprop="name">编程</span>

                  </a>

                </span>


                

                

              

            </span>

          


          

            

              <span class="post-comments-count">

              <span class="post-meta-divider">|</span>

              <span class="post-meta-item-icon">

                <i class="fa fa-comment-o"></i>

              </span>

              

                <a href="/2016/10/26/Java/深入理解struts的运行机制/#SOHUCS" itemprop="discussionUrl">

                  <span id="changyan_count_unit" class="post-comments-count hc-comment-count" data-xid="2016/10/26/Java/深入理解struts的运行机制/" itemprop="commentsCount"></span>

                </a>

              

            

          


          

          


          

            <span class="post-meta-divider">|</span>

            <span class="page-pv"><i class="fa fa-file-o">本文总阅读量</i>

            <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>次

            </span>

          


          

            <div class="post-wordcount">

              

                

                <span class="post-meta-item-icon">

                  <i class="fa fa-file-word-o"></i>

                </span>

                

                  <span class="post-meta-item-text">字数统计&#58;</span>

                

                <span title="字数统计">

                  2,898

                </span>

              


              

                <span class="post-meta-divider">|</span>

              


              

                <span class="post-meta-item-icon">

                  <i class="fa fa-clock-o"></i>

                </span>

                

                  <span class="post-meta-item-text">阅读时长 &asymp;</span>

                

                <span title="阅读时长">

                  12

                </span>

              

            </div>

          


          


        </div>

      </header>

    


    

    

    

    <div class="post-body" itemprop="articleBody">


      

      


      

        <p>个人剖析,不喜勿喷<br><a id="more"></a>  </p>

<p><strong>扫码关注公众号,不定期更新干活</strong><br><img src="https://img-blog.csdn.net/20161031125322526" alt="这里写图片描述"></p>

<blockquote>

<p>在此申明本博文并非原创,原文:<a href="http://blog.csdn.net/lenotang/article/details/3336623,本文章是在此文章基础上进行优化。也谈不上优化,只是加上了点自己的想法" target="_blank" rel="external">http://blog.csdn.net/lenotang/article/details/3336623,本文章是在此文章基础上进行优化。也谈不上优化,只是加上了点自己的想法</a></p>

</blockquote>

<h2 id="jar包准备"><a href="#jar包准备" class="headerlink" title="jar包准备"></a>jar包准备</h2><ul>

<li><p><img src="https://img-blog.csdn.net/20161025200046888" alt="这里写图片描述"></p>

</li>

<li><p>为什么会用到这两个jar包呢,因为我需要通过这个jar来解析xml配置文件。</p>

</li>

</ul>

<h2 id="新建项目"><a href="#新建项目" class="headerlink" title="新建项目"></a>新建项目</h2><ul>

<li><img src="https://img-blog.csdn.net/20161025200249781" alt="这里写图片描述"></li>

</ul>

<h2 id="流程梳理"><a href="#流程梳理" class="headerlink" title="流程梳理"></a>流程梳理</h2><ul>

<li>struts配置文件</li>

</ul>

<pre><code>```

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

</code></pre><p><struts><br>    <package><br>        <action name="login" method="login" class="org.zxh.action.LoginAction"><br>            <result name="success">/index.jsp</result><br>            <result name="login">/WEB-INF/login.jsp</result><br>        </action><br>    </package><br></struts></p>

<pre><code>```

</code></pre><ul>

<li><p>熟悉struts的朋友都清楚struts.xml配置文件的重要性,这个配置文件名字是可以更改的,这里简单解释下这个配置文件的作用,首先我们找到action这个节点这个action的name是login,就是说前台中请求这个login经过这个配置文件解析就会把这个请求交给action中的class属性,也就是上面的  </p>

<pre><code>org.zxh.action.LoginAction

</code></pre><p>具体的是交由这个类的login(method)这个方法。这个方法会方法一个string类型的字符串,如果返回的是success就将页面重定向到index.jsp如果是login就重定向到login.jsp。这个配置文件就是这样的作用。因为是自己写的,所以这里并不会想struts框架那样封装了很多东西,这里只是为了让读者更加深入的理解struts的运行机制。</p>

</li>

</ul>

<hr>

<h2 id="如何将我们写的struts-xml文件在程序中启动呢?"><a href="#如何将我们写的struts-xml文件在程序中启动呢?" class="headerlink" title="如何将我们写的struts.xml文件在程序中启动呢?"></a>如何将我们写的struts.xml文件在程序中启动呢?</h2><ul>

<li>刚入门的同志可能会疑问,写一个配置文件就能处理前后台交互了?答案当然是不能。这里给大家普及一下web基础接触filter的,每次交互需要filter(jsp就是特殊的servlet),所以想实现交互我们就得新建一个servlet,在这个servlet里我们去读我们写的struts.xml文件,通过读到的信息决定下一步的操作。那么如何启动一个filter呢?这个不多说,直接在web项目中的web.xml配置拦截器就会执行filter。</li>

</ul>

<h2 id="新建filter-FilterDispatcher"><a href="#新建filter-FilterDispatcher" class="headerlink" title="新建filter(FilterDispatcher)"></a>新建filter(FilterDispatcher)</h2><ul>

<li>这个servlet就是struts的核心过滤器,需要先继承过滤器。</li>

</ul>

<pre><code>```


public class FilterDispatcher implements Filter{


@Override

public void destroy() {

    // TODO Auto-generated method stub


}


@Override

public void doFilter(ServletRequest arg0, ServletResponse arg1,

        FilterChain arg2) throws IOException, ServletException {

    // TODO Auto-generated method stub


}


@Override

public void init(FilterConfig arg0) throws ServletException {

    // TODO Auto-generated method stub


}

</code></pre><p>}</p>

<pre><code>```

</code></pre><ul>

<li>Filter中我们要在初始化函数(init)中对一些参数进行初始化,对那些数据初始化呢,对!当然是拿配置文件的信息啦。配置文件是.xml这里我用dom4j读取.xml配置文件。 把struts.xml配置文件放在src下,(可以放在其他地方,这里的地址填的对应就行了)</li>

</ul>

<pre><code>// 获得xml配置文件

        String webRootPath = getClass().getClassLoader()

                .getResource(&quot;struts.xml&quot;).getPath();

</code></pre><ul>

<li><p>拿到配置文件路径之后开始读取,这里我讲读到的数据封装到一个map里面。在封装在Map中我们仔细观察一下配置文件</p>

<p><img src="https://img-blog.csdn.net/20161026185137212" alt="这里写图片描述"></p>

</li>

<li><p>其实我们放在Map里面就是这四个属性的值,有了这四个值我们就可以完成一次前后台交互的映射了。所以为了方便这里封装成javabean。</p>

</li>

</ul>

<pre><code>package org.zxh.util;


import java.util.HashMap;

import java.util.Map;


/**

 * 将action属性封装成类

 * @author 87077

 *

 */

public class ActionConfig {


    //action 给别人调用的名字

    private String name;

    //action对应程序中的action类

    private String clazzName;

    //action中的方法

    private String method;

    //返回结果不知一条 所以用Map

    private Map&lt;String, String&gt; resultMap = new HashMap&lt;String, String&gt;();


    public ActionConfig(){


    }


    public ActionConfig(String name , String clazzName , String method , Map&lt;String, String&gt; resultMap){

        this.name=name;

        this.clazzName=clazzName;

        this.method=method;

        this.resultMap=resultMap;

    }


    public String getName() {

        return name;

    }


    public String getClazzName() {

        return clazzName;

    }


    public String getMethod() {

        return method;

    }


    public Map&lt;String, String&gt; getResultMap() {

        return resultMap;

    }


    public void setName(String name) {

        this.name = name;

    }


    public void setClazzName(String clazzName) {

        this.clazzName = clazzName;

    }


    public void setMethod(String method) {

        this.method = method;

    }


    public void setResultMap(Map&lt;String, String&gt; resultMap) {

        this.resultMap = resultMap;

    }


}

</code></pre><ul>

<li>有了javabean 我们开始解析xml文件</li>

</ul>

<pre><code>package org.zxh.util;


import java.io.File;

import java.util.List;

import java.util.Map;


import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;


/**

 * 采用dom4j解析xml配置文件

 * 

 * @author 87077

 * 

 */

public class ConfigUtil {


    /**

     * @param fileName

     *            待解析的文件

     * @param map

     *            存放解析的数据

     */

    public static void parseConfigFile(String fileName,

            Map&lt;String, ActionConfig&gt; map) {

        SAXReader reader = new SAXReader();

        try {

            Document doc = reader.read(new File(&quot;D:\\zxh\\soft\\apache-tomcat-7.0.70\\apache-tomcat-7.0.70\\webapps\\MyStruts\\WEB-INF\\classes\\struts.xml&quot;));

            Element root = doc.getRootElement();

            List&lt;Element&gt; list = root.selectNodes(&quot;package/action&quot;);

            for (Element element : list) {

                // 封装成ActionConfig对象,保存在map中

                ActionConfig config = new ActionConfig();

                // 获取action中的值

                String name = element.attributeValue(&quot;name&quot;);

                String clazzName = element.attributeValue(&quot;class&quot;);

                String method = element.attributeValue(&quot;method&quot;);

                // 将值传入javabean中

                config.setName(name);

                config.setClazzName(clazzName);

                // 如果没有设置执行method 执行默认的

                if (method == null || &quot;&quot;.equals(method)) {

                    method = &quot;execute&quot;;

                }

                config.setMethod(method);

                // 继续向下获取action中的返回方法

                List&lt;Element&gt; resultList = element.selectNodes(&quot;result&quot;);

                for (Element resultElement : resultList) {

                    String resultName = resultElement.attributeValue(&quot;name&quot;);

                    String urlPath = resultElement.getTextTrim();

                    if (resultName == null || &quot;&quot;.equals(resultName)) {

                        resultName = &quot;success&quot;;

                    }

                    config.getResultMap().put(resultName, urlPath);

                }

                map.put(name, config);

            }

        } catch (DocumentException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

</code></pre><ul>

<li>现在我们在回到过滤器上,上面两个类就是为了解析xml的。所以在Filter中的init方法里我们就可以将解析的数据放到我们的全局Map中</li>

</ul>

<pre><code>@Override

    public void init(FilterConfig arg0) throws ServletException {

        // TODO Auto-generated method stub 过滤器的初始化过程

        // 获得xml配置文件

        String webRootPath = getClass().getClassLoader()

                .getResource(&quot;struts.xml&quot;).getPath();

        // 将xml配置文件解析装在到map中

        ConfigUtil.parseConfigFile(webRootPath, map);

    }

</code></pre><h2 id="过滤器的执行"><a href="#过滤器的执行" class="headerlink" title="过滤器的执行"></a>过滤器的执行</h2><ul>

<li>过滤器真正执行是在doFilter方法开始时。</li>

</ul>

<pre><code>public void doFilter(ServletRequest arg0, ServletResponse arg1,

            FilterChain arg2)

</code></pre><blockquote>

<p>doFilter()方法类似于Servlet接口的service()方法。当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的 doFilter()方法。其中参数 request, response 为 web 容器或 Filter 链的上一个 Filter 传递过来的请求和相应对象;参数 chain 为代表当前 Filter 链的对象,在特定的操作完成后,可以调用 FilterChain 对象的 chain.doFilter(request,response)方法将请求交付给 Filter 链中的下一个 Filter 或者目标 Servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()和include()方法,以及 HttpServletResponse的sendRedirect()方法将请求转向到其他资源。这个方法的请求和响应参数的类型是 ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。</p>

</blockquote>

<ul>

<li>获取请求域和响应域还有Filter链,并设置编码防止乱码</li>

</ul>

<pre><code>//针对http请求,将请求和响应的类型还原为HTTP类型

        HttpServletRequest request = (HttpServletRequest) arg0;

        HttpServletResponse response = (HttpServletResponse) arg1;

        //设置请求和响应的编码问题

        request.setCharacterEncoding(&quot;UTF-8&quot;);

        response.setCharacterEncoding(&quot;UTF-8&quot;);

</code></pre><ul>

<li>获取请求地址</li>

</ul>

<pre><code>//获取请求路径

String url = request.getServletPath();

</code></pre><ul>

<li>通过请求去判断知否拦截过滤这个地址的请求,本文默认过滤所有以.action结尾的请求</li>

</ul>

<pre><code>//请求地址过滤,如果不是以.action结尾的

        if(!url.endsWith(&quot;.action&quot;)){

            //不是.action的放行

            arg2.doFilter(request, response);

            return ;

        }

</code></pre><ul>

<li>看我之前将xml文件中数据放入到Map的格式可以看出我是讲整个javabean放入Map中名字是action的name。所以下面我就要去那个name(就是请求中的login)</li>

</ul>

<pre><code>//解析request路径

        int  start = url.indexOf(&quot;/&quot;);

        int end = url.lastIndexOf(&quot;.&quot;);

        String path=url.substring(start+1,end);

        //通过path去匹配到对应的ActionConfig类。在这里已经解析到了所有的action的信息

        ActionConfig config = map.get(path);

        //匹配不成功就返回找不到页面错误信息

        if(config==null){

            response.setStatus(response.SC_NOT_FOUND);

            return ;

        }

</code></pre><ul>

<li>获取了ActionConfig类了,action的所有信息都存储在这个javabean类中了,下面的事情就好办了。下面的只是会用到反射的知识。我们拿到真正action类的名称后就需要根据名字获取到这个action的实体类。</li>

</ul>

<pre><code>//通过ActionConfig获取完成的类名字

        String clazzName=config.getClazzName();

        //实例化Action对象,不存在的话就提示错误信息 

        Object action = getAction(clazzName);

        if(action==null){

            //说明这个action是错误的,在配置文件中没有占到对应的action类

            response.setStatus(response.SC_NOT_FOUND);

            return ;

        }

</code></pre><h2 id="request参数获取并赋值给action"><a href="#request参数获取并赋值给action" class="headerlink" title="request参数获取并赋值给action"></a>request参数获取并赋值给action</h2><ul>

<li>执行action的方法前很定需要先将request中的参数获取到,进行赋值,这部才是真正的意义上的交互。</li>

</ul>

<pre><code>public static void requestToAction(HttpServletRequest request , Object action )

</code></pre><ul>

<li>将传进来的action对象进行class话并获取action实体下的属性</li>

</ul>

<pre><code>Class&lt;? extends Object&gt; clazzAction = action.getClass();

        //获取aciton中所有属性,从前台获取的值很多,只有action属性中有的才会进行反射赋值

        Field[] fields = action.getClass().getDeclaredFields();

</code></pre><ul>

<li>拿到request传过来的值并进行遍历</li>

</ul>

<pre><code>//获取请求中的名字属性值

        Enumeration&lt;String&gt; names=request.getParameterNames();

</code></pre><pre><code>

String name=names.nextElement();

            boolean flag=false;

            //需要判断action属性中没有的而请求中有的我们不需要进行反射处理

            for (Field field : fields) {

                if(name.equals(field.getName())){

                    flag=true;

                }

            }

            if(!flag){

                return;

            }

            String[] value=request.getParameterValues(name);

</code></pre><ul>

<li>通过request中的name并且在action中有这个属性之后我们就需要获取action这个字段的属性。</li>

</ul>

<pre><code>Class&lt;Object&gt; fieldType=(Class&lt;Object&gt;) clazzAction.getDeclaredField(name).getType();

</code></pre><ul>

<li>获取action的改name字段属性的set方法</li>

</ul>

<pre><code>//通过反射调用该属性的set方法

                    String setName=&quot;set&quot;+name.substring(0,1).toUpperCase()+name.substring(1);

                    Method method=clazzAction.getMethod(setName, new Class[]{fieldType});

</code></pre><ul>

<li>下面我们就需要将获取的value按类型</li>

</ul>

<pre><code>private static Object[] transfer(Class&lt;Object&gt; fieldType , String[] value){

        Object[] os = null;

        //fieldType 是[]这种类型的,需要将[]去掉

        String type=fieldType.getSimpleName().replace(&quot;[]&quot;, &quot;&quot;);

        if(&quot;String&quot;.equals(type)){

            os=value;

        }else if(&quot;int&quot;.equals(type)||&quot;Integer&quot;.equals(type)){

            os = new Integer[value.length];

            for (int i = 0; i &lt; os.length; i++) {

                os[i] = Integer.parseInt(value[i]);

            }

        }else if(&quot;float&quot;.equals(type)||&quot;Float&quot;.equals(type)){

            os=new Float[value.length];

            for (int i = 0; i &lt; os.length; i++) {

                os[i]=Float.parseFloat(value[i]);

            }

        }else if(&quot;double&quot;.equals(type)||&quot;Double&quot;.equals(type)){

            os=new Double[value.length];

            for (int i = 0; i &lt; os.length; i++) {

                os[i]=Double.parseDouble(value[i]);

            }

        }

        return os;

    }

</code></pre><ul>

<li>获取object数据之后就是讲这个object数据通过反射付给action对应的属性</li>

</ul>

<pre><code>//判断是否是数组属性

                    if(fieldType.isArray()){

                        method.invoke(action, new Object[]{object});

                    }else {

                        method.invoke(action, new Object[]{object[0]});

                    }

</code></pre><p>这说一下 method.invoke是将action类中method方法这个方法需要的参数就是object&lt;a href=”<a href="http://www.oschina.net/code/snippet_216465_36771”&gt;详解" target="_blank" rel="external">http://www.oschina.net/code/snippet_216465_36771”&gt;详解</a></p>

<ul>

<li>有了这个方法我们在回到Filter就可以了</li>

</ul>

<pre><code>//前置拦截,获取request里面的参数,调用action的set方法给属性设置值

        BeanUtil.requestToAction(request, action);

</code></pre><ul>

<li>属性赋值完成就开始执行action中的method了</li>

</ul>

<pre><code>private String executeAction(ActionConfig config, Object action) {

        String method = config.getMethod();

        String result = null;

        try {

            Method callMethod = action.getClass().getMethod(method,String.class);

            result = (String) callMethod.invoke(action, new Object[] {});

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        return config.getResultMap().get(result);

    }

</code></pre><ul>

<li>到这里你已经获取了配置文件中前台映射后应该的result了,那么就简单了,直接重定向就可以了,到这里就实现了struts的前后台交互。</li>

</ul>

<pre><code>request.getRequestDispatcher(result).forward(request, response);

</code></pre><h2 id="验证正确性"><a href="#验证正确性" class="headerlink" title="验证正确性"></a>验证正确性</h2><ul>

<li>下面就在前台jsp中form表单将数据传递给我们的login  action看看会不会去执行指定的方法</li>

</ul>

<pre><code>&lt;form method=&quot;post&quot; action=&quot;login.action&quot; name=&quot;loginForm&quot;&gt;

        &lt;table width=&quot;422&quot; border=&quot;1&quot; bgcolor=&quot;#0080c0&quot; height=&quot;184&quot;&gt;

            &lt;caption&gt;

                &lt;h1&gt;用户登陆&lt;/h1&gt;

            &lt;/caption&gt;

            &lt;tbody&gt;

                &lt;tr&gt;

                    &lt;td&gt;&amp;nbsp;姓名:&lt;/td&gt;

                    &lt;td&gt;&amp;nbsp; &lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;

                    &lt;/td&gt;

                &lt;/tr&gt;

                &lt;tr&gt;

                    &lt;td&gt;&amp;nbsp;密码:&lt;/td&gt;

                    &lt;td&gt;&amp;nbsp; &lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;

                    &lt;/td&gt;

                &lt;/tr&gt;

                &lt;tr align=&quot;center&quot;&gt;

                    &lt;td colspan=&quot;2&quot;&gt;&amp;nbsp; &lt;input type=&quot;submit&quot; value=&quot;登陆&quot;

                        name=&quot;submit&quot;&gt; &lt;input type=&quot;reset&quot; value=&quot;重置&quot; name=&quot;reset&quot;&gt;

                    &lt;/td&gt;

                &lt;/tr&gt;

            &lt;/tbody&gt;

        &lt;/table&gt;

    &lt;/form&gt;

</code></pre><ul>

<li>效果读者自行展示吧,到这里struts的运行机制就讲完了,注意知识运行机制里面还有很多值得我们学习的东西,就好比说这里有很多过滤器,不同过滤器过滤数据程度不同执行效果不同。希望有机会再和大家分享一些其他关于struts的知识!</li>

</ul>

<p><strong><a href="http://download.csdn.net/detail/u013132051/9664897" target="_blank" rel="external">上诉原理的×××</a></strong></p>

<p><strong>扫码关注公众号,不定期更新干活</strong><br><img src="https://img-blog.csdn.net/20161031125335637" alt="这里写图片描述"></p>

<p><img src="https://img-blog.csdn.net/20170425212847159?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzEzMjA1MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描述"></p>


      

    </div>

    

    

    


    

      <div>

        <div id="wechat_subscriber" style="display: block; padding: 10px 0; margin: 20px auto; width: 100%; text-align: center">

    <img id="wechat_subscriber_qcode" src="/p_w_picpaths/wechat-qcode.jpg" alt="张新华 wechat" style="width: 200px; max-width: 100%;"/>

    <div>微信关注公众号</div>

</div>


      </div>

    


    

      <div>

        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">

  <div>可怜可怜我吧!</div>

  <button id="rewardButton" disable="enable" qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">

    <span>打赏</span>

  </button>

  <div id="QR" style="display: none;">


    

      <div id="wechat" style="display: inline-block">

        <img id="wechat_qr" src="/p_w_picpaths/wechatpay.jpg" alt="张新华 微信支付"/>

        <p>微信支付</p>

      </div>

    


    

      <div id="alipay" style="display: inline-block">

        <img id="alipay_qr" src="/p_w_picpaths/alipay.jpg" alt="张新华 支付宝"/>

        <p>支付宝</p>

      </div>

    


    


  </div>

</div>


      </div>

    


    


    <footer class="post-footer">

      

        <div class="post-tags">

          

            <a href="/tags/java/" rel="tag"><i class="fa fa-tag"></i> java</a>

          

        </div>

      


      

      

      


      

        <div class="post-nav">

          <div class="post-nav-next post-nav-item">

            

              <a href="/2016/10/22/Java/Window.open使用总结/" rel="next" title="Window.open使用总结">

                <i class="fa fa-chevron-left"></i> Window.open使用总结

              </a>

            

          </div>


          <span class="post-nav-divider"></span>


          <div class="post-nav-prev post-nav-item">

            

              <a href="/2016/11/23/Java/项目部署之工具使用心得/" rel="prev" title="项目部署之工具使用心得">

                项目部署之工具使用心得 <i class="fa fa-chevron-right"></i>

              </a>

            

          </div>

        </div>

      


      

      

    </footer>

  </div>

  

  

  

  </article>




    <div class="post-spread">

      

    </div>

  </div>



          </div>

          



          


  

    <div class="comments" id="comments">

      <div id="SOHUCS"></div>

    </div>


  




        </div>

        

          

  

  <div class="sidebar-toggle">

    <div class="sidebar-toggle-line-wrap">

      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>

      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>

      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>

    </div>

  </div>


  <aside id="sidebar" class="sidebar">

    

    <div class="sidebar-inner">


      


      

        <ul class="sidebar-nav motion-element">

          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">

            文章目录

          </li>

          <li class="sidebar-nav-overview" data-target="site-overview-wrap">

            站点概览

          </li>

        </ul>

      


      <section class="site-overview-wrap sidebar-panel">

        <div class="site-overview">

          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">

            

              <img class="site-author-p_w_picpath" itemprop="p_w_picpath"

                src="http://avatar.csdn.net/E/8/5/2_u013132051.jpg"

                alt="张新华" />

            

              <p class="site-author-name" itemprop="name">张新华</p>

              <p class="site-description motion-element" itemprop="description">张新华的个人网站</p>

          </div>


          <nav class="site-state motion-element">


            

              <div class="site-state-item site-state-posts">

              

                <a href="/archives/">

              

                  <span class="site-state-item-count">86</span>

                  <span class="site-state-item-name">日志</span>

                </a>

              </div>

            


            

              

              

              <div class="site-state-item site-state-categories">

                <a href="/categories/index.html">

                  <span class="site-state-item-count">4</span>

                  <span class="site-state-item-name">分类</span>

                </a>

              </div>

            


            

              

              

              <div class="site-state-item site-state-tags">

                <a href="/tags/index.html">

                  <span class="site-state-item-count">11</span>

                  <span class="site-state-item-name">标签</span>

                </a>

              </div>

            


          </nav>


          

            <div class="feed-link motion-element">

              <a href="/atom.xml" rel="alternate">

                <i class="fa fa-rss"></i>

                RSS

              </a>

            </div>

          


          <div class="links-of-author motion-element">

            

              

                <span class="links-of-author-item">

                  <a href="https://github.com/zxhTom" target="_blank" title="GitHub">

                    

                      <i class="fa fa-fw fa-github"></i>GitHub</a>

                </span>

              

                <span class="links-of-author-item">

                  <a href="mailto:870775401@qq.com" target="_blank" title="E-Mail">

                    

                      <i class="fa fa-fw fa-envelope"></i>E-Mail</a>

                </span>

              

                <span class="links-of-author-item">

                  <a href="https://plus.google.com/yourname" target="_blank" title="Google">

                    

                      <i class="fa fa-fw fa-google"></i>Google</a>

                </span>

              

                <span class="links-of-author-item">

                  <a href="https://twitter.com/yourname" target="_blank" title="Twitter">

                    

                      <i class="fa fa-fw fa-twitter"></i>Twitter</a>

                </span>

              

                <span class="links-of-author-item">

                  <a href="https://stackoverflow.com/yourname" target="_blank" title="StackOverflow">

                    

                      <i class="fa fa-fw fa-stack-overflow"></i>StackOverflow</a>

                </span>

              

            

          </div>


          

          


          

          


          


        </div>

      </section>


      

      <!--noindex-->

        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">

          <div class="post-toc">


            

              

            


            

              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#jar包准备"><span class="nav-number">1.</span> <span class="nav-text">jar包准备</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#新建项目"><span class="nav-number">2.</span> <span class="nav-text">新建项目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#流程梳理"><span class="nav-number">3.</span> <span class="nav-text">流程梳理</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#如何将我们写的struts-xml文件在程序中启动呢?"><span class="nav-number">4.</span> <span class="nav-text">如何将我们写的struts.xml文件在程序中启动呢?</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#新建filter-FilterDispatcher"><span class="nav-number">5.</span> <span class="nav-text">新建filter(FilterDispatcher)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#过滤器的执行"><span class="nav-number">6.</span> <span class="nav-text">过滤器的执行</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#request参数获取并赋值给action"><span class="nav-number">7.</span> <span class="nav-text">request参数获取并赋值给action</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#验证正确性"><span class="nav-number">8.</span> <span class="nav-text">验证正确性</span></a></li></ol></div>

            


          </div>

        </section>

      <!--/noindex-->

      


      


    </div>

  </aside>



        

      </div>

    </main>


    <footer id="footer" class="footer">

      <div class="footer-inner">

        

<div class="copyright">&copy; <span itemprop="copyrightYear">2017</span>

  <span class="with-love">

    <i class="fa fa-user"></i>

  </span>

  <span class="author" itemprop="copyrightHolder">张新华</span>


  

    <span class="post-meta-divider">|</span>

    <span class="post-meta-item-icon">

      <i class="fa fa-area-chart"></i>

    </span>

    

      <span class="post-meta-item-text">博客全站字数&#58;</span>

    

    <span title="博客全站字数">111.1k</span>

  

</div>



   <!--<div class="powered-by">

  <i class="fa fa-user-md"></i><span id="busuanzi_container_site_uv">

    本站访客数:<span id="busuanzi_value_site_uv"></span>次

    本站总访问量<span id="busuanzi_value_site_pv"></span>次

  </span>

  </div>-->

  <!--<div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>-->




  <span class="post-meta-divider">|</span>




  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Pisces</a> v5.1.3</div>




        

<div class="busuanzi-count">

  <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>


  

    <span class="site-uv">

      <i class="fa fa-user">本站访客数</i>

      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>

      人次

    </span>

  


  

    <span class="site-pv">

      <i class="fa fa-eye">本站总访问量</i>

      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>

      次

    </span>

  

</div>









        

      </div>

    </footer>


    

      <div class="back-to-top">

        <i class="fa fa-arrow-up"></i>

        

      </div>

    


    


  </div>


  


<script type="text/javascript">

  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {

    window.Promise = null;

  }

</script>










  













  

  

    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>

  


  

  

    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  


  

  

    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  


  

  

    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>

  


  

  

    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  


  

  

    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>

  



  



  <script type="text/javascript" src="/js/src/utils.js?v=5.1.3"></script>


  <script type="text/javascript" src="/js/src/motion.js?v=5.1.3"></script>




  

  



  <script type="text/javascript" src="/js/src/affix.js?v=5.1.3"></script>


  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.3"></script>




  

  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.3"></script>

<script type="text/javascript" src="/js/src/post-details.js?v=5.1.3"></script>




  



  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.3"></script>




  



  










  






  





  

    <script type="text/javascript">

    (function(){

      var appid = 'cyti5JvoU';

      var conf = 'e14a3908eb6e5192e901a85eb0445f63';

      var width = window.innerWidth || document.documentElement.clientWidth;

      if (width < 960) {

      window.document.write('<script id="changyan_mobile_js" charset="utf-8" type="text/javascript" src="https://changyan.sohu.com/upload/mobile/wap-js/changyan_mobile.js?client_id=' + appid + '&conf=' + conf + '"><\/script>'); } else { var loadJs=function(d,a){var c=document.getElementsByTagName("head")[0]||document.head||document.documentElement;var b=document.createElement("script");b.setAttribute("type","text/javascript");b.setAttribute("charset","UTF-8");b.setAttribute("src",d);if(typeof a==="function"){if(window.attachEvent){b.onreadystatechange=function(){var e=b.readyState;if(e==="loaded"||e==="complete"){b.onreadystatechange=null;a()}}}else{b.οnlοad=a}}c.appendChild(b)};loadJs("https://changyan.sohu.com/upload/changyan.js",function(){

        window.changyan.api.config({appid:appid,conf:conf})});

      }

    })();

    </script>

    <script type="text/javascript" src="https://assets.changyan.sohu.com/upload/plugins/plugins.count.js"></script>

  










  


  <script type="text/javascript">

    // Popup Window;

    var isfetched = false;

    var isXml = true;

    // Search DB path;

    var search_path = "search.xml";

    if (search_path.length === 0) {

      search_path = "search.xml";

    } else if (/json$/i.test(search_path)) {

      isXml = false;

    }

    var path = "/" + search_path;

    // monitor main search box;


    var onPopupClose = function (e) {

      $('.popup').hide();

      $('#local-search-input').val('');

      $('.search-result-list').remove();

      $('#no-result').remove();

      $(".local-search-pop-overlay").remove();

      $('body').css('overflow', '');

    }


    function proceedsearch() {

      $("body")

        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')

        .css('overflow', 'hidden');

      $('.search-popup-overlay').click(onPopupClose);

      $('.popup').toggle();

      var $localSearchInput = $('#local-search-input');

      $localSearchInput.attr("autocapitalize", "none");

      $localSearchInput.attr("autocorrect", "off");

      $localSearchInput.focus();

    }


    // search function;

    var searchFunc = function(path, search_id, content_id) {

      'use strict';


      // start loading animation

      $("body")

        .append('<div class="search-popup-overlay local-search-pop-overlay">' +

          '<div id="search-loading-icon">' +

          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +

          '</div>' +

          '</div>')

        .css('overflow', 'hidden');

      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');


      $.ajax({

        url: path,

        dataType: isXml ? "xml" : "json",

        async: true,

        success: function(res) {

          // get the contents from search data

          isfetched = true;

          $('.popup').detach().appendTo('.header-inner');

          var datas = isXml ? $("entry", res).map(function() {

            return {

              title: $("title", this).text(),

              content: $("content",this).text(),

              url: $("url" , this).text()

            };

          }).get() : res;

          var input = document.getElementById(search_id);

          var resultContent = document.getElementById(content_id);

          var inputEventFunction = function() {

            var searchText = input.value.trim().toLowerCase();

            var keywords = searchText.split(/[\s\-]+/);

            if (keywords.length > 1) {

              keywords.push(searchText);

            }

            var resultItems = [];

            if (searchText.length > 0) {

              // perform local searching

              datas.forEach(function(data) {

                var isMatch = false;

                var hitCount = 0;

                var searchTextCount = 0;

                var title = data.title.trim();

                var titleInLowerCase = title.toLowerCase();

                var content = data.content.trim().replace(/<[^>]+>/g,"");

                var contentInLowerCase = content.toLowerCase();

                var articleUrl = decodeURIComponent(data.url);

                var indexOfTitle = [];

                var indexOfContent = [];

                // only match articles with not empty titles

                if(title != '') {

                  keywords.forEach(function(keyword) {

                    function getIndexByWord(word, text, caseSensitive) {

                      var wordLen = word.length;

                      if (wordLen === 0) {

                        return [];

                      }

                      var startPosition = 0, position = [], index = [];

                      if (!caseSensitive) {

                        text = text.toLowerCase();

                        word = word.toLowerCase();

                      }

                      while ((position = text.indexOf(word, startPosition)) > -1) {

                        index.push({position: position, word: word});

                        startPosition = position + wordLen;

                      }

                      return index;

                    }


                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));

                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));

                  });

                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {

                    isMatch = true;

                    hitCount = indexOfTitle.length + indexOfContent.length;

                  }

                }


                // show search results


                if (isMatch) {

                  // sort index by position of keyword


                  [indexOfTitle, indexOfContent].forEach(function (index) {

                    index.sort(function (itemLeft, itemRight) {

                      if (itemRight.position !== itemLeft.position) {

                        return itemRight.position - itemLeft.position;

                      } else {

                        return itemLeft.word.length - itemRight.word.length;

                      }

                    });

                  });


                  // merge hits into slices


                  function mergeIntoSlice(text, start, end, index) {

                    var item = index[index.length - 1];

                    var position = item.position;

                    var word = item.word;

                    var hits = [];

                    var searchTextCountInSlice = 0;

                    while (position + word.length <= end && index.length != 0) {

                      if (word === searchText) {

                        searchTextCountInSlice++;

                      }

                      hits.push({position: position, length: word.length});

                      var wordEnd = position + word.length;


                      // move to next position of hit


                      index.pop();

                      while (index.length != 0) {

                        item = index[index.length - 1];

                        position = item.position;

                        word = item.word;

                        if (wordEnd > position) {

                          index.pop();

                        } else {

                          break;

                        }

                      }

                    }

                    searchTextCount += searchTextCountInSlice;

                    return {

                      hits: hits,

                      start: start,

                      end: end,

                      searchTextCount: searchTextCountInSlice

                    };

                  }


                  var slicesOfTitle = [];

                  if (indexOfTitle.length != 0) {

                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));

                  }


                  var slicesOfContent = [];

                  while (indexOfContent.length != 0) {

                    var item = indexOfContent[indexOfContent.length - 1];

                    var position = item.position;

                    var word = item.word;

                    // cut out 100 characters

                    var start = position - 20;

                    var end = position + 80;

                    if(start < 0){

                      start = 0;

                    }

                    if (end < position + word.length) {

                      end = position + word.length;

                    }

                    if(end > content.length){

                      end = content.length;

                    }

                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));

                  }


                  // sort slices in content by search text's count and hits' count


                  slicesOfContent.sort(function (sliceLeft, sliceRight) {

                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {

                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;

                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {

                      return sliceRight.hits.length - sliceLeft.hits.length;

                    } else {

                      return sliceLeft.start - sliceRight.start;

                    }

                  });


                  // select top N slices in content


                  var upperBound = parseInt('1');

                  if (upperBound >= 0) {

                    slicesOfContent = slicesOfContent.slice(0, upperBound);

                  }


                  // highlight title and content


                  function highlightKeyword(text, slice) {

                    var result = '';

                    var prevEnd = slice.start;

                    slice.hits.forEach(function (hit) {

                      result += text.substring(prevEnd, hit.position);

                      var end = hit.position + hit.length;

                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';

                      prevEnd = end;

                    });

                    result += text.substring(prevEnd, slice.end);

                    return result;

                  }


                  var resultItem = '';


                  if (slicesOfTitle.length != 0) {

                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";

                  } else {

                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";

                  }


                  slicesOfContent.forEach(function (slice) {

                    resultItem += "<a href='" + articleUrl + "'>" +

                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +

                      "...</p>" + "</a>";

                  });


                  resultItem += "</li>";

                  resultItems.push({

                    item: resultItem,

                    searchTextCount: searchTextCount,

                    hitCount: hitCount,

                    id: resultItems.length

                  });

                }

              })

            };

            if (keywords.length === 1 && keywords[0] === "") {

              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'

            } else if (resultItems.length === 0) {

              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'

            } else {

              resultItems.sort(function (resultLeft, resultRight) {

                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {

                  return resultRight.searchTextCount - resultLeft.searchTextCount;

                } else if (resultLeft.hitCount !== resultRight.hitCount) {

                  return resultRight.hitCount - resultLeft.hitCount;

                } else {

                  return resultRight.id - resultLeft.id;

                }

              });

              var searchResultList = '<ul class=\"search-result-list\">';

              resultItems.forEach(function (result) {

                searchResultList += result.item;

              })

              searchResultList += "</ul>";

              resultContent.innerHTML = searchResultList;

            }

          }


          if ('auto' === 'auto') {

            input.addEventListener('input', inputEventFunction);

          } else {

            $('.search-icon').click(inputEventFunction);

            input.addEventListener('keypress', function (event) {

              if (event.keyCode === 13) {

                inputEventFunction();

              }

            });

          }


          // remove loading animation

          $(".local-search-pop-overlay").remove();

          $('body').css('overflow', '');


          proceedsearch();

        }

      });

    }


    // handle and trigger popup window;

    $('.popup-trigger').click(function(e) {

      e.stopPropagation();

      if (isfetched === false) {

        searchFunc(path, 'local-search-input', 'local-search-result');

      } else {

        proceedsearch();

      };

    });


    $('.popup-btn-close').click(onPopupClose);

    $('.popup').click(function(e){

      e.stopPropagation();

    });

    $(document).on('keyup', function (event) {

      var shouldDismissSearchPopup = event.which === 27 &&

        $('.search-popup').is(':visible');

      if (shouldDismissSearchPopup) {

        onPopupClose();

      }

    });

  </script>






  


  


  

  


  


  


  


</body>

</html>