Samuel Learning

  • 联系
  •  
  • 管理

文章分类(203)

  • 01 ASP/HTML(6)
  • 02 Script/CSS(16)
  • 03 C/C++
  • 04 XML(4)
  • 05 微软编程(26)
  • 06 J2EE(60)
  • 09 Linux(14)
  • 10 Database(27)
  • 11 报表打印
  • 12 打包安装(1)
  • 13 模式重构(2)
  • 14 系统架构
  • 15 敏捷开发(11)
  • 16 案例分析(30)
  • 17 Workflow(1)
  • 18 配置管理(1)
  • 19 项目管理
  • 20 英语(4)

新闻分类(52)

  • CXF学习
  • Hibernate学习(1)
  • iBatis学习(16)
  • Struts1学习(1)
  • Struts2学习(34)

.NET资源

  • adxmenu
  • C# Open Source
  • DNN Directory
  • M2Land
  • Windows Form FAQ
  • 中国DNN
  • 中国DNN联盟

Ajax

  • DoJo
  • GWT
  • JQuery
  • jquery autocomplete
  • jquery flexgrid
  • JQuery Form
  • jquery masked input
  • JQuery UI
  • jquery validation
  • Jquery 图表
  • jquery报表
  • jquery插件集合
  • Qooxdoo
  • Tibco GI
  • YUI
  • YUI-EXT
  • ZeroKode

Java开源

  • ABLE
  • Agile Tao
  • Ajax4JSF
  • Alfresco
  • AppFuse
  • Compiere
  • Equinox
  • Findbugs
  • Geronimo
  • Grails
  • Harmony
  • Hibernate论坛
  • JAG
  • Java开源大全
  • Java视线论坛
  • jBPM工作流
  • JSFTutorials
  • Nereide ERP
  • Ofbiz ERP
  • Opentaps ERP
  • operamasks
  • Petstore
  • Prototype.js
  • RIFE
  • Runa
  • SpringSide
  • Struts Menu
  • Sun Glassfish
  • Trails
  • YUI4JSF
  • 满江红

Mobile

  • Sencha

WEB资源

  • DHTML中心
  • DHTML参考手册
  • DHTML文档
  • EclipsePlugin
  • Firebug
  • GRO Clinux
  • jMaki
  • JSTL文档
  • LoadIcon
  • Openlaszlo
  • Struts Menu 展示
  • Web Test Tools
  • WebCtrs
  • Webdeveloper
  • 中国RIA开发者论坛

Workflow

  • E-Workflow
  • JBPM
  • OpenWFE
  • OSWorkflow
  • WFMC
  • Workflow Research

其他连接

  • confach
  • CPP
  • ejay
  • Giovanni
  • 丹佛
  • 交大e-learning
  • 交大研究生院
  • 可恶的猫
  • 天天@blog
  • 我的相册
  • 阿飞

大牛人

  • 32篇JBPM
  • David.Turing
  • HongSoft@业务集成
  • Joel
  • Koen Aers
  • Martinfowler
  • Raible Matt
  • Raible Wiki
  • Scott W.Ambler
  • Tom Baeyens
  • Uncle Bob
  • 一个世界在等待
  • 子在川上曰
  • 小布老师
  • 小明
  • 差沙
  • 徐昊
  • 江南白衣
  • 汪博士
  • 汪小金
  • 银狐999

开源软件

  • 2Bizbox ERP
  • CompiereCRM&ERP
  • EGW
  • Vtiger CRM
  • webERP

敏捷

  • Canoo
  • Cruisecontrol
  • DBUnit
  • EL4Ant
  • Extreme Programming
  • Fit
  • Fitnesse
  • JFrog
  • Liquibase
  • Maven
  • MockObjects
  • Selenium
  • Squish
  • xpairtise
  • XPlanner
  • XProgramming
  • 敏捷联盟

数据库

  • Oracle 中国
  • Oracle-ERP
  • Oracle在线社区

未归类

  • Aquarius Orm Studio
  • mambo建站系统
  • Oracle产品下载
  • 远程同步管理工具Capivara

经典框架

  • Apache Shale
  • formdef-struts
  • FreeMarker 主页
  • JBoss Seam
  • JSF 中心
  • JSF 入门应用
  • JSF中国
  • MyFaces官方
  • Spring 社区
  • Spring专业网站
  • Spring中文论坛
  • Spring参考手册
  • Spring官方网站
  • strecks-struts
  • Struts1
  • Struts2
  • Struts-layout
  • StrutsWiKi
  • Tapestry WIKI
  • Tapestry 官方
  • Tapestry4开发指南
  • Tapestry中文文档
  • Webwork2文档
  • Wicket

网络教程

  • Laliluna
  • RoseIndia
  • Sang Shin
  • Visualbuilder

著名站点

  • Buildix
  • Dev2Dev
  • IBM dev中国
  • InfoQ
  • ITPub
  • Java Eye
  • Java Research
  • JavaRead
  • JavaWorldTW
  • Matrix
  • PHP100
  • PHPX
  • SpringSideWiKi
  • TheServerSide
  • TWPHP
  • 中国工作流论坛

项目管理

  • 管理人网

最新评论

View Post

Struts2 FAQ[笔记]

1,怎样显示用字节数组提供的动态或静态图片:
o display an image represented as an array of bytes
  • Reference an Action for the image src attribute
    关系到提供image源属性的Action
  • Provide a helper method on the Action to return an array of bytes
    在Action中提供一个返回字节数组的方法
  • Provide a Result Type that renders the array to the response
    提供一个渲染字节数组为图片的Result类型

MyAction.jsp
<img src="/myWebAppContext/myAction.do" />

Provide Helper Methods

MyAction.java
public class MyAction extends ActionSupport {
public String doDefault() {
return "myImageResult";
}

public byte[] getMyImageInBytes() { .... }

public String getMyContentType() { ... }
public String getMyContentDisposition() { ... }
public int getMyContentLength() { .... }
public int getMyBufferSize() { ... }

}

Provide a Custom Result Type

struts.xml
<struts>

...
<result-types>
<result-type name="myBytesResult" class="MyBytesResult" />
</result-types>
...
<action name="myAction" class="MyAction">
<result name="myImageResult" type="myBytesResult">
<param name="contentType">${myContentType}</param>
<param name="contentDisposition">${myContentDisposition}</param>
<param name="contentLength">${myContentLength}</param>
<param name="bufferSize">${myBufferSize}</param>
<result>
</action>
...

</struts>
MyBytesResult.java
public class MyBytesResult implements Result {

public void execute(ActionInvocation invocation) throws Exception {

MyAction action = (MyAction) invocation.getAction();
HttpServletResponse response = ServletActionContext.getResponse();

response.setContentType(action.getContentType());
response.setContentLength(action.getContentLength());

response.getOutputStream().write(action.getImageInBytes());
response.getOutputStream().flush();
}

}


2,怎样测试Struts2的web应用

First, push as much business and data access logic as possible out of the Action class and into a POJO facade that the Action can call. In this way, you can test all that outside of the Action. The MailReader is a fair example of this, although the data access API is quirky and could be streamlined.

首先,把业务和数据访问逻辑分离出去,并且放到能够被Action调用的POJO facade里。这样,你可以在Action的外面测试这部分内容。

After that, what's really left to test is the UI. For UI tests, a very good choice is Selenium.

之后,需要测试UI,对于UI测试,Selenium是个非常好的选择。

The Selenium IDE (a FireFox plugin) includes a recorder to help jump start the tests, and then you can go back and edit the tests, and also add test that can't be easily recorded. (Like is a control disabled or text not present.)

The best part is that the initial tests can be recorded in HTML and the convert to real Java code. The Java code can then be run as part of a standard JUnit test (if the Selenium proxy server is running in the background).

