论坛首页 Java企业应用论坛

struts2中参数传递的问题

浏览 12978 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-10  
看WebWork in action时,书中第12章提出了两种参数传递的方式,即Deep和Flat,书中的定义是:
Flat means the action always has all the fields needed to construct the entire request.
Deep means the action only has the objects it works with, such as domain model.
我们用一个简单的Login来说明问题:
User是领域模型,它仅含有username和password属性
user.java
package newsposter.model;

import java.io.Serializable;

public class User implements Serializable{
	private Long id;
	private String username;
	private String password;
	//********************** Construtor Methods ********************* //
	public User(){}
	public User(String username,String password){
		this.username = username;
		this.password = password;
	}
	// ********************** Accessor Methods ********************** //
	public String getPassword() {
		return password;
	}
	
	public String getUsername() {
		return username;
	}
	
	public Long getId() {
		return id;
	}
	// ********************** Common Methods ********************** //
	public boolean equals(Object o) {
		if(!(o instanceof User))
			return false;
		
		return ((User)o).getUsername().equals(username);
	}
	public int hashCode() {
		return username.hashCode();
	}
}

当我使用Flat方式传递参数时,能够正确的得到结果,下面是Login.jsp和Login.java的代码
以下代码中加粗的是两种方式不同的地方
Login.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page pageEncoding="GBK" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>登入</title>
  </head>
  
  <body onLoad="self.focus();document.Login.username.focus()">
  	<s:actionerror />
  	<s:form action="Login" validate="true" method="post">
                <!--这里直接使用User的域名来访问-->
  		<s:textfield label="用户名" name="username"/>
  		<s:password name="password" showPassword="true" label="密码" />
  		<s:submit key="登入"/>
  		<s:reset key="重置"/>
  		<s:submit action="Login_cancel" key="取消" onclick="form.onsubmit=null" />
  	</s:form>
  </body>
</html>

Login.java
package newsposter.web;

import java.util.Map;

import newsposter.model.User;
import newsposter.service.FacadeManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;

public class Login extends ActionSupport implements SessionAware{
	private static Log log = LogFactory.getLog(Login.class);
	public String cancel() throws Exception{
		return "cancel";
	}
	//FacadeManager是一个用来访问DAO层的门面模式封装
	private FacadeManager facadeManager;
	
	public FacadeManager getFacadeManager() {
		return facadeManager;
	}

	public void setFacadeManager(FacadeManager facadeManager) {
		this.facadeManager = facadeManager;
	}

	private Map session;

	public Map getSession() {
		return session;
	}

	public void setSession(Map session) {
		this.session = session;
	}
	//这里用的是User的所有域
	private String username;
	
	private String password;
	
	public String execute() throws Exception{
		log.info("in execute() method"); 
		User u = facadeManager.getUser(username);
		if((u != null) &&!u.getPassword().equals(password)){
			u = null;
		}
		if(u == null){
			this.addFieldError("password", "无效的用户名和密码");
			return Action.INPUT;
		}
		getSession().put("user", u);
		return Action.SUCCESS;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
}

当改用Deep方式时,我没有成功,下面是我失败的代码:
Login.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page pageEncoding="GBK" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>登入</title>
  </head>
  
  <body onLoad="self.focus();document.Login.username.focus()">
  	<s:actionerror />
  	<s:form action="Login" validate="true" method="post">
                <!--这里是通过User来访问他的域-->
  		<s:textfield label="用户名" name="%{user.username}"/>
  		<s:password name="%{user.password}" showPassword="true" label="密码" />
  		<s:submit key="登入"/>
  		<s:reset key="重置"/>
  		<s:submit action="Login_cancel" key="取消" onclick="form.onsubmit=null" />
  	</s:form>
  </body>
</html>

Login.java
package newsposter.web;

import java.util.Map;

import newsposter.model.User;
import newsposter.service.FacadeManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;

public class Login extends ActionSupport implements SessionAware{
	private static Log log = LogFactory.getLog(Login.class);
	public String cancel() throws Exception{
		return "cancel";
	}
	//FacadeManager是一个用来访问DAO层的门面模式封装
	private FacadeManager facadeManager;
	
	public FacadeManager getFacadeManager() {
		return facadeManager;
	}

	public void setFacadeManager(FacadeManager facadeManager) {
		this.facadeManager = facadeManager;
	}

	private Map session;

	public Map getSession() {
		return session;
	}

	public void setSession(Map session) {
		this.session = session;
	}
	//这里仅使用User
	private User user = new User();
	
	public String execute() throws Exception{
		log.info("in execute() method"); 
		User u = facadeManager.getUser(user.getUsername());
		if((u != null) &&!u.getPassword().equals(user.getPassword())){
			u = null;
		}
		if(u == null){
			this.addFieldError("password", "无效的用户名和密码");
			return Action.INPUT;
		}
		getSession().put("user", u);
		return Action.SUCCESS;
	}

