深入理解struts的运行机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解struts的运行机制相关的知识,希望对你有一定的参考价值。
<!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="/images/apple-touch-icon-next.png?v=5.1.3">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.3">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.3">
<link rel="mask-icon" href="/images/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:image" content="http://img.blog.csdn.net/20161031125322526">
<meta property="og:image" content="http://img.blog.csdn.net/20161025200046888">
<meta property="og:image" content="http://img.blog.csdn.net/20161025200249781">
<meta property="og:image" content="http://img.blog.csdn.net/20161026185137212">
<meta property="og:image" content="http://img.blog.csdn.net/20161031125335637">
<meta property="og:image" content="http://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:image" content="http://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="image" 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">字数统计:</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">阅读时长 ≈</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="http://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="http://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="http://img.blog.csdn.net/20161025200249781" alt="这里写图片描述"></li>
</ul>
<h2 id="流程梳理"><a href="#流程梳理" class="headerlink" title="流程梳理"></a>流程梳理</h2><ul>
<li>struts配置文件</li>
</ul>
<pre><code>```
<?xml version="1.0" encoding="UTF-8"?>
</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("struts.xml").getPath();
</code></pre><ul>
<li><p>拿到配置文件路径之后开始读取,这里我讲读到的数据封装到一个map里面。在封装在Map中我们仔细观察一下配置文件</p>
<p><img src="http://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<String, String> resultMap = new HashMap<String, String>();
public ActionConfig(){
}
public ActionConfig(String name , String clazzName , String method , Map<String, String> 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<String, String> 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<String, String> 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<String, ActionConfig> map) {
SAXReader reader = new SAXReader();
try {
Document doc = reader.read(new File("D:\\zxh\\soft\\apache-tomcat-7.0.70\\apache-tomcat-7.0.70\\webapps\\MyStruts\\WEB-INF\\classes\\struts.xml"));
Element root = doc.getRootElement();
List<Element> list = root.selectNodes("package/action");
for (Element element : list) {
// 封装成ActionConfig对象,保存在map中
ActionConfig config = new ActionConfig();
// 获取action中的值
String name = element.attributeValue("name");
String clazzName = element.attributeValue("class");
String method = element.attributeValue("method");
// 将值传入javabean中
config.setName(name);
config.setClazzName(clazzName);
// 如果没有设置执行method 执行默认的
if (method == null || "".equals(method)) {
method = "execute";
}
config.setMethod(method);
// 继续向下获取action中的返回方法
List<Element> resultList = element.selectNodes("result");
for (Element resultElement : resultList) {
String resultName = resultElement.attributeValue("name");
String urlPath = resultElement.getTextTrim();
if (resultName == null || "".equals(resultName)) {
resultName = "success";
}
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("struts.xml").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("UTF-8");
response.setCharacterEncoding("UTF-8");
</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(".action")){
//不是.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("/");
int end = url.lastIndexOf(".");
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<? extends Object> clazzAction = action.getClass();
//获取aciton中所有属性,从前台获取的值很多,只有action属性中有的才会进行反射赋值
Field[] fields = action.getClass().getDeclaredFields();
</code></pre><ul>
<li>拿到request传过来的值并进行遍历</li>
</ul>
<pre><code>//获取请求中的名字属性值
Enumeration<String> 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<Object> fieldType=(Class<Object>) clazzAction.getDeclaredField(name).getType();
</code></pre><ul>
<li>获取action的改name字段属性的set方法</li>
</ul>
<pre><code>//通过反射调用该属性的set方法
String setName="set"+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<Object> fieldType , String[] value){
Object[] os = null;
//fieldType 是[]这种类型的,需要将[]去掉
String type=fieldType.getSimpleName().replace("[]", "");
if("String".equals(type)){
os=value;
}else if("int".equals(type)||"Integer".equals(type)){
os = new Integer[value.length];
for (int i = 0; i < os.length; i++) {
os[i] = Integer.parseInt(value[i]);
}
}else if("float".equals(type)||"Float".equals(type)){
os=new Float[value.length];
for (int i = 0; i < os.length; i++) {
os[i]=Float.parseFloat(value[i]);
}
}else if("double".equals(type)||"Double".equals(type)){
os=new Double[value.length];
for (int i = 0; i < 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<a href=”<a href="http://www.oschina.net/code/snippet_216465_36771”>详解" target="_blank" rel="external">http://www.oschina.net/code/snippet_216465_36771”>详解</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><form method="post" action="login.action" name="loginForm">
<table width="422" border="1" bgcolor="#0080c0" height="184">
<caption>
<h1>用户登陆</h1>
</caption>
<tbody>
<tr>
<td>&nbsp;姓名:</td>
<td>&nbsp; <input type="text" name="username">
</td>
</tr>
<tr>
<td>&nbsp;密码:</td>
<td>&nbsp; <input type="password" name="password">
</td>
</tr>
<tr align="center">
<td colspan="2">&nbsp; <input type="submit" value="登陆"
name="submit"> <input type="reset" value="重置" name="reset">
</td>
</tr>
</tbody>
</table>
</form>
</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="http://img.blog.csdn.net/20161031125335637" alt="这里写图片描述"></p>
<p><img src="http://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="/images/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="/images/wechatpay.jpg" alt="张新华 微信支付"/>
<p>微信支付</p>
</div>
<div id="alipay" style="display: inline-block">
<img id="alipay_qr" src="/images/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-image" itemprop="image"
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:[email protected]" 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">© <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">博客全站字数:</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">主题 — <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.onload=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>
本文出自 “11110543” 博客,转载请与作者联系!
以上是关于深入理解struts的运行机制的主要内容,如果未能解决你的问题,请参考以下文章