[JAVA] Introduced Dozer to Play Framework

I used to use a library called Dozer for development using Spring Framework, but since it was a convenient library, I decided to use it with the Play Framework I am currently using, so I wrote the code. The created source is uploaded to GitHub.

environment

What is Dozer

A library that maps data between objects. It is very useful when passing data between layers with the MVC framework. First, let's look at a normal implementation that does not use Dozer. You will often write code like the following when passing data from the current layer to the next layer.

Normal mapping


//Current layer

//Pass data to the next layer bean
BeanB beanB = new BeanB();
beanB.field1 = beanA.field1;
beanB.field2 = beanA.field2;
beanB.field3 = beanA.field3;
             .
             .
             .
//Processing of the next layer
service.run(beanB);

The above is a simple pattern, but if the bean implements a setter or getter, or if you are doing type conversion because the types are different between the beans, the readability is poor and the more parameters there are, the more verbose code It will be. In addition, if the bean increases or decreases parameters, the mapping must be modified each time. The following is an example using Dozer.

Dozer mapping


//Current layer

//Bean mapping by Dozer
Mapper mapper = new DozerBeanMapper();
BeanB beanB = mapper.map(beanA, BeanB.class);

//Processing of the next layer
service.run(beanB);

If you pass the copy source object in the first argument of the map method and the copy destination class in the second argument, the object of the copy destination class that holds the copy source data will be returned. This is because Dozer maps the data of the copy source to the parameter of the same name of the copy destination. Furthermore, if the type supports type conversion, type conversion will be performed automatically. For more information on type conversion support, see here (http://dozer.sourceforge.net/documentation/simpleproperty.html).

Preparing to introduce Play

Let's try Dozer. I made an app that just inputs the name and amount from the screen and registers it, so I would like to introduce Dozer there. Installation is not particularly difficult as it can be used simply by adding it to build.sbt.

First, add the following to build.sbt and reload and update.

libraryDependencies += "net.sf.dozer" % "dozer" % "5.5.1"

After that, you can generate DozerBeanMapper in the layer that uses Dozer and use it, but this time I would like to define it in DI. Create a MappingModule class that inherits AbstractModule and define the dependencies.

MappingModule



//import omitted

public class MappingModule extends AbstractModule {

	@Override
	protected void configure() {
		bind(Mapper.class).to(DozerBeanMapper.class);
	}

}

Register the created MappingModule in applications.conf.

application.conf


play.modules {
    enabled += modules.MappingModule
}

Inject

The beans used in each layer are defined as follows.

Bean layer
Form Client - Controller
Dto Controller - Service
Model Service - Repository

Inject Mapper into the class you want to use Dozer. Since the following is the Controller class, we are mapping data from Form to Dto.

IndexController


package controllers;

//import omitted

public class IndexController extends Controller {
	@Inject
	private FormFactory formFactory;
	@Inject
	private Mapper mapper; //this
	@Inject
	private IndexService service; 
	
	//Other methods omitted

	public Result post() {
		Form<IndexForm> f = formFactory.form(IndexForm.class).bindFromRequest();
		IndexDto dto = mapper.map(f.get(), IndexDto.class); //Mapping here
		switch(f.get().action){
		case "regist":
			service.regist(dto);
			break;
		case "delete":
			service.delete(dto);
			break;
		default:
		}
		return ok(views.html.index.render(f, dto));
	}

}

After making a RequestBind to Form, data is mapped to Dto and processing is moved to the next layer (Service). Form and Dto are defined as follows.

IndexForm


package forms;

public class IndexForm {
	/**Screen action*/
	public String action;
	/**name*/
	public String name;
	/**Amount of money*/
	public String amount;
	/**Delete ID*/
	public String id;
}

IndexDto


package dtos;

//import omitted

public class IndexDto {
	/**name*/
	public String name;
	/**Amount of money*/
	public BigDecimal amount;
	/**Delete ID*/
	public Long id;
	/**Data list*/
	public List<Person> personList;
}

The type of the amount and the deletion ID are different, but the type conversion is performed in Mapper.

Finally

Since the server is actually started and the operation is confirmed, the source is uploaded to GitHub. Dozer can be customized to allow mapping between fields with different names and complex mapping, but I couldn't write because I didn't know how to set it in Play. I would like to investigate and update it.

Recommended Posts

Introduced Dozer to Play Framework
How to install Play Framework 2.6 for Mac
How to use BootStrap with Play Framework
Play Framework study
Post to Slack from Play Framework 2.8 (Java)
Play Framework2.5 (Java) Tips
Play Framework studying test
play framework personal notes
How to use Play Framework without using typesafe activator
Play Framework Study Memo Database ①
Java to play with Function
First Play Framework personal notes
Validation function in Play Framework
Introduced gRPC client to rails
Play Framework Study Memo Database ②Read
Play Framework 2.6 (Java) development environment creation
Play Framework Study Momo DB Update
Double submit measures with Play Framework
Play framework scheduled jobs and crontab