@ParentPackage("default")
@Namespace("/")
@Scope("prototype")
public class BaseAction extends ActionSupport {
private static final long serialVersionUID = 5468737591027540687L;
/**
* 将对象转换成JSON字符串,并响应回前台()
*
* @param object
* @throws IOException
*/
public void writeJson(Object object) {
try {
String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm");
ServletActionContext.getRequest().getSession();
ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
ServletActionContext.getResponse().getWriter().write(json);
ServletActionContext.getResponse().getWriter().flush();
ServletActionContext.getResponse().getWriter().close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param object
*/
public void writeJsonOut(Object object){
OutputStream outputStream=null;
String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm");
ServletActionContext.getRequest().getSession();
ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
HttpServletResponse response = ServletActionContext.getResponse();
byte[] jsonby;
try {
jsonby = json.toString().getBytes("utf-8");
response.setContentLength(jsonby.length);
outputStream=response.getOutputStream();
outputStream.write(jsonby);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 参数是已经封装好的json集合
* @param map
*/
public void writeJson(Map<String, Object>map) {
OutputStream outputStream=null;
try {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
request.setCharacterEncoding("UTF-8");
response.setContentType("text/json;charset=utf-8");
request.getSession();
byte[] jsonby=map.toString().getBytes("utf-8");
response.setContentLength(jsonby.length);
outputStream=response.getOutputStream();
outputStream.write(jsonby);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
if (outputStream!=null) {
try {
outputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
struts中的action一般都是继承ActionSupport的,只是里面增加一些公用的属性和方法,例如获取httpRequest,又比如获取用户信息的方法,完全是自己封装的。
这样做避免每个action甚至每个方法都要写这些,增加了代码的复用性。
web项目中对Action层进行公共方法的抽取放入到BaseAction中:
在项目启动的时候,struts过滤器已经把jsp常用内置对象和map集合存入到了ActionContext和值栈(ValueStack)中。如果实现了XXXAware接口,就会从相应的ActionContext中获取对应的map进行传入(通过拦截器实现: servletConfig 这个拦截器是在struts-default.xml中配置的)
if(action instanceof RequestAware){
((RequestAware)action).setRequest((Map)context.get("request")) ;
}
if(action instanceof SessionAware){
((SessionAware)action).setSession(context.getSession()) ;
}
if(action instanceof ApplicationAware){
((ApplicationAware)action).setApplication(context.getApplication()) ;
}
2.CategoryAction.java中的Category赋值方式:显示层页面通过拦截器然后由OGNL表达式实现值的注入的下面进行具体步骤的分析。
在CategoryAction.java中定义一个语句,使其显示值栈中的栈顶内容或根节点内容
CategoryAction.java
public String query(){
System.out.println(ActionContext.getContext().getValueStack().getRoot());
}
3.让CategoryAction实现数据模型驱动接口
public class CategoryAction extends BaseAction implements ModelDriven{
public Object getModel() {
//它会把得到的值压入栈顶中(删除category对象的setter、getter方法)
Category category = new Category() ;
return category;
}
public String update(){
System.out.println(ActionContext.getContext().getValueStack().getRoot());
System.out.println("==update==") ;
System.out.println(categoryService) ; //如果还没有与spring整合,所以输出为null
System.out.println(category) ;
// categoryService.update(category);
return "index" ;
}
}
----------
index.jsp
<a href="${pageContext.request.contextPath}/category_update.action?id=1&type=儿童休闲&hot=false">ModelDriven驱动程序测试</a>
----------
如果修改action
CategoryAction.java
private Integer id ;
private Integer id1 ;
public void setId1(Integer id1) {
this.id1 = id1;
}
public String update(){
System.out.println(ActionContext.getContext().getValueStack().getRoot());
System.out.println("==update==") ;
System.out.println(category) ;
System.out.println(id) ;
System.out.println(id1) ;
return "index" ;
}
index.jsp
<a href="${pageContext.request.contextPath}/category_update.action?id=1&type=儿童休闲&hot=false&id1=123">ModelDriven驱动程序测试</a>
此时id=null, id1=123
ModelDriven 同样是通过拦截器(ModelDrivenInterceptor)实现的
ModelDrivenInterceptor.java
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
if (action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;
ValueStack stack = invocation.getStack();
Object model = modelDriven.getModel();
if (model != null) {
stack.push(model);
}
}
return invocation.invoke();
}
4.moderDriven是所有的action都可以使用的,所以可以把modelDriven放到baseAction中去同时要使用到泛型
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {
protected T model ;
public T getModel() {
ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass() ;
Class clazz = (Class)type.getActualTypeArguments()[0] ;
try {
model = (T)clazz.newInstance() ;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return model;
}
}
5.然后在简化CategoryAction.java,这样就只剩下service层的类对象了。
CategoryAction.java
public class CategoryAction extends BaseAction<Category>{
private CategoryService categoryService ;
public void setCategoryService(CategoryService categoryService){
this.categoryService = categoryService ;
}
public String update(){
System.out.println(ActionContext.getContext().getValueStack().getRoot());
System.out.println("==update==") ;
System.out.println(model) ;
return "index" ;
}
public String save(){
System.out.println("==save==") ;
System.out.println(categoryService) ; //如果还没有与spring整合,所以输出为null
return "index" ;
}
public String query(){
System.out.println(ActionContext.getContext().getValueStack().getRoot());
request.put("categoryList", categoryService.query()) ;
session.put("categoryList", categoryService.query()) ;
application.put("categoryList", categoryService.query()) ;
return "index" ;
}
}
BaseAction.java
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {
protected Map<String,Object> request ;
protected Map<String,Object> session ;
protected Map<String,Object> application ;
//以下都是通过ActionContex传递过来的
public void setApplication(Map<String, Object> application) {
this.application = application ;
}
public void setSession(Map<String, Object> session) {
this.session = session ;
}
public void setRequest(Map<String, Object> request) {
this.request = request ;
}
protected T model ;
public T getModel() {
ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass() ;
Class clazz = (Class)type.getActualTypeArguments()[0] ;
try {
model = (T)clazz.newInstance() ;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return model;
}
}
- 为了进一步简化,现在连CategoryAction中的service也放到baseAction中去。
protected CategoryService categoryService ;
protected AccountService accountService;
public void setAccountService(AccountService accountService){
this.accountService = accountService ;
}
public void setCategoryService(CategoryService categoryService){
this.categoryService = categoryService ;
}
为了实现在baseAction中依赖spring注入,需要配置
applicationContext-action.xml
<bean id="categoryAction" class="cn.it.shop.action.CategoryAction" scope="prototype" parent="baseAction"/>
<bean id="baseAction" class="cn.it.shop.action.BaseAction" scope="prototype">
<property name="categoryService" ref="categoryService"/>
<property name="accountService" ref="accountService"/>
</bean>
BaseAction定义好之后现在定义其他action实现类就变得简单了,下面定义
AccountAction.java
public class AccountAction extends BaseAction<Account>{
public String query(){
System.out.println(model);
return "index" ;
}
}
定义
index.jsp
<a href="account_query.action?id=10&login=zz">account</a>
<br>
${id }<br>${login }<br>${name}<br>${pass }<br>
然后定义struts的配置文件
struts.xml
<action name="account_*" class="accountAction" method="{1}">
<result name="index">/index.jsp</result>
</action>
然后再定义spring的配置文件
applicationContext-action.xml
<bean id="accountAction" class="cn.it.shop.action.AccountAction" scope="prototype" parent="baseAction"/>