[スプリングコア]3データバインド抽象
PropertyEditor
(最も古典的なデータバインド方法を表示)
main\java\me\jinmin\Event
package me.jinmin;
public class Event {
private Integer id;
private String title;
public Event(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Event{" +
"id=" + id +
", title='" + title + '\'' +
'}';
}
}
main\java\me\jinmin\EventController
package me.jinmin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EventController {
@GetMapping("/event/{evnet}")
public String getEvent(@PathVariable Event event){
System.out.println(event);
return event.getId().toString();
}
}
{event}
:イベントのid入力した数値タイプのidをイベントタイプ(ドメインタイプ)に変換し、スプリングで受信する必要があります.
❗Test (Spring boot WebMvc Test)
MockMvc:WebApp.スプリングMVC動作をサーバに配備せずに再生する.
必要な依存性のテスト
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
test\java\me\jinmin\EventControllerTest
package me.jinmin;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void getTest() throws Exception {
mockMvc.perform(get("/event/1"))
.andExpect(status().isOk())
.andExpect(content().string("1"));
}
}
結果:エラー
main\java\me\jinmin\EventEditor
package me.jinmin;
import java.beans.PropertyEditorSupport;
public class EventEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
Event event = (Event) getValue();
return event.getId().toString();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(new Event(Integer.parseInt(text));
}
}
共有するValueは、PropertyEditorが所有する値です.♥(重要)この値は異なるスレッドに共有され、状態は完全→Non-Thread-Safeです.→実装体を複数のスレッドで共有することはできません.(=beanとして登録できません.)
では、登録しないで空にして、どうやって使いますか?◇
EventController
にてDataBinderの実装体を実現する.package me.jinmin;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EventController {
@InitBinder
public void init(WebDataBinder webDataBinder){
webDataBinder.registerCustomEditor(Event.class, new EventEditor());
}
@GetMapping("/event/{evnet}")
public String getEvent(@PathVariable Event event){
System.out.println(event);
return event.getId().toString();
}
}
test\java\me\jinmin\EventControllerTest
駆動結果.print:
Event{id=1, title='null'}
💜n/a.結論💜,
Controller
が任意の要求を処理する前に、データバインド@InitBinder
public void init(WebDataBinder webDataBinder){
webDataBinder.registerCustomEditor(Event.class, new EventEditor());
}
メソッドの
PropertyEditor(WebDataBinder)
を使用して、Editor
から受信したValue값
(=文字列の1)を数値に変換し、Eventオブジェクトに変換します.テストに問題はありません.欠点:オブジェクトとStringの間でのみ変換できます(ほとんどの場合、非常に注意して使用します).
Converter & Formatter
Converter
Conレガシー:ソースタイプをTタイプに変換する非常に一般的な変換器です.
ステータス情報なし=ステータスなし=Thread-Safe
Thread-Safeは、各クラスを空に登録できますが、ConverterRegistry(\\直接x,Spring Web MVCコンフィギュレータ)に登録して使用します.
\main\me\jinmin\EventController
package me.jinmin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EventController {
@GetMapping("/event/{event}")
public String getEvent(@PathVariable Event event){
System.out.println(event);
return event.getId().toString();
}
}
\main\me\jinmin\EventConverter
package me.jinmin;
import org.springframework.core.convert.converter.Converter;
public class EventConverter {
public static class StringToEventConverter implements Converter<String, Event> {
@Override
public Event convert(String source) {
return new Event(Integer.parseInt(source));
}
}
public static class EventToStringConverter implements Converter<Event, String>{
@Override
public String convert(Event source) {
return source.getId().toString();
}
}
}
\main\me\jinmin\WebConfig
package me.jinmin;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new EventConverter.StringToEventConverter());
}
}
Spring Web MVC Configurer
でConverter
を登録します.\test\java\me\jinmin\EventControllerTest
およびテスト駆動結果package me.jinmin;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void getTest() throws Exception {
mockMvc.perform(get("/event/1"))
.andExpect(status().isOk())
.andExpect(content().string("1"));
}
}
print:
Event{id=1, title='null'}
/event/1
のうちの1は、Converter
によってイベントタイプに変換され、Controller
からイベントタイプが受信できることを示す.Formatter
PropertyEddiorの代替製品
オブジェクトとStringの変換
オプションの文字列ローカライズ(Localeベース)
「読み込み-保存」のため、空に登録できますが、FormateRegistryに登録して使用できます.
\main\java\me\jinmin\EventController
は上のConverter
と同じです\main\java\me\jinmin\EventFormatter
package me.jinmin;
import org.springframework.format.Formatter;
import java.text.ParseException;
import java.util.Locale;
public class EventFormatter implements Formatter<Event> {
@Override
public Event parse(String text, Locale locale) throws ParseException {
return new Event(Integer.parseInt(text));
}
@Override
public String print(Event object, Locale locale) {
return object.getId().toString();
}
}
\main\java\me\jinmin\WebConfig
package me.jinmin;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new EventFormatter());
}
}
\test\java\me\jinmin\EventControllerTest
コードおよび結果はConverter
と同じである.ConversionService
PropertyEditorとは異なり、実際の変換は
ConversionService
インタフェースを使用し、「読み取り-セキュリティ」機能を備えています.Spring MVC、Spring xml空設定ファイル、Spring Expression Languageで使用します.
❗DefaultFormattingConversionService
複数のデフォルトConverterとFormateを登録します(継承関係)
package me.jinmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Component;
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
ConversionService conversionService;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(conversionService.getClass().toString());
}
}
print:
class org.springframework.boot.autoconfigure.web.format.WebConversionService
出力は
ConversionService
ではなく、WebConversionService
(スプリングガイドが提供するクラス)である.(実際の使用率は高くありませんが、トレーニングで理解する必要があります)SpringBootでは、
Formatter
とConverter
の空きが登録されていると、その空きが見つかり自動的に登録されます.(つまり、既存のWebConfig
で登録する必要はありません.)(確認して!)まず、
WebConfig
を削除し、EventConverter
の内部クラスを@Component
に登録してアプリケーションを起動します.package me.jinmin;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
public class EventConverter {
@Component
public static class StringToEventConverter implements Converter<String, Event> {
@Override
public Event convert(String source) {
return new Event(Integer.parseInt(source));
}
}
@Component
public static class EventToStringConverter implements Converter<Event, String>{
@Override
public String convert(Event source) {
return source.getId().toString();
}
}
}
結果
第二に、
WebConfig
を削除し、EventFormatter
を@Component
として登録し、アプリケーションを起動する.package me.jinmin;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.util.Locale;
@Component
public class EventFormatter implements Formatter<Event> {
@Override
public Event parse(String text, Locale locale) throws ParseException {
return new Event(Integer.parseInt(text));
}
@Override
public String print(Event object, Locale locale) {
return object.getId().toString();
}
}
Conveter
)と同じ:テストではどのように起動しますか?
発(補足説明)階層テスト→ページ関連の空のみ登録する.主に
Controller
人しか登録していませんが、Formatter
とConverter
が正しく登録されていなければ、テストは破られます.\test\java\me\jinmin\EventControllerTest
Formatter Test
@WebMvcTest
⇒ @WebMvcTest({EventFormatter.class, EventController.class})
Conveter Test
@WebMvcTest
⇒ @WebMvcTest({EventConverter.StringToEventConverter.class, EventController.class})
2つの結果
print:
Event{id=1, title='null'}
🔔(推奨)Formateの使用:主にWebで使用されます.△退役した老兵も悪くない.
Reference
この問題について([スプリングコア]3データバインド抽象), 我々は、より多くの情報をここで見つけました https://velog.io/@jinmin2216/스프링-3.-데이터-바인딩-추상화テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol