理解Struts2的Action中的setter方法是怎么工作的

 我来答
匿名用户
2016-05-28
展开全部
(1)提交表单时的参数
在struts2-core-2.3.1.2.jar压缩包内的struts-default.xml配置文件中有这个配置:
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
这个拦截器是负责解析请求中的URL参数,并赋值给action中对应的属性
来看代码:
Java代码
//com.opensymphony.xwork2.interceptor.ParametersInterceptor.java
//主要代码如下:
//...

@Override
public String doIntercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (!(action instanceof NoParameters)) {
ActionContext ac = invocation.getInvocationContext();
final Map<String, Object> parameters = retrieveParameters(ac);

if (LOG.isDebugEnabled()) {
LOG.debug("Setting params " + getParameterLogMap(parameters));
}

if (parameters != null) {
Map<String, Object> contextMap = ac.getContextMap();
try {
ReflectionContextState.setCreatingNullObjects(contextMap, true);
ReflectionContextState.setDenyMethodExecution(contextMap, true);
ReflectionContextState.setReportingConversionErrors(contextMap, true);

ValueStack stack = ac.getValueStack();
setParameters(action, stack, parameters);
} finally {
ReflectionContextState.setCreatingNullObjects(contextMap, false);
ReflectionContextState.setDenyMethodExecution(contextMap, false);
ReflectionContextState.setReportingConversionErrors(contextMap, false);
}
}
}
return invocation.invoke();
}

protected void setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) {
ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)
? (ParameterNameAware) action : null;

Map<String, Object> params;
Map<String, Object> acceptableParameters;
if (ordered) {
params = new TreeMap<String, Object>(getOrderedComparator());
acceptableParameters = new TreeMap<String, Object>(getOrderedComparator());
params.putAll(parameters);
} else {
params = new TreeMap<String, Object>(parameters);
acceptableParameters = new TreeMap<String, Object>();
}

for (Map.Entry<String, Object> entry : params.entrySet()) {
String name = entry.getKey();

boolean acceptableName = acceptableName(name)
&& (parameterNameAware == null
|| parameterNameAware.acceptableParameterName(name));

if (acceptableName) {
acceptableParameters.put(name, entry.getValue());
}
}

ValueStack newStack = valueStackFactory.createValueStack(stack);
boolean clearableStack = newStack instanceof ClearableValueStack;
if (clearableStack) {
//if the stack's context can be cleared, do that to prevent OGNL
//from having access to objects in the stack, see XW-641
((ClearableValueStack)newStack).clearContextValues();
Map<String, Object> context = newStack.getContext();
ReflectionContextState.setCreatingNullObjects(context, true);
ReflectionContextState.setDenyMethodExecution(context, true);
ReflectionContextState.setReportingConversionErrors(context, true);

//keep locale from original context
context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE));
}

boolean memberAccessStack = newStack instanceof MemberAccessValueStack;
if (memberAccessStack) {
//block or allow access to properties
//see WW-2761 for more details
MemberAccessValueStack accessValueStack = (MemberAccessValueStack) newStack;
accessValueStack.setAcceptProperties(acceptParams);
accessValueStack.setExcludeProperties(excludeParams);
}

for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();
try {
newStack.setParameter(name, value);
} catch (RuntimeException e) {
if (devMode) {
String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
"Unexpected Exception caught setting '" + name + "' on '" + action.getClass() + ": " + e.getMessage()
});
LOG.error(developerNotification);
if (action instanceof ValidationAware) {
((ValidationAware) action).addActionMessage(developerNotification);
}
}
}
}

if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS));

addParametersToContext(ActionContext.getContext(), acceptableParameters);
}
//...

上面的代码ValueStack stack = ac.getValueStack();
表明,它是从当前Action上下文获取值栈(其实就类似一个全局Map集合,用来存储参数值或struts上下文全局变量),
然后由判断如果是当前action可以接受的参数(Action中有setter方法)就过滤出来,
调用这句“newStack.setParameter(name, value); ”来保存到值栈中,
保存到了值栈中其实action实例的属性就能拿到值了。
最后一句“addParametersToContext(ActionContext.getContext(), acceptableParameters); ”
表明它还把这些过滤出来的参数保存到了ActionContext上下文中,
这样,如果跳转的类型是forward(服务器内部重定向),
目标url中就会带上上次请求的url的所有有用的参数。

(2) Spring配置bean注入到Action中
来看一个简单的Action类:
Java代码
package com.liany.demo.pubs.org.employee.action;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

import com.liany.demo.pubs.org.employee.model.Employee;
import com.liany.demo.pubs.org.employee.service.EmployeeService;

public class EmployeeAction extends ActionSupport{

private EmployeeService employeeService;
private List list;
private Employee employee = new Employee();

public StringReader getStringReader() {
StringReader is = null;
try {
is = new StringReader(xmlBuf.toString());
} catch (Exception e) {
e.printStackTrace();
}
return is;
}

public Employee getEmployee() {
return employee;
}

public void setEmployee(Employee employee) {
this.employee = employee;
}

public List getList() {
return list;
}

public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}

public String execute(){
//列表
list = this.employeeService.getEmployees();

return "list";
}

public String view(){
employee = this.employeeService.getEmployeeById(employee.getId());

return "view";
}

public String edit(){
if(employee.getId()!=null){
//修改
employee = this.employeeService.getEmployeeById(employee.getId());
}else{
//新增
employee.setId(null);
}

return "input";
}

public String save(){
this.employeeService.saveEmployee(employee);

return "repage";
}

public String delete(){
this.employeeService.deleteEmployeeById(employee.getId());

return "repage";
}
}

上面Action中的employeeService对象其实是在Spring配置文件中声明的bean,
代码中给它定义一个public的setEmployeeService()方法,这样就可以将bean实例注入到
Action中的实例中,这个功能是在Struts过虑器初始化的时候初始化了一个全局变量,
从而使得调用action时,从spring ioc容器中找到这个bean,再set给action对象。
配置文件是在struts.properties 文件中声明:
struts.objectFactory = spring
struts.objectFactory.spring.autoWire = name
匿名用户
2016-05-28
展开全部
只要在你的action中添加tyId的属性就行(属性名称要和这参数名一样),并且要有它的setter和getter方法,请求的时候就可以自动抓取值了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式