天天看点

在Struts2框架中使用注解

       Struts2框架是WEB开发最常用的MVC框架之一,对Struts1作了很大的改进,例如去除了FormBean,屏蔽Servlet API等特征,使用OGNL导航对象图语言,简化了Action和HTML表单的开发工作。我个人觉得Struts2比Spring  MVC要更好用,至少是脱离了Servlet API。

      在项目中使用Struts2框架,首先需要集成该框架,集成Struts2框架有几种方法,一种是不与IOC/DI框架直接集成,一种是与IOC/DI框架集成。目前开源的IOC框架主要有Guice和Spring两种框架,这两个框架都支持与Struts2集成。本文中的示例我们将Struts2和Spring集成。

       首先我们需要提供一个配置文件,我们主要配置struts2的对象实例化工厂、国际化,还有拦截器等。

       配置由Spring实例化Struts2,需要Spring框架的支持

<constant name="struts.objectFactory" value="spring"></constant>
           

       配置国际化编码

<constant name="struts.i18n.encoding" value="UTF-8"></constant>
           

       完整配置如下

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
  <constant name="struts.enable.DynamicMethodInvocation" value="false" />
   <constant name="struts.devMode" value="false" />
   <constant name="struts.objectFactory" value="spring"></constant>
	<!--charset-->
   <constant name="struts.i18n.encoding" value="UTF-8"></constant>
   <!-- convention-plugin  -->
   <constant name="struts.convention.default.parent.package" value="default" />
   <package name="default" extends="struts-default,json-default">
      <interceptors>
      	 <interceptor-stack name="securedStack">
      	 	 <interceptor-ref name="defaultStack" />
      	 </interceptor-stack>
      </interceptors>
      <default-interceptor-ref name="securedStack"></default-interceptor-ref>
      <global-results>
			<result name="error">/error.jsp</result>
			<result name="invalid.token">/error.jsp</result>
			<result name="login" type="redirect">/login</result>
	</global-results>
   </package>
</struts>
           

       编写一个BaseAction类,主要提供分页参数和一些JSON格式转换函数,这样可以在子类中直接应用,而且不用每次都编写转换函数和分页属性。

package com.mcs.core.action;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;

import com.mcs.common.PageBean;
import com.opensymphony.xwork2.ActionSupport;

public class BaseAction<T> extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Resource
	protected PageBean<T> pageBean;

	protected int limit;
	protected int start;

	/**
	 * 将对象转换为BEAN
	 * 
	 * @param clsz
	 * @return
	 */
	public <T extends Object>  T convertJSONToBean(Class<?> clsz) {
		HttpServletRequest request = ServletActionContext.getRequest();
		String json = request.getParameter("data");
		JSONObject jsonObject = JSONObject.fromObject(json);
		return (T) JSONObject.toBean(jsonObject, clsz);
	}

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public int getStart() {
		return start;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public PageBean getPageBean() {
		return pageBean;
	}

	public void setPageBean(PageBean pageBean) {
		this.pageBean = pageBean;
	}
}
           

        还要编写一个pageBean对象,这个对象负责将分页信息和分页后的数据返回给客户端,由客户端的AJAX框架进行处理。使用这个pageBean对象可以直接和Ext JS框架整合,我们不用再刀耕火种的做各种数据格式转换了。

package com.mcs.common;

import java.util.List;

import org.springframework.stereotype.Component;

@Component("pageObject")
public class PageBean<T> {
	private List<T> rows;
	
	private int total;// 总记录数,-1表示未知

	public PageBean() {
	}


	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}


	public List<T> getRows() {
		return rows;
	}


	public void setRows(List<T> rows) {
		this.rows = rows;
	}

}
           

        在struts2中编写一个Action很简单,和编写Java Bean一样,只需要类、属性和方法就可以完一个Action,编写完的Action如果不加配置的话是不起作用的,Action的配置方法有两种,一种是注解的方式,一种是配置文件的方式。在JAVA EE的开发规范中,JAVA主推注解的方式,所以后续出来的各种JAVA框架也都提供了注解配置的支持,JAVA的注解和C#中的特性原理相似,都是通过一些特殊的标注让代码实现某一特定的功能,这样可以大大简化代码量和配置文件的编写。当然注解并不是万能的,注解是一个静态参数,随JAVA代码一起被编译,而配置文件很多则是在程序运行的时候从文件中读取,所以在项目开发过程中,也可以跟据需要适当的使用一些配置文件。

        使用struts2注解需要提供一个struts2的注解插件,这个插件在我们下载过来的开发包里可以找到,如下图:

在Struts2框架中使用注解

        另外还需要一个JSON插件,因为我们在开发过程中大部份的数据传输都是使用JSON传输的,这个插件我们也可以在struts2的开发包中找到,如下图:

