JavaEE高级框架学习笔记(九)Struts高级Action

0. 前言

熟悉了Struts的开发流程之后,一个新的问题出现了。一个表单对应一个Action和ActionForm是常见的事情,如果这个表单有两种提交的方式,一个Action是否能够解决呢?比如在一个页面上,用户输入账号和密码之后,可以选择“登录”按钮,也可以选择“注册”按钮。

一个表单对应两种截然不同的提交方式,用Action中的execute方法还能够很好的胜任吗?也许可以,但是这要求Action必须认识JSP页面的内容。这种被动的方式是开发过程中最为忌讳的。Action和JSP进行了耦合,违背了MVC的原则。

所以DispatchAction,就能够动态的处理上述问题。

1.DispatchAction

这里以购物车为例,用户可以选择把喜欢的书籍加入购物车,也可以选择从购物车删除。请求被发送到一个Action里面,利用DispatchAction可以解决Action过多,系统变得臃肿的问题。

buy.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> 
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>   
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>购买书籍</title>
</head>
<body>
	<html:form action="/buy.do?method=add">
		book<html:text property="book"></html:text>
		<html:submit value="加入购物车"/>
	</html:form><br>
	<logic:present name="cart">
	<logic:iterate id="book" name="cart">
		<bean:write name="book"/>
		<html:link action="/buy.do?method=delete" paramId="BOOK" paramName="book">删除</html:link>
		</logic:iterate>
	</logic:present>
</body>
</html>

上述代码的method是用户自主定义的,为了识别Action内的方法。

struts-config.xml:

<form-bean name="buyForm" type="Action.BuyForm"/>

<action name="buyForm" path="/buy" parameter="method" scope="request"
 type="Action.BuyAction"/>

上述代码的parameter就是方便jsp认识Action内的方法。

BuyAction.jsp:

package Action;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import jdk.nashorn.internal.ir.RuntimeNode.Request;

/**
 * 作用:
 *@author   欧世乐
 */
public class BuyAction extends DispatchAction{
	public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			BuyForm buyForm=(BuyForm)form;
			String book=buyForm.getBook();
			HttpSession session=request.getSession();
			
			ArrayList cart=(ArrayList) session.getAttribute("cart");
			if(cart==null) {
				cart=new ArrayList();
			}
			cart.add(book);
			
			session.setAttribute("cart", cart);
			
		return new ActionForward("/buy.jsp");
	}
	
	public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			
			String book=request.getParameter("BOOK");
			HttpSession session=request.getSession();
			
			ArrayList cart=(ArrayList) session.getAttribute("cart");
			
			cart.remove(book);
			
			session.setAttribute("cart", cart);
			
		return new ActionForward("/buy.jsp");
	}
}	

在这里插入图片描述

但是这种方法也有缺陷,jsp页面必须要认识Action的方法,才可以调用。所以接下来要改进这种方法。

2.MappingDispatchAction

在Action中将继承的父类从DispatchAction改为MappingDispatchAction,在从配置文件里面,将ActionForm内的方法予以注册,这样jsp就可以调用配置文件内的方法进行提交表单,而不需要和Action有任何的交集。

Struts-config.xml:

<form-bean name="buyForm" type="Action.BuyForm"/>

<action name="buyForm" path="/add" parameter="add" scope="request" type="Action.BuyAction"/>
<action path="/delete" parameter="delete"  type="Action.BuyAction"/>

BuyAction.jsp:

public class BuyAction extends MappingDispatchAction{
	public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			BuyForm buyForm=(BuyForm)form;
			String book=buyForm.getBook();
			HttpSession session=request.getSession();
			
			ArrayList cart=(ArrayList) session.getAttribute("cart");
			if(cart==null) {
				cart=new ArrayList();
			}
			cart.add(book);
			
			session.setAttribute("cart", cart);
			
		return new ActionForward("/buy.jsp");
	}
	
	public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			
			String book=request.getParameter("BOOK");
			HttpSession session=request.getSession();
			
			ArrayList cart=(ArrayList) session.getAttribute("cart");
			
			cart.remove(book);
			
			session.setAttribute("cart", cart);
			
		return new ActionForward("/buy.jsp");
	}
}	

3.LookUpDispatchAction

让我们回到前言里面的问题,一个页面,可以选择登录或者注册,提交表单后Action如何去认识呢?LookUpDispatchAction类可以提供新思路

流程:

1.建立ActionForm和相应的JSP,建立LookUpDispatchAction,此时按钮标签从资源文件获取。

2.重写getKeyMethodMap方法(用一个map保存资源文件key和方法名的映射)

3.编写方法

4.为Action建立参数

5.将提交按钮和property和参数名称一致

LookUpDispatchAction主要是利用资源文件对提交的按钮进行检索,而资源文件的内容会保存在map里面,这也是为什么强制要求重写getKeyMethodMap方法的原因。

LrAction.java:

package Action;

import java.util.HashMap;
import java.util.Map;

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.LookupDispatchAction;

/**
 * 作用:
 *@author   欧世乐
 */
public class LrAction extends LookupDispatchAction{

	@Override
	protected Map getKeyMethodMap() {//用一个map保存资源文件key和方法名的映射
		Map map=new HashMap();
		map.put("info.tag.login", "login");
		map.put("info.tag.reg", "reg");
		return map;
	}
	
	
	public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		LrForm lrForm=(LrForm)form;
		System.out.println("登录");
		return null;
	}
	public ActionForward reg(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		LrForm lrForm=(LrForm)form;
		System.out.println("注册");
		return null;
	}
	
}

资源文件:

info.tag.login = Login
info.tag.reg   = reg

lr.jsp:

<html:form action="/lr.do">
		账号<html:text property="account"></html:text><br>
		密码<html:password property="password"></html:password><br>
		<html:submit property="method" ><bean:message key="info.tag.login"/></html:submit>
		<html:submit property="method" ><bean:message key="info.tag.reg"/></html:submit>
	</html:form>

这里的提交按钮是交给资源文件来校验的,不同的key对应不同的内容,这个内容在传送到Action的时候,map会自动去检索这个内容,究竟是login还是reg,然后调用相应的方法。
在这里插入图片描述

4.小结

Action还有许多的用法,和基础比起来,DispatchAction,MappingDispatchAction和LookUpDispatchAction都是比较高级的用法。他们的核心目的都在于满足需求的同时,减少和其他代码的耦合性和联系性,让一切联系都交由配置文件去完成,符合MVC的风格和要求。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值