struts2 形式的抽象类 [英] abstract classes in struts2 forms

查看:26
本文介绍了struts2 形式的抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个表单来创建类型层次结构中的几个子类之一.假设它是带有子类 Employee 和 Visitor 的 AbstractPerson.

I want to have a form that creates one of several subclasses in a type hierarchy. Say it's AbstractPerson with the subclasses Employee and Visitor.

我可以使用单个 Action/REST-Controller Bean 来做到这一点吗?

Can I do that with a single Action / REST-Controller Bean?

通常我使用 form-ids smart,所以它直接为我的 Action 的 setter 赋值.所以如果我有这样的成员

Usually I use the form-ids smart, so it assigns values directly to the setters of my Action. So if I have a member like

AbstractPerson member;

我会尝试使用带有名为member.name"的输入字段的表单.

I would try to use a form with an input field called "member.name".

然而,struts 必须先创建一个 AbstractPerson 的实例——它不能,因为它是抽象的!如果我能给 struts2 一个提示,它实际上应该创建一个 Empolyee 或 Visitor 对象(取决于表单内容),那将是非常酷的.这或类似的可能吗?

However, struts must create an instance of AbstractPerson first - and it can't because it's abstract! It would be very cool if I could give struts2 a hint that it should actually create a Empolyee or Visitor object (depending on the form content). Is that or sth similar possible?

干杯!

推荐答案

这类似于我最近通过一小组 crud 操作访问实体类所做的事情.这是一些 crud 操作,允许您对某个包中的所有实体类进行操作.您应该能够将此策略应用于您的 Employee 和 Visitor 类.

This is similar to something I've done recently to access Entity classes via a small set of crud actions. That is a handful of crud actions allow you to operate on all the entity classes within a certain package. You should be able to apply this strategy to your Employee and Visitor classes.

简而言之它是​​如何工作的:

How it works in a nutshell:

1) 您需要在命名空间或操作名称中指定应创建的类的名称.

1) You need to specify in either the namespace or the action name the name of the class that should be created.

2) 您使用 struts2s 的可准备接口来创建模型.(反射性地创建从步骤 1 中确定的类.

2) You use struts2s prepareable interface to create a model. (Reflectively create the class determined from step 1.

3) 使用模型驱动接口,它返回在步骤 2 中定义的对象.这样该对象位于堆栈顶部,您可以简单地说名称"并知道它是类的名称属性在步骤 1 中确定.您可以避免这一步,但它没有那么漂亮.

3) Use the model driven interface, which returns the object defined in step 2. This way that object is at the top of the stack and you can simply say "name" and know that it is the name attribute of the Class determined in step 1. You could avoid this step but it isn't as pretty.

现在这样做有一个小故障,您会发现要执行上述三个步骤,您需要一个自定义堆栈,即staticParams-prepare-params"堆栈.

Now there is a small glitch in doing this, you'll find that to perform the above three steps you'll need a custom stack, a "staticParams-prepare-params" stack.

首先是一个示例,然后是该堆栈的定义以使其工作,如果您有任何问题,请告诉我:

First an example and then a definition of that stack to make this work, please let me know if you have any questions:

package com.quaternion.demo.action.crud;

import com.quaternion.demo.orm.ActionValidateable;
import com.quaternion.demo.service.CrudService;
import com.quaternion.demo.util.ActionUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;

// Adds a new record to the database
@ParentPackage("staticParams-prepare-parms")
@Namespace("/crud/{entityName}")
@Result(type = "kjson") //TODO: could rid of this line by setting the result as the default for the package
public class AddAction extends ActionSupport implements Preparable, ModelDriven {

    private static final Logger log = Logger.getLogger(AddAction.class.getName());
    @Autowired
    private CrudService crudService;
    private String entityName; 
    private Object entityModel; 
    private Map jsonModel = new HashMap(); //for output, return the newly created object
    private Class clazz;

    @Override
    public String execute() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        log.log(Level.INFO, "In execute entityName is set with {0}", entityName);
        //If an id is passed in it will merge the object with that id, null will be used for unset attributes
        String status = SUCCESS;
        boolean error = false;
        Object entity = null;
        try { 
            entity = crudService.create(clazz, entityModel);
        } catch (Exception e) {
            error = true;
            status = ERROR;
            jsonModel.put("message", e.getMessage());
        }
        if (error == false) {
            jsonModel.put("entity", entity);
        }
        jsonModel.put("status", status);
        return SUCCESS;
    }

    public Object getEntityModel() {
        return entityModel;
    }

    public void setEntityModel(Object entityModel) {
        this.entityModel = entityModel;
    }

    public Object getJsonModel() {
        return jsonModel;
    }

    @Override
    public Object getModel() {
        return this.entityModel;
    }

    @Override
    public void prepare() throws Exception {
        log.log(Level.INFO, "In prepare entityName is set with {0}", entityName);
        clazz = ActionUtils.initClazz(entityName);
        entityModel = clazz.newInstance();
    }

    public String getEntityName() {
        return entityName;
    }

    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }

    //TODO: validation would be a good idea can't implement in this class need to delegate
    //if entity implements a validate method, this validate should
    //call that validate
    @Override
    public void validate(){
        if (entityModel instanceof ActionValidateable){
            ((ActionValidateable)entityModel).validate(this);
        }
    }
}

这里是堆栈的定义:

<package name="staticParams-prepare-parms" extends="struts-default">
    <result-types>
        <result-type name="kjson" default="true" class="com.quaternion.demo.result.Kjson"/>
    </result-types>
    <interceptors>
        <interceptor-stack name="staticParamsPrepareParamsStack">
            <interceptor-ref name="exception"/>
            <interceptor-ref name="alias"/>
            <interceptor-ref name="i18n"/>
            <interceptor-ref name="checkbox"/>
            <interceptor-ref name="multiselect"/>
            <interceptor-ref name="staticParams"/>
            <interceptor-ref name="actionMappingParams"/>
            <interceptor-ref name="servletConfig"/>
            <interceptor-ref name="prepare"/>
            <interceptor-ref name="chain"/>
            <interceptor-ref name="modelDriven"/>
            <interceptor-ref name="fileUpload"/>
            <interceptor-ref name="staticParams"/>
            <interceptor-ref name="actionMappingParams"/>
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
            </interceptor-ref>
            <interceptor-ref name="conversionError"/>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
        </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="staticParamsPrepareParamsStack"/>
</package> 

您可能想知道 kjson 结果类型是什么.我对 struts2-json 插件的其他几个操作感到挑战.我创建了一个通用的分页和读取操作,默认情况下flexjson"不会序列化集合,这可以防止延迟加载问题(如果集合未加载,这些简单服务总是如此)所以 kjson 只是一个使用 flexjson 返回 json 的结果类型.

You might wonder what the kjson result type is. I was feeling challenged by the struts2-json plugin on several other actions. I created a generic paging and read actions, "flexjson" does not serialize collections by default, which prevents lazy loading issue (well in the case the collections were not loaded which will always be the case with these simple services) so kjson is just a result type which returns json using flexjson.

这篇关于struts2 形式的抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