在Struts2框架中使用注解

        将这件插件拷到你的WEB-INFO/lib目录下,就可以使用注解了。

        在web.xml中配置Struts2的过滤器

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
           

         下面介绍Struts2的常用注解:

       1、@Action注解用来标注一个方法的URL、返回结果等值,其中value值是该Action的URL,在浏览器中输入该URL则可以访问到这个方法,@Result是返回结果的注解,location则是转发到的具体URL,一般都是一个JSP,当然也可以是HTML。

@Action(value="queryCardType",results={@Result(location="cardType/cardTypeList.jsp")})
           

        2、@Result注解还可以支持JSON类型的参数返回,我们只需要将设置type=”json”,配置params参数即可。其中params中的root是键,pageObject是值,表示该JSON的根节点是从pageObject对象开始转换,pageObject对象是我们定义一个分页对象,用于和前台的Ext JS框架对应。

@Action(value="listCardType",results={@Result(type="json",params={"root","pageObject"})})
           

            pageObject对应的JSON格式数据:

{"rows":[{"cardName":"会员卡","cardNum":"12321","discount":0,"id":"009038ef4c0bd04b014c0c7fc7d70000","maxConsumeSum":300,"maxConsumeTimes":1,"oid":"","remark":"","type":"1","validDays":1,"validMachine":null,"validSetMeal":null,"validTime":"2015-03-12T13:40:43"}],"total":1}
           

        3、@JSON注解用来标注哪些属性不被实例化,这个可以提升页面的响应速度,另外,可以屏蔽其他框架,例如hibernate框架在序列化的时候带来的死循环异常,当然,这个注解不是必需的,我们可以使用params={"root","pageObject"}来代替@JSON注解。        3、@JSON注解用来标注哪些属性不被实例化,这个可以提升页面的响应速度,另外,可以屏蔽其他框架,例如hibernate框架在序列化的时候带来的死循环异常,当然,这个注解不是必需的,我们可以使用params={"root","pageObject"}来代替@JSON注解。

@JSON(serialize=false)//不被序列化
           

         4、@Namespace命名空间注解用来区分不同模块的URL,在一个庞大的开发团队中,很有可能会有URL重名的情况,而加上命名空间后,重名的机率就大大降低了,并且代码结构会更加清晰,所以,大家在开发代码时候尽量加上命名空间的注解。

@Namespace("/basicOperation")
           

        怎么样?是不是很简单,我们只用了少数几个注解就完成了Action的开发工作,当然,我们用其他的MVC框架一样可以完成我们所需要做的事情,但总的来讲,struts2框架是比较成熟的一款MVC框架,安全漏洞也相对较少,MVC框架是网站的安全门户,一旦爆发出安全漏洞,后果不堪设想。因为研究struts2框架漏洞的人很多,struts2团队也在不停的打补丁。完整的Action代码如下:

package com.mcs.basicOperation.action;

import java.util.List;

import javax.annotation.Resource;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.json.annotations.JSON;

import com.mcs.basicOperation.pojo.CardType;
import com.mcs.basicOperation.service.CardTypeService;
import com.mcs.common.PageBean;
import com.mcs.core.action.BaseAction;


@Namespace("/basicOperation")
public class CardTypeAction extends BaseAction<CardType>{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Resource
	private CardTypeService cardTypeService;
	
	@Resource(name="pageObject")
	private PageBean<CardType> pageObject;
	
	@Action(value="queryCardType",results={@Result(location="cardType/cardTypeList.jsp")})
	public String queryCT(){
		return "success";
	}

	@Action(value="listCardType",results={@Result(type="json",params={"root","pageObject"})})
	public String queryListCardType(){
		CardType ct=convertJSONToBean(CardType.class);
		pageObject.setTotal(cardTypeService.findAllCardType(ct));
		List<CardType> rows = cardTypeService.queryCardType(start, limit, ct);
		pageObject.setRows(rows);
		return SUCCESS;
	}
	
	/**
	 * 根据ID查询信息
	 * @param id
	 * @return
	 */
	@Action(value="findCardTypeByid",results={@Result(type="json")})
	public String findCardTypeByid(String id){
		cardTypeService.findCardTypeByid(id);
		return SUCCESS;
	}

	@Action(value="saveCardType",results={@Result(type="json")})
	public String saveCardType(){
		CardType ct=convertJSONToBean(CardType.class);
		cardTypeService.saveCardType(ct);
		return SUCCESS;
	}

	@Action(value="delCardType",results={@Result(type="json")})
	public String delCardType(){
		CardType ct=convertJSONToBean(CardType.class);
		cardTypeService.delCardType(ct);
		return SUCCESS;
	}
	
	@JSON(serialize=false)//不被序列化
	public CardTypeService getCardTypeService() {
		return cardTypeService;
	}

	public void setCardTypeService(CardTypeService cardTypeService) {
		this.cardTypeService = cardTypeService;
	}

	public PageBean<CardType> getPageObject() {
		return pageObject;
	}

	public void setPageObject(PageBean<CardType> pageObject) {
		this.pageObject = pageObject;
	}
	
}

           

         在前台显示数据:

在Struts2框架中使用注解

继续阅读