Spring MVC Multiselect,选择的值在保存时不会返回

时间:2014-10-08 10:57:59

标签: java spring spring-mvc java-ee jsp-tags

您能看到保存时所选值不会返回的原因是什么?

JSP

<form:select class="multiselect" multiple="true" path="conversionPixels">
        <form:options path="conversionPixels" items="${CONVERSION_PIXELS.getItems()}" itemValue="uniqueCode" itemLabel="displayName" /> 
</form:select>

MVC的控制器类,显示此处的保存方法

@Controller
public class EditController extends BaseController {
    @RequestMapping(method = RequestMethod.POST, value = "/edit/save.htm")
    public RedirectView save(@ModelAttribute("package") Package package,
        BindingResult bindingResult, RedirectAttributes redirectAttributes,
        HttpSession session) {

        if (!bindingResult.hasErrors()) {
            if(package.getConversionPixels()!=null){
                for (Object o : package.getConversionPixels()) {
                    logger.debug("*****************EditController Save other type "+o.getClass());
                    WadConversionPixels w=  (WadConversionPixels)o;
                    logger.debug("****************** w.getId()"+w.getId());
                    logger.debug("****************** w.getConversionPixel().getId()"+w.getConversionPixel().getId());
                }
            }
        } else {
            ErrorMessageCollector errors = new BindValidateErrorCollector(
                    bindingResult);
            MessageDisplayHelper.addDisplayMessagesToRedirect(errors,
                    redirectAttributes);
            return new RedirectView("/edit/display.htm", true);
        }
    }



    @InitBinder
    public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(String.class, new TextPropertyEditor());
    binder.registerCustomEditor(CostMethodLookupItem.class, new LookupItemPropertyEditor(CostMethodLookupTableCode.COST_METHOD, lookupTableService));
    //binder.registerCustomEditor(ConversionPixelsLookupItem.class, new LookupItemPropertyEditor(ConversionPixelsLookupTableCode.CONVERSION_PIXELS, lookupTableService));
    //binder.registerCustomEditor(ConversionPixelsLookupItem.class, new LookupItemPropertyEditor(ConversionPixelLookupTableCode.CONVERSION_PIXEL, lookupTableService));
    binder.setDisallowedFields(new String[] {"conversionPixels"});
    binder.registerCustomEditor(Set.class, "conversionPixels",
        new CustomCollectionEditor(Set.class) {
            protected Object convertElement(Object element) {
                if (element instanceof ConversionPixelsLookupItem) {
                    System.out
                            .println("Converting from ConversionPixelsLookupItem to WadConversionPixels: "
                                    + element);
                    WadConversionPixels wadConPixel = new WadConversionPixels();
                    wadConPixel
                            .setConversionPixel((ConversionPixelsLookupItem) element);
                    return ((ConversionPixelsLookupItem) element)
                            .getUniqueCode();
                }
                if (element instanceof WadConversionPixels) {
                    System.out
                            .println("Converting from WadConversionPixels to WadConversionPixels: "
                                    + element);
                    return element;
                }

                if (element instanceof String) {
                    String lookupCode = (String) element;
                    ConversionPixelsLookupItem item = (ConversionPixelsLookupItem) lookupTableService
                            .readLookupTable(
                                    ConversionPixelsLookupTableCode.CONVERSION_PIXELS)
                            .findLookupItemForCode(lookupCode);
                    WadConversionPixels wadConPixel = new WadConversionPixels();
                    wadConPixel.setConversionPixel(item);
                    System.out.println("Looking up staff for id "
                            + lookupCode + ": " + item);
                    return (String) element;// wadConPixel;
                }
                System.out.println("Don't know what to do with: "
                        + element);
                return null;
            }

        });
    }
}

模型类,共有三个类供您参考

@Entity
@Table(name = "Ad_Packages")
@SequenceGenerator(name = "Package_id_seq", sequenceName = "AD_PACKAGE_SEQ", allocationSize = 1)
public class Package extends TransactionalEntity {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Package_id_seq")
    @Column(name = "Ad_Package_ID")
    private Integer id;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "package", orphanRemoval = true)
    private Set<WadConversionPixels> conversionPixels;

    public Set<WadConversionPixels> getConversionPixels() {
        return conversionPixels;
    }

    public void setConversionPixels(Set<WadConversionPixels> conversionPixels) {
        this.conversionPixels = conversionPixels;
    }

}


@Entity
@Table(name = "Ad_Package_Actions")
@SequenceGenerator(name = "wad_package_action_id_seq", sequenceName = "AD_PACKAGE_ACTION_SEQ", allocationSize = 1)
public class WadConversionPixels  {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "wad_package_action_id_seq")
    @Column(name = "AD_PACKAGE_ACTION_ID")
    private Integer id; 

    @JoinColumn(name = "AD_PACKAGE_ID", referencedColumnName = "AD_PACKAGE_ID")
    @ManyToOne(fetch = FetchType.LAZY, optional = false )
    private Package package;

    @ManyToOne(optional = false)
    @JoinColumn(name = "CONVERSION_PIXEL_ID", nullable = false)
    private ConversionPixelsLookupItem conversionPixel;

    public Package getPackage() {
        return package;
    }

    public void setPackage(Package package) {
        this.package = package;
    }

    public ConversionPixelsLookupItem getConversionPixel() {
        return conversionPixel;
    }

    public void setConversionPixel(ConversionPixelsLookupItem conversionPixel) {
        this.conversionPixel = conversionPixel;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    }


@Entity
@Table(name = "PIXELS")
public class ConversionPixelsLookupItem implements LookupItem {

    public ConversionPixelsLookupItem() {};

    public ConversionPixelsLookupItem(String uniqueCode, String displayName) {
        this.uniqueCode = uniqueCode;
        this.displayName = displayName;
    }

    @SuppressWarnings("unused")
    @Id
    @Column(name = "CONVERSION_PIXEL_ID")
    private Integer id;

    @Column(name="CONVERSION_PIXEL_DESCRIPTION", insertable = false, updatable = false)
    private String uniqueCode;

    @Column(name="CONVERSION_PIXEL_DESCRIPTION", insertable = false, updatable = false)
    private String displayName;

    @Type(type = "yes_no")
    @Column(name = "IS_ACTIVE")
    private boolean active;

    @Column(name = "Product_Line_Code")
    private String prodLine;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProdLine() {
        return prodLine;
    }

    public void setProdLine(String prodLine) {
        this.prodLine = prodLine;
    }

    public String getUniqueCode() {
        return uniqueCode;
    }

    public void setUniqueCode(String uniqueCode) {
        this.uniqueCode = uniqueCode;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

}

1 个答案:

答案 0 :(得分:0)

您需要创建转换服务并使用以下命令将其设置为使用MVC

 <annotation-driven validator="validator" conversionService = "conversionService" />

有关转换类,请参阅第7.5节:

http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/validation.html

编辑:

有关详细信息,请参阅链接 - 第7.5节 - 这是摘录:

用于实现类型转换逻辑的SPI简单且强类型化:

package org.springframework.core.convert.converter;

public interface Converter<S, T> {

    T convert(S source);

}

要创建自己的Converter,只需实现上面的界面即可。将S作为要转换的类型参数化,将T作为要转换的类型。对于每次转换(S)的调用,源参数保证为非null。如果转换失败,您的Converter可能会抛出任何异常。应抛出IllegalArgumentException以报告无效的源值。注意确保您的Converter实现是线程安全的。 为方便起见,core.convert.support包中提供了几个转换器实现。这些包括从字符串到数字的转换器和其他常见类型。将StringToInteger视为示例转换器实现:

package org.springframework.core.convert.support;

    final class StringToInteger implements Converter<String, Integer> {

        public Integer convert(String source) {
            return Integer.valueOf(source);
        }

    }