Copy properties from source to target class using beanutils.properties method - spring

I have a source class Entity having some params and a target class Dto class.
Now, Entity class is having params of some other class but in dto class I'm using those params directly not using the other class reference in dto.
Problem is : while doing BeanUtils.copyProperties(source,target) those properties having reference to other class does not get copies to dto class.
Entity class:
Public class Entity{
private A a;
private String add;
}
Public class A{
private String name;
}
Dto class :
public class Dto{
private String add;
private String name; // here instead of class A i directly took the param of class A as per requirement.
}
How can I do BeanUtils.copyProperties(Entity,Dto); so that all properties get copied.
The entity class contains params from other entity class but dto does not contain the reference to other class instead directly having other class params.

Spring has the concept of Converters that are used automatically when it has to convert between classes. BeanUtils.copyProperties doesn't seem to use it, but it's should be difficult using BeanWrapper to write an alternative that loops over properties and attempts to use Converters (in this case a Converter from A to String) to copy the properties.
Alternatively there are other libraries that can do similar tasks: Dozer, ModelMapper, MapStruct just to name a few without any preference.

Related

Spring MVC mapping #RequestBody with variables containing a dot

I am doing a POST request to my Rest Contoller with the following object:
{
"relationship.name": "someting"
}
I'd like to map that to a POJO:
public class Request {
private String relationshipName;
// Getters, setter and contructor
}
How would I dot that?
Annotate your property with #JsonProperty
public class Request {
#JsonProperty("relationship.name")
private String relationshipName;
...
}
By default, the mapping will use the variable name as the key for the property. So without the annotation, it would expect relationshipName. #JsonProperty allows you to customize the key without changing the variable name.
Have u tried using #JsonProperty on relationshipName?
#JsonProperty(name), tells Jackson ObjectMapper to map the JSON property name to the annotated Java field's name.

Custom serialization of single #RestController endpoint

Is there a way (preferably some type of annotation) to register a custom serializer for a single endpoint in a #RestController? Extending the bean and putting a #JsonSerialize on it would be an option, but that demands an otherwise pretty useless new bean class. I tried the following:
#JsonSerialize(using = CustomSerializer.class)
#RequestMapping(value = "/some_endpoint/", method = RequestMethod.GET)
public SomeType someEndpoint() {
return someObject;
}
But the #JsonSerialize annotation doesn't appear to have any meaning to Spring in that context. Is there an alternative or is the extra bean class my only option?
You can use #JsonView(View.Summary::class) in the attributes you want to add or ignore and in the method you want to apply that view, for example:
public class View {
public interface Summary
}
public class A{
#JsonView(View.Summary.class)
private String serialized = "",
private String notSerialized = ""}
and then in the controller:
#JsonView(View.Summary.class)
#GetMapping("/")
#ResponseBody
public A getA(){
return A()
}
If you want to reverse the JsonView (serialize the atributtes who doesnt have the view). you can add the following propertie: spring.jackson.mapper.default-view-inclusion=true

How can I put an instance of an object as session attribute in a Spring MVC project?

I am working on a Spring MVC application and I have the following problem.
I have this RegistrazioneInfo class that contains some information inserted into a form by the user:
public class RegistrazioneInfo {
#NotNull
#Size(min=16, max=16)
private String codiceFiscale;
String gRecaptchaResponse;
public String getCodiceFiscale() {
return codiceFiscale;
}
public void setCodiceFiscale(String codiceFiscale) {
this.codiceFiscale = codiceFiscale;
}
public String getgRecaptchaResponse() {
return gRecaptchaResponse;
}
public void setgRecaptchaResponse(String gRecaptchaResponse) {
this.gRecaptchaResponse = gRecaptchaResponse;
}
}
Then I have this controller class:
#Controller
public class RegistrazioneController extends BaseController {
private RegistrazioneInfo registrazioneInfo;
...............................................
...............................................
...............................................
}
that contains some methods handling request towards some resources.
Ok, my problem is that I want to use an instance of the previous RegistrazioneInfo class as session attribute by the use of the #SessionAttributes Spring annotation as shown here: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-sessionattrib
My problem is, in the previous example do something like this:
#SessionAttributes("pet")
public class EditPetForm {
// ...
}
So what exactly is pet? I think that it is something like an id that identify the object that have to be used as a session attribute or something like this. How can I say to put an instance of my RegistrazioneInfo as session attribute?
#SessionAttributes is declared in a Controller Class (#Controller), so on the class level.
Pet is an Bean Object that persist in HttpSession
From the documentation:
This will typically list the names of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans. Declared at the type level, applying to the model attributes that the annotated handler class operates on.
(emphasis is mine)
Also note that, as indicated in the documentation, you should not use that for "non temporary" elements.

