0

コントローラーとビューの間でオブジェクトを渡すことを使用して、Spring を使用してフォームにアイテムを入力しています。

ドメイン オブジェクト

public class Client {
private String name;
private int id;
private Bar bar;
// getters and setters omitted
}


public class Bar {
private Integer id;
private String name;
// getters and setters omitted

}

コントローラ

@RequestMapping(method = RequestMethod.GET, value = "/")
public String index(Model m) {
m.addAttribute("Client", new Client());
Bar o1 = new Bar();
o1.setName("n 1");
o1.setId(1);
Bar o2 = new Bar();
o2.setName("n 2");
o2.setId(2);
Bar o3 = new Bar();
o3.setName("n 3");
o3.setId(3);
Bar o4 = new Bar();
o4.setName("n 4");
o4.setId(4);
Bar o5 = new Bar();
o5.setName("n 5");
o5.setId(5);
List<Bar> orders = new ArrayList<Bar>();
orders.add(o1);
orders.add(o2);
orders.add(o3);
orders.add(o4);
orders.add(o5);
m.addAttribute("ordersList", orders);
return "index";
}

@RequestMapping(method = RequestMethod.POST, value = "/")
public String indexPost(@ModelAttribute("Client") Client g, BindingResult r) {
log.info(g.getId() + " " + g.getName());
log.info(g.getBar().getName());
return "index";
}

ビュー (index.jsp)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form:form method="POST" modelAttribute="Client">
<form:label path="name">Name</form:label>
<form:input path="name" />
<form:label path="id">Id</form:label>
<form:input path="id" />
<form:label path="orders">Order</form:label>
<form:select path="bar" items="${ordersList}" />    
<form:button>Insert</form:button>
</form:form>
</body>
</html>

問題

フォームに入力して送信すると、コントローラーは NullPointerException をスローしlog.info(g.getBar().getName()); ますnull。このデータバインディングのどこが間違っていますか?

4

3 に答える 3

1

モデルに新しいClientオブジェクトを設定しようとしていますが、そのオブジェクトは空です。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));
            }
        }
    });
}
于 2013-01-02T20:24:09.957 に答える
0

まず、フォームは選択したバーの ID のみをサーバー側にポストします。そのため、Spring は、追加作業なしでは Bar の name フィールドを自動的に埋めることができません。

次に、Spring が ID を Bar または Bar を ID に変換できるようにするには、Bar オブジェクトをどこかに保存する必要があります。バーは、キャッシュ、セッション、データベース、または HTML フォームの非表示の入力などに保存できます。バーをサーバー側に保存し、ストアのインターフェースが次のように定義されているとします。

package com.example;

public interface BarStore {

    Bar getBar(Integer id);

    void putBar(Bar bar);

}

以下のように Bar オブジェクトを public String index(Model m) メソッドに保存します。

...
@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());
    }

}
于 2013-01-03T06:43:10.680 に答える
0

form:selectタグが適切に定義されていないと思います。これを試すことができますか?

 <form:select path="bar"> 
  <form:options items="${ordersList}" itemValue="id" itemLabel="name" />
 </form:select>
于 2013-01-02T20:39:18.323 に答える