最好的部分是,初始化测试在Html能被录制下来,并且转化成真正的Java代码。Java代码能够作为标准的JUnit来测试(只要Selenium代理服务器在后台运行)


3,怎样测试Action?

The Struts 2 Action doesn't expose HTTP in its signature. When access to HTTP resources is needed, references to these resources can be injected at runtime, but, to the Action, the servlet resources appear as ordinary Maps. When running tests outside of the framework, the test scaffolding can create and set a Map with whatever objects are needed by the test.

Struts2 Action在签名上不依赖预HTTP。当访问需要的HTTP是,这些资源在运行时能构被注入。Action,servlet资源看上区就像通用的Maps。当在Framework外部测试时,测试平台会建立所有需要的任何对象的映射。

There are several approaches to unit testing Struts 2-based applications, whether using JUnit or TestNG. Two popular techniques are direct Action invocation and testing interceptors and result-types independently. We will demonstrate both approaches using JUnit 3.

两个流行的技术是独立地测试直接的Action调用和interceptor和Result-Type。

Direct Action Invocation

The simplest approach is to instantiate your Actions, call the appropriate setters, then invoke execute. Calling the Action directly allows you to bypass all the complicated container setup.

最简单的手段是实例化Action,调用相关的Setter,然后调用excute。调用Action直接允许你绕过复杂的容器启动过程。

Taken from Petsoar
package org.petsoar.actions.inventory;

import com.mockobjects.constraint.IsEqual;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;
import com.opensymphony.xwork.Action;
import junit.framework.TestCase;
import org.petsoar.pets.Pet;
import org.petsoar.pets.PetStore;

public class TestViewPet extends TestCase {
private Mock mockPetStore;
private ViewPet action;

protected void setUp() throws Exception {
mockPetStore = new Mock(PetStore.class);
PetStore petStore = (PetStore) mockPetStore.proxy();

action = new ViewPet();
action.setPetStore(petStore);
}

public void testViewPet() throws Exception {
Pet existingPet = new Pet();
existingPet.setName("harry");
existingPet.setId(1);

Pet expectedPet = new Pet();
expectedPet.setName("harry");
expectedPet.setId(1);

mockPetStore.expectAndReturn("getPet", C.args(new IsEqual(new Long(1))), existingPet);
action.setId(1);

String result = action.execute();

assertEquals(Action.SUCCESS, result);
assertEquals(expectedPet, existingPet);
mockPetStore.verify();
}

public void testViewPetNoId() throws Exception {
mockPetStore.expectAndReturn("getPet", C.ANY_ARGS, null);

String result = action.execute();

assertEquals(Action.ERROR, result);
assertEquals(1, action.getActionErrors().size());
assertEquals("Invalid pet selected.", action.getActionErrors().iterator().next());
assertNull(action.getPet());
mockPetStore.verify();
}

public void testViewPetInvalidId() throws Exception {
action.setId(-1);
testViewPetNoId();
}
}

Testing Interceptors and/or Result Types

Check out the test suites in XWork and Struts 2. These suites are comprehensive and provide a good starting point. Here's an example.

取出XWork和Struts2的测试套件,这些测试套件是复杂的,并且提供了好的起点。

Test for ParametersInterceptor
public void testDoesNotAllowMethodInvocations() {
Map params = new HashMap();
params.put("@java.lang.System@exit(1).dummy", "dumb value");

HashMap extraContext = new HashMap();
extraContext.put(ActionContext.PARAMETERS, params);

try {
ActionProxy proxy = ActionProxyFactory.getFactory().
createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, extraContext);
assertEquals(Action.SUCCESS, proxy.execute());

ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
TestBean model = (TestBean) action.getModel();

String property = System.getProperty("action.security.test");
assertNull(property);
} catch (Exception e) {
e.printStackTrace();
fail();
}
}

The framework also provides built-in support for JUnit 3.8 via an abstract StrutsTestCase, which provides common Struts variables and setup code.

