zoukankan      html  css  js  c++  java
  • struts2进阶篇(2)

    一、Action与MVC

    struts2是一个基于MVC的web应用框架,它将应用程序分为三个组件:模型,视图,控制器。

    模型:包含了应用程序的业务逻辑和业务数据,由封装数据和处理业务的javaBean组成。

    视图:封装了应用程序的输出形式,也就是页面,如jsp,html。

    控制器:负责接收用户的http请求,再调用模型中响应的方法来处理业务,然后调用响应的视图作为显示。

    三者共同协同处理响应客户端的请求。

    在struts2中控制器分为两部分:

    1.核心控制器:它就是在web.xml中配置的StrutsPrepareAndExecuteFilter负责过滤用户的所有请求,根据请求不同,分发不同的Action处理。

    2.业务控制器:也就是Action,负责调用模型来实现请求的业务,并把结果交给视图层。

    二、Action接收参数

    在action中接收用户从jsp传入的参数有三种方式:

    1.属性方式

    2.JavaBean方式

    3.ModelDriven方式

    (1).属性方式:

    package action;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.apache.struts2.ServletActionContext;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class UserAction extends ActionSupport {
    	private String username;
    	private String password;
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	/**
    	 * 业务逻辑层
    	 */
    
    	public String login() {
    
    		Map<String, Object> map = new HashMap<String, Object>();
    		boolean isLogin = (Boolean) map.get("isLogin");
    		if (isLogin) {
    			// 登录成功
    			// session==>>>>>>>>>>>>
    			/**
    			 * 得到一个Map对象,相当于jsp中的内置对象session 解耦方式
    			 */
    			/*
    			 * Map<String,Object>
    			 * session=ActionContext.getContext().getSession();
    			 * session.put("user", map.get("user"));
    			 */
    			/**
    			 * 耦合方式
    			 */
    			// ServletContext
    			// sc=ServletActionContext.getServletContext();//得到Servlet上下文
    			HttpServletRequest request = ServletActionContext.getRequest();
    			HttpServletResponse response = ServletActionContext.getResponse();
    			HttpSession session = request.getSession();
    			session.setAttribute("user", map.get("user"));
    			return SUCCESS;
    		} else {
    			return INPUT;
    		}
    	}
    
    }
    

    login.jsp页面定义form表单:

    <form action="login" method="post">
      		用户名:<input name="username"/>
      		密码:<input name="password"/>
      		<input type="submit" value="提交"/>
      		<input type="reset" value="重置"/>
    </form>
    

    说明:

    1.在form表单中的用户名和密码的<input>标签中的name属性username和password,和action中的定义的成员变量username和password形同,在提交表单时struts会把值赋为形同的字段名。

    2.如果上传的包含中文,则action接收可能存在乱码,可以修改struts.xml文件,添加<constant name="struts.i18n.encoding" value="utf-8">

    二、JavaBean的方式

    1、定义User对象实体类,并添加username,password和相应的get,set方法

    package entity;
    
    public class User {
    	private String username;
    	private String password;
    	public String getUsername() {
    		return username;
    	}
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	public String getPassword() {
    		return password;
    	}
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	
    
    }
    

    2.添加JavaBean的action,添加User类型的成员变量user,和get,set方法,execute()方法

    package action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import entity.User;
    
    public class UserActionByJavaBean extends ActionSupport {
    	private User user;
    
    	@Override
    	public String execute() throws Exception {
    		return "success";
    	}
    
    	public User getUser() {
    		return user;
    	}
    
    	public void setUser(User user) {
    		this.user = user;
    	}
    	
    
    }
    

    3.form表单中添加页面代码:

    <form action="login" method="post">
      		用户名:<input name="user.username"/>
      		密码:<input name="user.password"/>
      		<input type="submit" value="提交"/>
      		<input type="reset" value="重置"/>
    </form>
    

    说明:

    1.在提交form表单时会将属性值通过User实体属性传递给Action,但必须保持前后属性的一致性。

    2.在jsp页面中,可以实用<s:property value ="user.username"/>输出Action中的user对象的username属性的值。

    三、ModelDriven方式接收参数

    在action中实现ModelDriven接口来接收客户端上传的参数,这种方式任然需要实体User。

    它的运行过程是:Struts2调用ModelDriven接口中的getModel()方法取得Action中的user对象,再把上传的用户名密码存入user对象。

    package action;
    
    import com.opensymphony.xwork2.ModelDriven;
    
    import entity.User;
    
    public class UserActionByModelDriven implements ModelDriven {
    	private User user = new User();
    
    	@Override
    	public Object getModel() {
    		return null;
    	}
    	public String execute(){
    		return "success";
    	}
    
    }
    

    UserAction类中的User对象用来接收用户名,密码。getModel()是ModelDriven接口中定义的方法,它提供了类对外user对象的访问。

    <form action="login" method="post">
      		用户名:<input name="username"/>
      		密码:<input name="password"/>
      		<input type="submit" value="提交"/>
      		<input type="reset" value="重置"/>
    </form>
    

    说明:

    1.使用ModelDriven方式接收页面参数,name属性不需要添加对象,name="username";

    三、Struts.xml中<action>标签中method属性的用法

    1.在<action>的配置代码中method属性默认调用action类的execute()方法,但是在实际应用中一个action需要处理很多方法,就可以添加method="不同的方法名"来调用acton中对应的方法。

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    		<constant name="struts.devMode" value="true" />
    		<constant name="struts.i18n.encoding" value="utf-8" />
        <package name="default" namespace="/" extends="struts-default">
    		
    	<action name="login" class="action.UserAction" method="login">
    		<result type="chain">all</result>
    		<result name="input">login.jsp</result>
    	</action>
    	
    	<action name="all" class="action.DeptAction" method="getDept">
    		<result>list.jsp</result>
    	</action>
    
        </package>
    </struts>
    

      上面<action>标签中定义method='login'和method='getDept'方法,就会请求Action类中方法名为login和getDept的方法。

    2.动态方法调用

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    		<constant name="struts.devMode" value="true" />
    		<constant name="struts.i18n.encoding" value="utf-8" />
        <package name="default" namespace="/" extends="struts-default">
    	
        <action name="all" class="action.DeptAction">
    		<result>list.jsp</result>
    	</action>
        </package>
    </struts>
        
    

      不难发现上面的方法并没有指定具体调用哪个方法,这是应为在下面的form表单中指定。

    <form action="login!getAllDept" method="post">
      		用户名:<input name="user.username"/>
      		密码:<input name="user.password"/>
      		<input type="submit" value="提交"/>
      		<input type="reset" value="重置"/>
    </form>
    

      在form表单中的action="login!getAllDept"会调用Action类中的getAllDept方法。

    不难发现动态调用的语法是:actionName !methodName.action,其中.action可以省略,但是值得注意的是,动态方法调用可能会带了安全隐患,暴露业务方法给用户,官方也不推荐这样用,不过可以在struts.xml中添加<constant name="struts.enable.DynamicMethodInvocation" value="false"/>来禁用动态方法调用。

    四、使用通配符简化struts.xml中<action>标签的配置

    1.在<action>中使用通配符简化配置

    struts.xml中配置:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    		<constant name="struts.devMode" value="true" />
    		<constant name="struts.i18n.encoding" value="utf-8" />
        <package name="default" namespace="/" extends="struts-default">
    		<!-- 定义默认拦截器 -->
    		<default-interceptor-ref name="myDefault"/>	
                     <action name="index">
    		        <result>index.jsp</result>
    	          </action>
    	<action name="host_*" class="action.HouseAction" method="{1}">
    		<result>list_{1}.jsp</result>
    	</action>
    
        </package>
    </struts>
    

      以上的配置在jsp页面的<form action="house_add"></form>或者<form action="house_update"></form>都会得到响应的请求,也就是action属性是house_任意字符都会得到请求,返回result中的list_任意字符的jsp页面,也就是house_后面的字符和{1}是一样的匹配。

    问题:当有多个<action>匹配的时候会匹配哪个?

    假如有下配置会匹配哪个呢:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    	
    		
    	<action name="house_add" class="action.HouseAction" method="add">
    		<result name="success">add.jsp</result>
    	</action>
    	
    	<action name="house_*" class="action.HouseAction" method={1}>
    		<result>{1}.jsp</result>
    	</action>
        </package>
    </struts>
    

      答案:如果有完全匹配的就优先使用完全匹配的,没有完全匹配的使用通配符匹配,如果有多个通配符匹配的,按照先后顺序优先使用在前的匹配。

  • 相关阅读:
    小总结下iphone开发环境搭建过程!
    Raspberry Pi之旅 【序】
    linux虚拟机中配置samba的实现文件共享的方法
    编写高质量的代码1尽量使用StringBuilder
    ArcEngine开发点滴1
    开源Firebird .NET Provider V0.9.0.0发布
    .NET的Ant构建系统 NAnt 0.91发布!
    iis7.5 发布rest服务,put请求返回404错误 解决方法
    COM学习笔记(1)
    2004年南京美食地图 [转载]
  • 原文地址:https://www.cnblogs.com/ablejava/p/5656042.html
Copyright © 2011-2022 走看看