视图层传递参数(Struts2)

5 篇文章 0 订阅
2 篇文章 0 订阅
  1. 说明:struts2中前端页面传递各种参数(简单参数,数组,List,Set,Map 及复合结构)至后端。
  2. 建议:如果你需要了解如何传递数组的,先看页面再看对应的Action,再看里面的注释(如果想了解传参的具体细节或底层思想)。演示输出结果,请看控制台。
  3. 环境:tomcat+struts2+Ognl
  4. 主代码如下:
**************************1视图层CODE*****************************
findUser.jsp>>>>>>>>>>>


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String basePath = request.getScheme()+"://"
				+ request.getServerName() +":"
				+request.getServerPort() +"/"
				+ request.getContextPath()+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 重写href,作为相对路径 -->
 <base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>findUser.jsp</title>
</head>
<body>


	<h1>前端提交到服务器的数据的数据结构</h1>
	<p>
			
http://localhost:8080/应用名/findUser.action?
user.id=1688&pnames=tom&pnames=anie&pnames=maniy&names%5B0%5D=%E6%9D%8E%E4%B8%89&names%5B1%5D=%E6%9D%8E%E5%9B%9B
&names%5B2%5D=%E7%8E%8B%E4%BA%94&user.ids%5B0%5D=10086&user.ids%5B1%5D=10082&user.ids%5B2%5D=10085
&user.orders%5B0%5D.orderId=order1688&user.orders%5B0%5D.orderName=AJ%E9%A3%9E%E4%BA%BA&user.orders%5B0%5D.productPrice=1500
&user.orders%5B1%5D.orderId=order1699&user.orders%5B1%5D.orderName=Ads%E4%B8%89%E5%8F%B6&user.orders%5B1%5D.productPrice=800
&orderSet.makeNew%5B0%5D.orderName=hi&orderSet.makeNew%5B1%5D.orderName=hello&userMap.user.id=2600
&userMap.user.name=jack&userMap%5B%27mu2%27%5D.id=2700&userMap%5B%27mu2%27%5D.name=jack2
	<br/>
	
	<span>
	 <blockquote>前端(视图层)映射到后端时的数据结构。可以看出都是弱类型(文本类型String)来表示前端的所有数据。 
	也就是说:不论你是float,int,String,Date,object在前端都视为弱类型,那为映射到java中,必须要进行数据类型转换。
	转换的具体思路或过程,在UserAction.java文件中搜索:"前端的弱类型数据转换成java强类型思路或过程"有说明。</blockquote>
	</span><br/>
	{<br/> <blockquote>
		用户id:<br/>
		user.id=[Ljava.lang.String;@1504a84, <br/>
		
		用户名数组,方式一<br/>
		pnames=[Ljava.lang.String;@1644c9, <br/>
		
		用户名数组,方式二(Ognl)<br/>
		names[0]=[Ljava.lang.String;@3da671, names[1]=[Ljava.lang.String;@13aa7d4, names[2]=[Ljava.lang.String;@49968b,<br/>
		
		对象中数组:<br/>
		user.ids[0]=[Ljava.lang.String;@28ad5a, user.ids[1]=[Ljava.lang.String;@13864d9, user.ids[2]=[Ljava.lang.String;@1c66091,<br/>
		
		List传参:List<Order>	<br/>	
		user.orders[0].orderId=[Ljava.lang.String;@a87a8, <br/>
		user.orders[0].orderName=[Ljava.lang.String;@164e850, user.orders[0].productPrice=[Ljava.lang.String;@eeda37,<br/> 
					
		user.orders[1].orderId=[Ljava.lang.String;@17a8369,<br/>
		user.orders[1].orderName=[Ljava.lang.String;@1fdf894, user.orders[1].productPrice=[Ljava.lang.String;@4c4ff8,<br/>
		
		Set传参:Set<Order><br/>
		orderSet.makeNew[0].orderName=[Ljava.lang.String;@1e070c0, <br/>
		orderSet.makeNew[1].orderName=[Ljava.lang.String;@edfb95, <br/>

		Map传参:Map<User><br/>
		userMap.user.id=[Ljava.lang.String;@201dbc, userMap.user.name=[Ljava.lang.String;@8024c8,<br/> 
		userMap['mu2'].id=[Ljava.lang.String;@8d241b, userMap['mu2'].name=[Ljava.lang.String;@1cfee57<br/>
		</blockquote>
	}
	</p><hr>
	<h1>开发中实用传参方式及原理说明(实验时建议选中所有数据再提交)</h1>
	<form action="findUser.action" method="get">
		<div>
			<span>1.根据用户id查询用户</span><br/>
			<input type="text" name="user.id" value="1688"/><br/>
		</div>
		
		<div>
			<span>2.简单数组传参1(原始方式,但后端设值还是用到Ognl)</span><br/>
			<!-- 获取user,再获取ids,运用Array.set(array, index, value)设值<br/> -->
			tom<input type="checkbox" name="pnames" value="tom"><br/>
			anie<input type="checkbox" name="pnames" value="anie"><br/>
			maniy<input type="checkbox" name="pnames" value="maniy"><br/><br/>
		</div>
		
		<!-- 以下全是ognl方式传参 -->
		<div>
			<span>3.简单数组传参2(这以下皆为Ognl方式传递参数)</span><br/>
			<!-- 获取user,再获取ids,运用Array.set(array, index, value)设值<br/> -->
			李三<input type="checkbox" name="names[0]" value="李三"><br/>
			李四<input type="checkbox" name="names[1]" value="李四"><br/>
			王五<input type="checkbox" name="names[2]" value="王五"><br/>
		</div>
		
		<div>
			<span>4.对象中的数组传参</span><br/>
			<!-- 获取user,再获取ids,运用Array.set(array, index, value)设值<br/> -->
			10086<input type="checkbox" name="user.ids[0]" value="10086"><br/>
			10082<input type="checkbox" name="user.ids[1]" value="10082"><br/>
			10085<input type="checkbox" name="user.ids[2]" value="10085"><br/>
		</div>
				
		<div>
			<span>5.List传参(List&lt;Order&gt;)</span><br/>
			<span>第一个订单</span><br/>
			order1688<input type="checkbox" name="user.orders[0].orderId" value="order1688"><br/>
			AJ飞人<input type="checkbox" name="user.orders[0].orderName" value="AJ飞人"><br/>
			1500<input type="checkbox" name="user.orders[0].productPrice" value="1500"><br/><br/>
	
			<!-- 第二个订单 :重复异常user.orders[0].productPrice-->
			<span>第二个订单</span><br/>
			order1699<input type="checkbox" name="user.orders[1].orderId" value="order1699"><br/>
			Ads三叶<input type="checkbox" name="user.orders[1].orderName" value="Ads三叶"><br/>
			800<input type="checkbox" name="user.orders[1].productPrice" value="800"><br/><br/>		
		</div> 
		
		<div>6.Set传参<br/>
			hi<input type="checkbox" name="orderSet.makeNew[0].orderName" value="hi"><br/>
			hello<input type="checkbox" name="orderSet.makeNew[1].orderName" value="hello"><br/><br/>
		</div>
	
		<div>7.Map接收参数<br/>
			<span>第一个Entry(指定Map的key为user)</span><br/>
			2600<input type="checkbox" name="userMap.user.id" value="2600"><br/>
			jack<input type="checkbox" name="userMap.user.name" value="jack"><br/><br/>
			
			<span>第二个Entry(指定Map的key为mu2,若作用相同的key则进行"追加赋值")</span><br/>
			2700<input type="checkbox" name="userMap['mu2'].id" value="2700"><br/>
			jack2<input type="checkbox" name="userMap['mu2'].name" value="jack2"><br/>
		</div>

		<input type="submit" value="提交数据" /><br/>
		
			
	</form>
</body>
</html>


showFindUser.jsp >>>>>>>>>>>>>


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
	import="java.util.*"
	import="com.opensymphony.xwork2.ognl.OgnlValueStack"
	import="com.opensymphony.xwork2.util.CompoundRoot"
	import="org.yl.action.UserAction"
	import="org.yl.domain.User"
	
	
%>
<!-- 引入struts2标签库 -->
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
  String basePath = request.getScheme()+"://"
				+ request.getServerName() +":"
				+request.getServerPort() +"/"
				+ request.getContextPath()+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>视图层:JSP,从ValueStack中的CompoundRoot中取值</h1>
	
	<div>
		<span>用户信息:</span><br/>
		<!-- 1.java直接取值 -->
		<%
			OgnlValueStack vs = (OgnlValueStack)request.getAttribute("struts.valueStack");
			//值栈的上下文
			Map<String,Object> vsContext = vs.getContext();
			for(Map.Entry<String, Object> entry: vsContext.entrySet()){
				//System.out.println("key:" + entry.getKey() + "--value:" + entry.getValue() + "\n");
			}
			//值栈的根(CompoundRoot数据结构为栈,使用ArrayList实现的)
			CompoundRoot root = vs.getRoot();
			Object obj = root.peek();//从root栈中取出一个数据
			UserAction userAction = null;
		 	User user = null;
		 	String name = null;
			if(obj instanceof UserAction){
				userAction = (UserAction)obj;
				user = userAction.getUser();
				System.out.println("************showFindUser.jsp页面展示信息*************");
				System.out.println("Action中的成员变量信息:" +"\n"
							+ "1.user信息 ======"
							+ "id:" + user.getId() + "\n"
							+ "name:" + user.getName() + "\n"
							+ "sex:" + user.getSex() + "\n"
							+ "deposit:" + user.getDeposit()+ "\n"
							+ "telephone:" + user.getTelephone() + "\n"
							+"");
				name = user.getName();//供页面使用,与html标签进行整合
			}
			
		%>
		java直接取值:<input type="text" value="<%=name %>" readonly="readonly" /><br/>
		
		<!-- 2.标签库解药or毒药 -->
		<!-- el表达式 -->
		el表达式取值:<input type="text" value="${user.name }" readonly="readonly" /><br/>
		
		<!-- 使用struts2标签库中的标签 
		<s:property value="user.telephone"/><br/>-->
		struts2标签取值:<input type="text" value="<s:property value="user.telephone"/>" readonly="readonly" /><br/>
		
	</div>
	
</body>
</html>
**************************2控制层CODE*****************************
UserAction.java >>>>>>>

package org.yl.action;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.yl.domain.Order;
import org.yl.domain.User;

import com.opensymphony.xwork2.util.Element;
import com.opensymphony.xwork2.util.KeyProperty;


/**
 * 演示:显示层从ValueStack中取值
 *  (1)视图层传递参数
 * 	(2)el+jstl
 * 	(3)struts2标签库+Ognl
 * 
 * @author 拈花为何不一笑
 *
 *	此UserAction对应的页面:findUser.jsp
 */
public class UserAction {//何时何地创建Action?服务Action时创建ActionProxy,
	//而在创建代理时ObjectFactory创建Action并且把Action放入至值栈中(实际是放入CompoundRoot中)
	//何地?DefaultActionInvocation作为场地
	
	//初始化
	private User user = new User();
	
	//普通数组(原始方式接收数组)
	private String pnames[];
	
	
	//普通数组(Ognl方式:names[0])
	private String names[] = new String[6];
	
	
	//Xwork2重写Ognl中的SetPropertyAccessor等Accessor
	//Set中不支持存放基本数据类型和String类型(即使String被实例化为"",也不能当作类对象操作String中的属性或方法),可以存放javaBean
	//private Set<String> sts = new HashSet<String>();
	
	//Set集合接收参数
	/**
	 * 表达式:orderSet.makeNew[0].orderName
	 * 问题一:如何把新创建了的Order作为元素被添加到orderSet中的?怎么辨别或区分新创建的Order的?引入了一个包装类:SurrugeList
	 * 	且它的成员变量surrugate存放orderSet(HashSet)
	 * 简要而关键的流程:
	 * 	1.把orderSet(HashSet类型)包装成一个SurrugateList用于对应下标[0][1]……
	 * (因为Set中取值是用iterator,而没有get(index)。为了与表达式中的下标关联List类型,用到了SurrugateList)
	 * 2.ATS Node:makeNew获取Property时创建SurrugateList
	 * 3.后面逻辑就按List Accessor进行处理
	 * 
	 * 4.ATS Nod:[0]获取Property时,使用XWorkListPropertyAccessor
	 * 		对象工厂创建bean,用@Element注解(orderSet属性上的注解)获取bean的Class
	 * 	来创建bean(Order):
	 * 		objectFactory.buildBean(beanClass, context)
	 *  并把这个创建的Order元素放到SurrugateList的的成员变量surrugate(存放的是orderSet)中:
	 *  	orderSet.add(Order);
	 * 
	 * 5.再然后,通过Ognl给Order.setOrderName("前端的参数值"),就OK了。
	 * 
	 * 问题二:这个过程中用到了两个注解:@KeyProperty和@Element,它们的作用是什么呢?
	 * 		 注解:@KeyProperty 作为后面逻辑,进行数据类型转换的Class参数
	 * 			(不设置会报异常:Error getting property descriptor影响整个过程。对当前的参数映射到Set中并无逻辑关系)
	 * 		 注解:@Element 创建Set<T>中的T时,使用到的beanClass
	 *
	 * 以上过程总结起来就是一句话:Ognl解析Set类型的表达式时,是披着ListAccessor的外衣把Set当作List来处理的。(当然这是Xwork2对Ognl的扩展了)
	 * 
	 * 建议:由于Set逻辑处理繁琐且复杂,昼量用List替代Set接收参数。(Set食之无味,弃之可惜!)	 
	 */
	@KeyProperty(value="orderId")
	@Element(value=org.yl.domain.Order.class )
	private Set<Order> orderSet = new HashSet<Order>();//若不初始化,默认创建一个ArrayList,显然不正确 
	
	
	//Map接收参数
	private Map<String,User> userMap = new HashMap<String,User>();
	
	
	
	
	
	
	//业务方法(struts.xml的UserAction配置中不指定具体方法时,excute或doExecute作为默认方法)
	public String doExecute(){//执行action阶段调用
		System.out.println("findUser...");
		
		
		/**
		 * 下面逻辑发生在拦截器阶段
		 * 1.xwork2的InstantiatingNullHandler类调用对象工厂objectFactory.buildBean(clazz, context);
		 * 来创建了UserAction中为空的成员属性User:user。
		 * 2.当UserAction中的成员属性是类对象时且开发人员没有初始化时,
		 * 	由Ognl+CompoundRootAccessor+InstantiatingNullHandler经过一系列逻辑创建了该成员属性
		 *  创建User实例后,再通过Ognl把前端传递过来的参数值:user.id="m-p6"赋给User对象中的成员变量id。
		 * 3.由于步骤2开销不少,建议开发中先初始化Action中的成员变量(类对象作为Action的成员变量),避免程序执行步骤2
		 */
		if(this.user != null){//UserAction中的User实例也被框架创建了。(谁创建的?在哪创建的?)
			System.out.println("user.id:" + this.user.getId());
			//模拟从DB或企业信息系统中获取到的数据
			if(user.getId() != null && user.getId().equals("1688")){
				this.user.setName("张天见");
				this.user.setSex("男");
				this.user.setTelephone("13638885606");
				this.user.setDeposit(73000);
			}
			/**
			 * 原始方式接收参数
			 * 
			 */
			//数组接收参数:接收前端传递的多个pnames
			String[] mypnames = this.pnames;
			if(mypnames != null && mypnames.length > 0){
				System.out.println("***数组接收参数1:前端参数pnames映射到UserActoin中的成员变量pnames***");
				for(String pn:mypnames){
					System.out.println(pn);
				}
			}
			
			/**
			 * 以下都是ognl方式接收参数,顺便说一说前端的弱类型数据转换成java强类型思路或过程
			 * Ongl设值过程序,前端传递过来的参数被xwork+ognl进行了文本弱类型转换成java强类型
			 *  比如:前端传递一个文本类型(弱类型)name=user.orders[0].productPrice" value="1500"
			 *   1500是个文本类型,如何转换成java强类型float?
			 *  简要说下过程:拿到setProductPrice(float)方法,再拿到这个方法的参数类型float。
			 *  知道了是对float进行设值,那么xwork+ognl就把弱类型1500转换成float类型。
			 *  
			 *  说明:xwork对ognl数据类型转换进行了扩展。
			 */
			//数组来接收参数:前端参数ids映射到UserActoin中的成员变量User中的ids
			String ids[] = this.user.getIds();
			if(ids !=null && ids.length > 0){
				System.out.println("***数组接收参数2:前端参数ids映射到UserActoin中的成员变量User中的ids***");
				for(String e:ids){
					System.out.println(e);
				}
			}
			

			//数组来接收参数:前端参数names映射到UserActoin中的成员变量names
			String names[] = this.names;
			if(names != null && names.length > 0){
				System.out.println("***数组接收参数:前端参数names映射到UserActoin中的成员变量names***");
				for(String n:names){
					
					try {
						if(n!= null)
						n = new String(n.getBytes("ISO-8859-1"),"UTF-8");
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					System.out.println(n);
				}
			}
			
			//List接收数据List<Order> orders
			List<Order> orders = this.user.getOrders();
			if(orders != null && orders.size() > 0){
				System.out.println("***List接收数据:前端参数orders映射到UserActoin中的成员变量User中的orders***");
				for(Order order:orders){
						if(order!= null){
							String orderName = null;
							try {
								orderName = new String(order.getOrderName().getBytes("ISO-8859-1"),"UTF-8");
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
							System.out.println("订单号:" + order.getOrderId() +"\n"
									+ "订单名称:" + orderName  +"\n"
									+ "产品单价:" + order.getProductPrice() + "\n"
									);
						
							System.out.println("\n\n");
						}
				}
			}//
			
			//set接收数据,与list逻辑相似只是多了一个披外衣的过程
			System.out.println("************Set接收数据*******************");
			if(this.orderSet != null && this.orderSet.size() > 0){
				for(Order or: orderSet){
					System.out.println(or.getOrderName());
				}
			}//
			
			//Map接收参数
			System.out.println("************Map接收数据*******************");
			Map<String,User> uMap = this.userMap;
			if(uMap != null && !uMap.isEmpty()){
				for(Map.Entry<String, User> entry:uMap.entrySet()){
					String key = entry.getKey();
					User u = entry.getValue();
					//使用userMap.user.id的user作为key
					System.out.println("key-String:" + key);
					System.out.println("value-User如下:");
					if(u!=null){
						System.out.println("用户Id:"+u.getId()+", 用户名:"+u.getName());
					}
				}
			}
			
		}
		
		
		//struts2中提供与Web容器直接交互的类:ServletActionContext
		//获取服务器路径
		/*HttpServletRequest request =ServletActionContext.getRequest();
		String serverPath = request.getSession().getServletContext().getRealPath("/");
		System.out.println("serverPath: " + serverPath);*/

		return "showFindUser";
	}
	
	
	public User getUser() {
		return user;
	}

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


	public void setNames(String names[]) {
		this.names = names;
	}


	public String[] getNames() {
		return names;
	}



	public void setOrderSet(Set<Order> orderSet) {
		this.orderSet = orderSet;
	}


	public Set<Order> getOrderSet() {
		return orderSet;
	}


	public void setUserMap(Map<String,User> userMap) {
		this.userMap = userMap;
	}


	public Map<String,User> getUserMap() {
		return userMap;
	}

	public void setPnames(String pnames[]) {
		this.pnames = pnames;
	}


	public String[] getPnames() {
		return pnames;
	}


	
}

**************************3配置文件E*****************************
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>
	<!-- 常量bean配置 -->
	<constant name="struts.devMode" value="true" />
	<!-- action事件映射 -->
    <package name="default" namespace="/" extends="struts-default">
       <action name="reg" class="org.yl.action.Register">
		  <result name="success">/success.jsp</result>
		</action>
       
       <action name="findUser" class="org.yl.action.UserAction">
		  <result name="showFindUser">/showFindUser.jsp</result>
		</action>
       
       
    </package>

</struts>

=123向左向右向前向后。///******

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值