SpringMVC 3 转换<表单:复选框..>返回字符串[]到实体对象



我有一个与Campaign cities城市有OneToOne关系的Entity Campaign。反过来,CampaignCities包含一组城市;

战役实体

    @Entity 
    @javax.persistence.Table(uniqueConstraints={@UniqueConstraint(columnNames={"name","company_id"}), @UniqueConstraint(columnNames={"id"})})
    public class Campaign implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private Long id;
        @NotEmpty
        @Size(min=1, max=100)
        private String name;
        private Date startDate;
        private Date endDate;
        @Valid
        private Deal deal;
        @Valid
        private Company company;
        @OneToOne
        private CampaignCities cities = new CampaignCities();

CampaignCities实体

@Entity
public class CampaignCities {
    private long id;
    private Set<City> cities = new HashSet<City>();
    @Id
    @javax.persistence.GeneratedValue(strategy=GenerationType.AUTO)
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @OneToMany
    public Set<City> getCities() {
        return cities;
    }
    public void setCities(Set<City> cities) {
        this.cities = cities;
    }
}

城市实体:

@Entity
public class City implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String name;
    private Long id;
    @javax.persistence.Id
    @javax.persistence.GeneratedValue(strategy=GenerationType.AUTO)
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
我NewCampaignController

@SessionAttributes(value={"campaign", "campaignCities"})
@Controller
public class NewCampaignController {
    //private static final Logger logger = LoggerFactory.getLogger(NewDealController.class);
    @Autowired
    private CampaignManager campaignManager;
    @Autowired
    private CityManager cityManager;
    @Autowired
    SimpleDateFormat dateFormat;
    @Autowired
    CustomDateEditor dateEditor;
    @RequestMapping(value = "campaign/new", method = RequestMethod.GET)
    public String showForm(Map<String, Object> model) {
        //List<Campaign> campaigns = campaignManager.getCampaigns();
        Campaign campaignForm = new Campaign();
        CampaignCities cities = new CampaignCities();
        cities.setCities(new HashSet<City>(cityManager.getCity()));
        //campaignForm.setCities(cities);
        model.put("campaignCities", cities);
        model.put("campaign", campaignForm);
        return "campaign/new";
    }
    @RequestMapping(value = "campaign/new", method = RequestMethod.POST)
    public String processForm(@Valid Campaign campaignForm, BindingResult result, Map<String,Object> model) {
        new CampaignValidator().validate(campaignForm, result);
        if (result.hasErrors()) {
            return "campaign/new";
        }
        this.campaignManager.saveCampaign(campaignForm);
        model.put("campaign", campaignForm);
        model.put("campaigns", this.campaignManager.getCampaigns());
        return "campaign/added";
    }

我已经能够让活动渲染在一个形式,我已经渲染的城市列表成功使用:

<form:checkboxes items="${campaignCities.cities}" path="cities" itemLabel="name" itemValue="id" delimiter="<br/>" />

但是,当我提交表单时,我得到以下验证错误:

对象"campaign"在字段"cities"上出现字段错误:拒绝值(2, 1);代码[typeMismatch.campaign.cities, typeMismatch.cities typeMismatch.com.groupdealclone.app.domain.CampaignCities typeMismatch);参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码(campaign.cities、城市);参数[];默认消息(城市)];default message[转换类型属性值失败。. lang。字符串[]'为所需的类型"com.groupdealclone.app.domain。"城市运动"为房地产"城市";嵌套异常是java.lang.IllegalStateException: Cannot convert类型的值[java.lang.]字符串[]]需要的类型[com.groupdealclone.app.domain。房地产"城市":没有找到匹配的编辑器或转换策略]

我试图找出一种方法来处理这个在SpringMVC 3,但我已经卡住了超过一天没有成功。我只是想要一个列表或设置或城市,在表单上被选中,提交给控制器,并添加到活动。如何解决转换问题,我可以将返回的String[]转换为城市列表或集合。

我正在工作的项目是一个公共GitHub项目,你可以下载源代码并使用Maven设置它,如果你喜欢这个项目被称为Group-Deal-Clone

差不多2天后,答案比我想象的要简单。多亏了这个帖子,我找到了答案。

在我的NewCampaignController中我做了:

@InitBinder
public void initBinder(WebDataBinder binder) {
    dateFormat.setLenient(false);
    binder.registerCustomEditor(Date.class, dateEditor);
    binder.registerCustomEditor(CampaignCities.class, "cities", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            String [] ids = text.split(",");
            CampaignCities cities = null;
            for(String id:ids){
                if(cities == null)
                    cities = new CampaignCities();
                City city = cityManager.getCity(new Long(id));
                if(city != null)
                    cities.getCities().add(city);
            }
            if(cities != null){
                cities.setId(null);
                setValue(cities);
            }
        }
    });

最新更新