Spring: #NestedConfigurationProperty List in #ConfigurationProperties

Hi I am trying to get the following configuration up and running.
#ConfigurationProperties(prefix="my")
public class Config {
#NestedConfigurationProperty
private List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>();
public List<ServerConfiguration> getServers() {
return this.servers;
}
}
#ConfigurationProperties(prefix = "server")
public class ServerConfiguration {
private String name;
private String description;
}
So, I want to have multiple server configs nested in objects.
I tried setting the properties with the following properties file. I can see that the list is added up by items but the members of the server are never set (name, description)
my.servers[0].name=test
my.servers[0].server.name=test
my.servers[1].name=test
my.servers[1].server.name=test
To extend what Maciej said already.
#ConfigurationProperties should be set only on root objects (that is objects that are responsible to handle a given prefix. There is no need to annotated nested objects with it.
#NestedConfigurationProperty is only used by the meta-data generator (to indicate that a property is not a single value but something we should explore to generate additional meta-data. In the case of the List there isn't any finite amount of properties so the meta-data will have to stop at the list.
In any case you need a getter and a setter for each singular property. We don't do field binding and we require a public getter to avoid exposing unnecessary properties in the meta-data.
You need to add setters and getters to ServerConfiguration
You don't need to annotate class with nested properties with #ConfigurationProperties
There is a mismatch in names between ServerConfiguration.description and property my.servers[X].server.name=test

Inject #Parameter in different class in maven plugin

I am writing a maven plugin and based on my previous experience i know that my mojo class will end up with a bunch of #Parameters to configure it. What I would like to do is instead of having those configuration parameters injected in the mojo class, I would like to have them injected in a second, configuration-only class. Is this possible?
The current way I do it is the mojo class just constructs a Configuration object where it passes all the injected parameters. Something like this
#Mojo
public class MyMojo extends AbstractMojo {
private MyConfig myConfig;
#Parameter
private String myArg1;
...
public void execute() {
myConfig = new MyConfig(myArg1, myArg2, ...);
}
}
But this is rather ugly. I want the DI to happen directly in Config
If MyConfig is a pojo, you can use the #Parameter here as well, However, you config will look like:
<configuration>
<myConfig>
<someField>value</someField>
</myConfig>
</configuration>
The second trick is to use setters, because an #Parameter-annotated field will use the matching public setter, if there is one.
private MyConfig myConfig = new MyConfig();
#Parameter
private String someField;
// matching setter for #parameter-annotated field
public void setSomeField( String field )
{
myConfig.setSomeField( field );
}
You can use your MyConfig POJO as #Parameter:
#Mojo
public class MyMojo extends AbstractMojo {
#Parameter
private MyConfig myConfig;
...
}
The rules for mapping complex objects are as follows:
There must be a private field that corresponds to name of the element being mapped. So in our case the person element must map to a person field in the mojo.
The object instantiated must be in the same package as the Mojo itself. So if your mojo is in com.mycompany.mojo.query then the mapping mechanism will look in that package for an object named Person. As you can see the mechanism will capitalize the first letter of the element name and use that to search for the object to instantiate.
Source
However, using the #Parameter for fields of MyConfig has no effect, see this thread.

Resources