框架也提供了一个抽象的StrutsTestCase,支持JUnit3.8,这个类提供了常用的Struts变量和启动代码。


4,怎样上传文件?

You can obtain the MultipartRequestWrapper from the ServletActionContext or by utilizing the fileUpload interceptor. The fileUpload interceptor is preferred.

Ask the ServletActionContext

MultipartRequestWrapper multipartRequest = ((MultipartRequestWrapper)ServletActionContext.getRequest())

The MultipartRequestWrapper provideds access methods such as getFiles, getFile, getContentType, hasErrors, getErrors, and so forth, so that you can process the file uploaded.

Utilize the fileUpload Interceptor

_Preferred_

  • Ensure that {{fileUpload }} Interceptor is included in the Action's stack.
    • The default stack already includes {{fileUpload }}.
  • Ensure that the HTML form sets the enctype and specifies on or more file type inputs.
<form name="myForm" enctype="multipart/form-data">
<input type="file" name="myDoc" value="Browse ..." />
<input type="submit" />
</form>
  • Ensure that the Action provides one or more fileUpload mutator methods, with names that correspond to name of the file type input.
public void setMyDoc(File myDoc)
public void setMyDocContentType(String contentType)
public void setMyDocFileName(String filename)
  • The Action may also provide the corresponding accessor methods.
public File getMyDoc()
public ContentType getMyDocContentType()
public String getMyDocFileName()

Handling multiple files

When multiple files are uploaded by a form, the files are represented by an array.

可以在同一个Form上传多个文件哦,厉害了

Given:

<form name="myForm" enctype="multipart/form-data">
<input type="file" name="myDoc" value="Browse File A ..." />
<input type="file" name="myDoc" value="Browse File B ..." />
<input type="file" name="myDoc" value="Browse File C ..." />
<input type="submit" />
</form>

The Action class can define file handling methods that accept an array.

public void setMyDoc(File[] myDocs)
public void setMyDocContentType(String[] contentTypes)
public void setMyDocFileName(String[] fileNames)

The uploaded files can be handled by iterating through the appropriate array.

Extra Information

Property Default
struts.multipart.parser Commons FileUpload
struts.multipart.saveDir javax.servlet.context.tempdir as defined by container
struts.multipart.maxSize Approximately 2M

@see struts.properties
@see org.apache.struts2.dispatcher.FilterDispatcher#doFilter(SerlvetRequest, ServletRepsonse, FilterChain)
@see org.apache.struts2.dispatcher.DispatcherUtil#wrapRequest(HttpServletRequest, SerlvetContext)
@see org.apache.struts2.dispatcher.multipart.MultipartRequestWrapper
@see org.apache.struts2.interceptor.FileUploadInterceptor


5,怎样处理配置中Result的参数?

Sometimes there is a need to redirect from one action to another, but you do not know the exact url or the destination url requires parameters that are only known in runtime.

有时,需要重定向到另外一个Action,但是你不知道确切的url或者目标url需要的运行时才知道的参数。

Struts 2 gives you easy to use solution for that problem.

Parameters in action result definitions

<struts>
....
<package name="somePackage" namespace="/myNamespace" extends="struts-default">
<action name="myAction" class="com.project.MyAction">
<result name="success" type="redirect-action">otherAction?id=${id}</result>
<result name="back" type="redirect">${redirectURL}</result>
</action>

<action name="otherAction" class="com.project.MyOtherAction">
...
</action>
</package>
....
</struts>

The only requirement is to declare the necessary properties in your action, in this case com.project.MyAction should define properties id and redirectURL with standard accessor methods.

仅仅需要在Action里声明需要的属性,本例中:com.project.MyAction 应该定义redirectURL和get函数。

