Java Spring和带有select的表单
我使用Spring在窗体中填充一个项,使用在控制器和视图之间传递的对象: 域对象 控制器Java Spring和带有select的表单,java,spring,data-binding,Java,Spring,Data Binding,我使用Spring在窗体中填充一个项,使用在控制器和视图之间传递的对象: 域对象 控制器 @RequestMapping(method=RequestMethod.GET,value=“/”) 公共字符串索引(m型){ m、 addAttribute(“客户端”,新客户端()); 棒o1=新棒(); o1.设置名称(“n1”); o1.setId(1); 巴o2=新巴(); o2.设定名称(“N2”); o2.setId(2); 棒o3=新棒(); o3.设定名称(“N3”); o3.setId
@RequestMapping(method=RequestMethod.GET,value=“/”)
公共字符串索引(m型){
m、 addAttribute(“客户端”,新客户端());
棒o1=新棒();
o1.设置名称(“n1”);
o1.setId(1);
巴o2=新巴();
o2.设定名称(“N2”);
o2.setId(2);
棒o3=新棒();
o3.设定名称(“N3”);
o3.setId(3);
棒o4=新棒();
o4.集合名(“N4”);
o4.setId(4);
棒o5=新棒();
o5.集合名(“N5”);
o5.setId(5);
列表顺序=新的ArrayList();
订单。添加(o1);
添加(o2);
添加(o3);
订单。添加(o4);
订单。添加(o5);
m、 addAttribute(“订单列表”,订单);
返回“索引”;
}
@RequestMapping(method=RequestMethod.POST,value=“/”)
公共字符串indexPost(@modeldattribute(“Client”)Client g,BindingResult r){
log.info(g.getId()+“”+g.getName());
log.info(g.getBar().getName());
返回“索引”;
}
视图(index.jsp)
名称
身份证件
命令
插入
问题
当我填写表单并提交时,控制器在log.info(g.getBar().getName())上抛出一个NullPointerException代码>
我认为这是因为getBar()返回null
。
此数据绑定的错误在哪里?您正在为模型设置一个新的客户端
对象,但该对象为空。首先尝试创建完整的Client
对象,然后在index()
方法中将其设置为模型
编辑:
因此,您需要为该字段设置属性编辑器。调整并将以下方法添加到控制器:
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Bar.class, "bar", new PropertyEditorSupport(Bar.class) {
@Override
public String getAsText() {
if(null != getValue()) {
return ((Bar) getValue()).getId();
} else {
return StringUtils.EMPTY;
}
}
@Override
public void setAsText(String text) {
if(!StringUtils.isEmpty(text)) {
setValue(UtilityClassUtils.getBarById(text));
}
}
});
}
我认为表单:select
标记没有正确定义。你能试试这个吗
<form:select path="bar">
<form:options items="${ordersList}" itemValue="id" itemLabel="name" />
</form:select>
首先,您的表单只会将所选条的ID发回服务器端。因此,Spring将无法在没有额外工作的情况下自动填充栏的名称字段
其次,为了帮助Spring将ID转换为Bar或Bar转换为ID,您需要将Bar对象存储在某个位置。您可以将该条保存在缓存、会话、数据库或HTML表单的隐藏输入等中。假设我们将该条存储在服务器端,存储界面定义如下:
package com.example;
public interface BarStore {
Bar getBar(Integer id);
void putBar(Bar bar);
}
...
@Autowired
private BarStore barStore;
...
@RequestMapping(method = RequestMethod.GET, value = "/")
public String index(Model m) {
...
barStore.putBar(o1);
barStore.putBar(o2);
barStore.putBar(o3);
barStore.putBar(o4);
barStore.putBar(o5);
...
}
并将条形图对象存储在公共字符串索引(m型)方法中,如下所示:
package com.example;
public interface BarStore {
Bar getBar(Integer id);
void putBar(Bar bar);
}
...
@Autowired
private BarStore barStore;
...
@RequestMapping(method = RequestMethod.GET, value = "/")
public String index(Model m) {
...
barStore.putBar(o1);
barStore.putBar(o2);
barStore.putBar(o3);
barStore.putBar(o4);
barStore.putBar(o5);
...
}
最后,您可以注册一些转换器来将Bar转换为ID,并将ID转换为Bar。以下是一个例子:
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
@Configurable
public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {
@Autowired
private BarStore barStore;
public Converter<Bar, String> getBarToStringConverter() {
return new Converter<Bar, String>() {
public String convert(Bar bar) {
return new StringBuilder().append(bar.getId()).append(' ').append(bar.getName()).toString();
}
};
}
public Converter<Integer, Bar> getIdToBarConverter() {
return new Converter<Integer, Bar>() {
public Bar convert(Integer id) {
return barStore.getBar(id);
}
};
}
public Converter<String, Bar> getStringToBarConverter() {
return new Converter<String, Bar>() {
public Bar convert(String id) {
return getObject().convert(getObject().convert(id, Integer.class), Bar.class);
}
};
}
public void installLabelConverters(FormatterRegistry registry) {
registry.addConverter(getBarToStringConverter());
registry.addConverter(getIdToBarConverter());
registry.addConverter(getStringToBarConverter());
}
public void afterPropertiesSet() {
super.afterPropertiesSet();
installLabelConverters(getObject());
}
}
package.com.example;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.annotation.Configurable;
导入org.springframework.core.convert.converter.converter;
导入org.springframework.format.FormatterRegistry;
导入org.springframework.format.support.FormattingConversionServiceFactoryBean;
@可配置
公共类应用程序转换ServiceFactoryBean扩展格式化转换ServiceFactoryBean{
@自动连线
私人酒吧;
公共转换器getBarToStringConverter(){
返回新转换器(){
公共字符串转换(Bar){
返回新的StringBuilder().append(bar.getId()).append(“”).append(bar.getName()).toString();
}
};
}
公共转换器getIdToBarConverter(){
返回新转换器(){
公共条转换(整数id){
返回barStore.getBar(id);
}
};
}
公共转换器getStringToBarConverter(){
返回新转换器(){
公共条转换(字符串id){
返回getObject().convert(getObject().convert(id,Integer.class),Bar.class);
}
};
}
public void installLabelConverters(FormatterRegistry注册表){
addConverter(getBarToStringConverter());
addConverter(getIdToBarConverter());
addConverter(getStringToBarConverter());
}
公共无效afterPropertiesSet(){
super.afterPropertiesSet();
installLabelConverters(getObject());
}
}
我看不到您在任何地方将“bar”设置为客户端。。。你错过这一点了吗?什么意思?你能举个例子吗?首先,当呈现选择框时,你的值是什么?它是id还是主键?因为,我的意思是,当您将表单发布回服务器时,您必须获取并设置实际的“订单”,或者在您的情况下为您的客户机设置“bar”。在创建客户机
对象的过程中,我缺少了什么?您只需使用m.addAttribute(“client”,new client())创建一个新的客户机
对象代码>但其所有字段均为空。因此,调用g.getBar()将返回null,这就是您获得NPE的原因。对g.getBar()
的调用在@modeldattribute
之后(在post方法中),在代码的这一部分,Spring应该用表单中相应的值填充对象。我明白了,看看我上次的编辑。对于栏
字段,您需要一个属性编辑器。
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
@Configurable
public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean {
@Autowired
private BarStore barStore;
public Converter<Bar, String> getBarToStringConverter() {
return new Converter<Bar, String>() {
public String convert(Bar bar) {
return new StringBuilder().append(bar.getId()).append(' ').append(bar.getName()).toString();
}
};
}
public Converter<Integer, Bar> getIdToBarConverter() {
return new Converter<Integer, Bar>() {
public Bar convert(Integer id) {
return barStore.getBar(id);
}
};
}
public Converter<String, Bar> getStringToBarConverter() {
return new Converter<String, Bar>() {
public Bar convert(String id) {
return getObject().convert(getObject().convert(id, Integer.class), Bar.class);
}
};
}
public void installLabelConverters(FormatterRegistry registry) {
registry.addConverter(getBarToStringConverter());
registry.addConverter(getIdToBarConverter());
registry.addConverter(getStringToBarConverter());
}
public void afterPropertiesSet() {
super.afterPropertiesSet();
installLabelConverters(getObject());
}
}