	public User getUser(){
               return user;
        }

        public void setUser(User user){
              this.user = user;
        }
}

这样执行的话没有任何反应,希望各位达人赐教一二
   发表时间:2007-05-10  
要实现ModelDriven接口吧。
0 请登录后投票
   发表时间:2007-05-10  
1.
引用

<s:textfield label="用户名" name="username"/> 
         <s:password name="password" showPassword="true" label="密码" /> 



2.

<s:textfield label="用户名" name="%{user.username}"/> 
         <s:password name="%{user.password}" showPassword="true" label="密码" /> 


为什么写法不一样?

2应该用 user.username, not %{user.username}
0 请登录后投票
   发表时间:2007-05-10  
这个我尝试过了,如果直接用user.username的话,ParameterInterceptor会寻找一个user.username的变量
0 请登录后投票
   发表时间:2007-05-10  
我是象scud那样用的,没有问题
如果ParameterInterceptor有问题,可能需要查查其他配置
0 请登录后投票
   发表时间:2007-05-10  
用user.username仍是不行,贴我的配置吧
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.devMode" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation"
		value="false" />
	<constant name="struts.objectFactory" value="spring" />
	<constant name="struts.i18n.encoding" value="GBK" />
	<package name="newsposter" namespace="/" extends="struts-default">
		<interceptors>
			<interceptor name="authentication"
				class="newsposter.web.AuthenticationInterceptor" />
			<interceptor-stack name="user">
				<interceptor-ref name="authentication" />
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
			<interceptor-stack name="user-submit">
				<interceptor-ref name="token-session" />
				<interceptor-ref name="user" />
			</interceptor-stack>
			<interceptor-stack name="guest">
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="user" />
		<global-results>
			<result name="error">/pages/Error.jsp</result>
			<result name="invalid.token">/pages/Error.jsp</result>
			<result name="login" type="redirect-action">
				Login_input
			</result>
		</global-results>

		<global-exception-mappings>
			<exception-mapping result="error"
				exception="java.lang.Throwable" />
		</global-exception-mappings>
		<action name="Login_*" method="{1}" class="login">
			<result name="input">/pages/Login.jsp</result>
			<result name="cancel" type="redirect-action">HomePage</result>
			<result type="redirect-action">HomePage</result>
			<interceptor-ref name="guest" />
		</action>
	</package>
</struts>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
	<display-name>NewsPoster</display-name>
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>gbk</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>hibernateFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>hibernateFilter</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:applicationContext*.xml</param-value>
	</context-param>
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

我运行时得到的异常是:
18:20:11,807 ERROR ParametersInterceptor:198 - ParametersInterceptor - [setParameters]: Unexpected Exception catched: Error setting expression 'user.password' with value '[Ljava.lang.String;@19ba1d8'
18:20:11,817 ERROR ParametersInterceptor:198 - ParametersInterceptor - [setParameters]: Unexpected Exception catched: Error setting expression 'user.username' with value '[Ljava.lang.String;@15738e0'
18:20:11,817 ERROR ParametersInterceptor:198 - ParametersInterceptor - [setParameters]: Unexpected Exception catched: Error setting expression '登入' with value '[Ljava.lang.String;@15726ec'
0 请登录后投票
   发表时间:2007-05-10  
你给的代码不全,没法调试啊~~~
是不是因为Login的user属性尚未初始化?你试试先为它赋个初始值

另外Login.java中的setUser方法没有参数,似乎是有问题吧!?
0 请登录后投票
   发表时间:2007-05-10  
Deep方式login.java中关于User的部分应该这么写:
public class Login extends ActionSupport implements SessionAware{  
    private User user; //这里不要初始化,切记;也可以写成private User user = null;
     // getter/setter 必需的,一定不能少
     public User getUser() {
        return this.user
    }
    public void setUser(User user) {
        this.user = user;
    }
    // 其他代码省略
     .....................
}


在页面中应该使用name="user.username"和name="user.password",以此类推
0 请登录后投票
   发表时间:2007-05-11  
十分感谢大家的帮助,问题解决了,原来是User类中没有定义setUsername()和setPassword()方法,
相当弱智的错误了,狠狠的抽了自己3个耳刮子,汗呀
1 请登录后投票
   发表时间:2007-05-11  
^_^  我和楼主一样, 以前经常被一个莫明其妙的问题阻碍很长时间也解决不了, 结果在没在意的乱看以前的代码时, 发现原来是这里名字大写变小写了, 或者是在""里面多了一个空格。现在熟练一些, 这些问题出现的也少了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics