How to handle empty constructor with final fields - java

I have a class like this
public class Test {
private String m_username;
public Test() {}
public Test(String username) {
m_username = username;
}
}
And with Moxy. I can post this POJO to other API using Jersey client without any converting operation. But I need to set the m_username as a final field and that will need the empty constructor to initiate m_username. And also the Moxy doesn't work. How can I fix that?

The question isn't very well asked.
AS far as I understand:
You have to make your field final
You have to keep the empty constructor because your object is automatically serialized/deserialized in a format like JSON, using a library such as those you can find in Spring
Unfortunately, these two constraints can't be held at the same time. You will need to abandon final if you want to keep the empty constructor, and conversely.

Related

How to use multiple Java annotations with the same value?

I'm using Retrofit along with GSON to retrieve data from an API and deserialize it to Java objects using GSON's #SerializedName annotation like below:
public class MyApiObject {
#SerializedName("apiJsonKey")
private String myValue;
...
}
It works fine, but I need to send objects of MyApiObject to a Firebase database and for that the object needs to be serialized back to JSON. Firebase's Java API does this automatically, but it generates the keys based on the instance variable's names (myValue) and not the serialized name ("apiJsonKey").
I know I can use Firebase's #PropertyName annotation, but that would require me to use two annotations with the same values, which is redundant and error-prone.
Is there a better way to do this?
The usual aproach in this cases is to set a constant and use it in both annotations.
public class MyApiObject {
private static final String MY_VALUE_NAME = "apiJsonKey";
#SerializedName(MY_VALUE_NAME)
#ParameterName(MY_VALUE_NAME)
private String myValue;
...
}
This is fairly usual in sequence annotations for JPA.

How to JSON parse immutable object in Java + Jersey

So I am just trying out Jersey for REST services and it seems to we working out fine. I only expose get services and all of the object types that I expose with these services have an immutable object representation in Java. By default Jersey seems to use a parser (JAXB?), requiring a #XmlRootElement annotation for the class that should be parsed, zero-arg constructor and setters.
I have been using Gson with no zero-arg constructor, no setters and final on all fields with no problems at all. Is there any way to accomplish this with Jersey(i.e. the paser it is using)? I have seen solutions with adapter classes that map data from a immutable object to a mutable representation, but this seems like a lot of boilerplate(new classes, more annotations, etc.) if it can be achieved with Gson without anything added.
Note: 1) I have heard people promote using zero-arg constructor and claim that Gson should not work without it. This is not what I am interested in. 2) I really have tried googling this but my keywords might be off. In other words, humiliate me in moderation.
EDIT 1:
My webservice works if I do like this:
#XmlRootElement
public class Code{
private String code; //Silly object just used for example.
public Code(){}
//(G || S)etters
}
With this class exposing the object:
#GET
#Produces(MediaType.APPLICATION_JSON)
public Set<Code> get(#QueryParam("name") String name) { // Here I want to use a class of my own instead of String name, haven't figured out how yet.
return this.codeService.get(name);
}
If I replace the Code with the following, the webservice stops working:
public class Code{
private final String code;
#JsonCreator
public Code(#JsonProperty("code") String code) {
this.code = code;
}
//Getters omitted
}
What I want is to be able to 1) have immutable objects that can be parsed to/from json and 2) Be able to define something like #RequestBody in Spring MVC for my incoming objects.
Actually this could be pretty easy with Genson. You just need the jar and then configure the Genson feature to use constructors with arguments (if you don't want to put annotations on it).
Genson genson = new GensonBuilder().useConstructorWithArguments(true).create();
// and then register it with jersey
new ResourceConfig().register(new GensonJaxRSFeature().use(genson));
Or you can use JsonProperty on the arguments. See the User Guide for more details.

Using Java Spring injection with `public static final` objects (for Jakarta Unstandard)

Disclaimer: I understand that trying to use Spring to inject static variables is considered bad practice (and I know there are ways around it, e.g. here). So ultimately I plan to redesign, but am curious about possible solutions or workarounds.
I am using Jakarta's Unstandard tag library (particularly useConstants) to easily expose public static final objects to my JSP pages. I want these static objects to initialize themselves from my database, which means I need to inject a JDBC Template or Data Source. So I want something like:
public class MyGroup {
// #Autowire or inject somehow?
private static /*final?*/ NamedParameterJdbcTemplate jdbcTemplate;
public static final MyGroup GROUP_A = new MyGroup("GROUP_A");
public static final MyGroup GROUP_B = new MyGroup("GROUP_B");
public static final MyGroup GROUP_C = new MyGroup("GROUP_C");
// Instance fields
private int id;
private String name;
private String description;
/**
* Construct a group
*/
public MyGroup() {}
/**
* Construct a group using information from the database
* #param key the key to match
*/
public MyGroup(String key) {
// Do DB stuff using injected JDBC template
this.id = id_from_DB;
this.name = name_from_DB;
this.description = desc_from_DB;
}
}
In my JSP, I could simply do ${MyGroup.GROUP_A.id} and anywhere else in the Java code I could just MyGroup.GROUP_B.getName().
So the problem is that these groups must be final for the Jakarta library to pick them up, but I can't static initialize them via Spring. Thoughts?
This isn't a problem with spring so much as with a conflict between what you want and what java allows. You cannot delay the assignment of a static final property. It has to be set when the class is loaded. Therefore, by the time spring could inject, it is too late.
If you don't have to have it be final, you can open up some options.
Another possibility is it might be possible to create an aspect when intercepts the access of the property, and returns the value you want rather than the stored value. You could then inject the desired value into the aspect.
I've never done it before specifically with static properties, but I presume it is possible. It is not possible to use constant fields (static final fields bound to a constant string object or primitive value) as a JoinPoint since java requires those to be inlined, but since you are pointing to a non-String object, I think using an aspect could work.
To make sure spring injects into your aspect, make sure you tell spring about it via via something like this:
<bean id="someId" class="com.yourdomain.YourAspect" factory-method="aspectOf"/>

Retrieve field values using BeanUtils

I want to extract private field values that are not marked by certain custom annotation, is this possible via BeanUtils? If yes, how?
Yes, assuming that you know the fields names. You can use PropertyUtils.getSimpleProperty(...). See also here for an example.
No, it is not possible with BeanUtils. But you can use Java's own reflection tools like this:
public class BeanUtilTest {
public static void main(String[] args) throws ... {
MyBean bean = new MyBean();
Field field = bean.getClass().getDeclaredField("bar");
field.setAccessible(true);
System.out.println(field.get(bean));
}
public static class MyBean {
private final String bar = "foo";
}
}
Please consider: Accessing private fields with reflection is very bad style and should be done only for tests or if you are sure there is no other way. If you don't have the ability to change the sources of the class you're trying to access, it might be a last resort. But consider that the behavior might change in the future (e.g. as an update of the library you're using) and break your code.
Edit: If BeanUtils or PropertyUtils are working, this means there is a public getter for this property and you should be using it instead of using reflection. Using PropertyUtils on a private field without a public getter throws a NoSuchMethodException.

How can I convert a java bean to a properties file?

What libraries are available that can do something like
public class Person {
private Long id;
private Name;
private List<Long> associations;
// accessors
}
public class Name {
private String first;
private String last;
// accessors
}
into something like
id=1
associations=1,2,3,4,5
name.first=Franz
name.last=See
And If there's no library to do that, what's a good way to do it? :-)
I doubt there's a library for that since common way to serialize beans is into XML. You may write simple library yourself using Java Reflection API to get list of properties and extract their values. It would be more common solution than making custom toString() for any class you may need to serialize.
Well I think instead of using any external library you can do it yourself just add getters and setters in your javabeans and override to string method of it and then you can form the string as you want.Then only task remaining is to write that string into one file, thats it!!!!!
Well, you can go check how XMLEncoder extract field names and values from object, and try to rewrite it to output properties files. I think that, by replacing xml output by properties output, you can get a fairly good properties creator. Notice, as an added benefit, that the same goes for properties reading using an equivalent opf XMLDecoder.
Please check if JSON would solve this problem.
import net.sf.json.JSONObject;
public class YourJSONJavaExample
{
public static void main(String args[]){
JSONObject object=new JSONObject();
object.put("firstname","John");
object.put("age",new Integer(21));
object.put("lastname","smith");
System.out.println(object);
}
}

Categories