public class MyAction extends ActionSupport {
private int id;
private String redirectURL;
...


public String execute() {
...
if (someCondition) {
this.redirectURL = "/the/target/page.action";
return "back";
}

this.id = 123;
return SUCCESS;
}

public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
public String getRedirectURL() { return this.redirectURL; }
public void setRedirectURL(String redirectURL) { this.redirectURL= redirectURL; }
...
}

In the above code if it returns SUCCESS then the browser will be forwarded to
/<app-prefix>/myNamespace/otherAction.action?id=123


6,怎样访问Action中的参数?

You can obtain the request parameters by asking the ActionContext or implementing ParameterAware. Implementing ParameterAware is preferred.

你可以通过访问ActionContext或者实现ParameterAware获取请求参数。实现ParameterAware是首选的。

Ask the ActionContext

The request parameters are available on the ActionContext instance, which is made available via ThreadLocal.

Map parameters = ActionContext.getContext().getParameters();

Implement ParameterAware

Preferred

  • Ensure that servlet-config Interceptor is included in the Action's stack.
    • The default stack already includes servlet-config.
  • Edit the Action so that it implements the ParameterAware interface.
    • The ParameterAware interface expects a setParameters method. You may wish to include a companion getParameters method.
  • At runtime, call getParameters to obtain a Map representing the request parameters.
Map parameters = this.getParameters();
When the servlet-config Interceptor sees that an Action implements ParameterAware, it passes a Map of the request parameters to the Action's setParameters method.

To unit test a ParameterAware Action, create your own Map with the pertinent request parameters and call setParameters as part of the test's setUp method.

@see struts-default.xml
@see org.apache.struts.action2.interceptor.ParameterAware
@see org.apache.struts.action2.interceptor.Servlet Config Interceptor

7,怎样访问JAAS?

You can obtain the UserPrincipal and other security details by going through the request or implementing PrincipalAware. Implementing PrincipalAware is preferred.

Go Through the Request

First obtain the HttpServletRequest and then obtain the security Principal.

HttpServletRequest request = ServletActionContext.getRequest();
String authType = request.getAuthType(); // http or https
String user = request.getRemoteUser(); // the user principal (in string)
Principalprincipal = request.getUserPrincipal(); // get a Principal object
bool isAuth = request.isUserInRole("patrick");

Implement PrincipalAware

Preferred

  • Ensure that servlet-config Interceptor is included in the Action's stack.
    • The default stack already includes servlet-config.
  • Edit the Action so that it implements the PrincipalAware interface.
    • The PrincipalAware interface expects a setPrincipalProxy(PrincipalProxy) method. You may wish to include a companion getPrincipalProxy method.
  • At runtime, use the PrincipalProxy reference to invoke methods such as isUserInRole, getUserPrincipal(), getRemoteUser(), isRequestSecure(), and so forth.

@see org.apache.struts.action2.interceptor.PrincipalProxy
@see org.apache.struts.action2.interceptor.PrincipalAware
@see org.apache.struts.action2.interceptor.ServletConfigInterceptor


8,怎样访问JSTL?
About JSTL
The JavaServer Pages Standard Tag Library (JSTL) encapsulates as simple tags the core functionality common to many Web applications. JSTL has support for common, structural tasks such as iteration and conditionals, tags for manipulating XML documents, internationalization tags, and SQL tags.

JSTL integration is built into the framework - there are no steps required to enable it. Simply refer to your JSTL expressions just as you would with a normal SAF JSP tag, such as the property tag.

JSTL被整合到框架里面,不需要做任何工作。GOOD!


Javadoc: (org.apache.struts.action2.dispatcher.StrutsRequestWrapper)

All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops. Namely, we don't let any attribute name with "#" in it delegate out to the value stack, as it could potentially cause an infinite loop. For example, an infinite loop would take place if you called: request.getAttribute("#attr.foo").








posted on 2007-04-27 14:01 MingIsMe 阅读(1283) 评论(0)  编辑  收藏 所属分类: Struts2学习

 
Powered by:
BlogJava
Copyright © MingIsMe