FlexJson and #JSON annotation - #JSON(name = "") not working - java

I just switched to FlexJson and I am already having a problem.
The documentation at http://flexjson.sourceforge.net/, chapter Controlling JSON naming with #JSON states :
When an object is serialized the names of the properties on JSON
objects are determined from the name of the Java property. This means
the names of the getter methods or the field names are used. However,
sometimes the JSON output doesn't match the names used by the Java
object. You can control this using the #JSON annotation. For example:
public class Species {
#JSON(jsonName = "genus")
private String type;
private String name;
#JSON(jsonName="species")
public String getName() {
return name;
}
}
Except it doesn't work. And then they say :
Defining a #JSON.jsonName is used in both serialization and
deserialization.
Now when I have a look into the javadocs at http://flexjson.sourceforge.net/javadoc/index.html, I can see there are 4 optional elements belonging to the #JSON annotation, those are
include name objectFactory transformer
None of it is jsonName, like in the example.
So how do I get this annotation to work, so I can have different java and json names?
How can I define this annotation element or make use of the predefined name
To clarify, I can annotate #JSON and autocomplete recommends #JSON(include), but then include cannot be resolved...
I am using FlexJson 2.1, and I imported flexjson.JSON;
Btw I am aware of this answer https://stackoverflow.com/a/8879616/2001247, but it's not what I want. I want to use annotations.

You need to use FlexJson 3.2
The problem is, latest jar accessible via developer site have 2.1 version number.
But java doc corresponds to version 3.2.
You can find FlexJson 3.2 jar in maven repository.

Related

Problems with sonar changing the names of an object in REST calls by Jackson JSON

I have an object that in its fields is mandatory that some names have '_' for example local_PC instead of localPC.
The problem I have is that I need it to be local_PC and when a call is made to my app they send that field and I can't change it, but sonar launches me error because it must be localPC
Is there any way I can control it by Jackson?
realizing #jsonproperty only allows me to change the names in the output but not in the input of the controller
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
#AllArgsConstructor
public class Example{
private String local_PC;
}
Use #JsonAlias
#JsonAlias is introduced in Jackson 2.9 release. #JsonAlias defines one or more alternative names for a property to be accepted during deserialization i.e. setting JSON data to Java object. But at the time of serialization i.e. while getting JSON from Java object, only actual logical property name is used and not alias. #JsonAlias
#JsonAlias({"local_PC", "localPC"})
private String local_PC;

Auto display of list of enums in spring auto rest docs isn't explanatory

I've generated a document using spring auto rest docs. This uses capital.scalable libraries combined with java docs and spring rest docs.
My issue is with the List of enums while describing the request fields.
Type column generates a value as Array[Object]. Also, the description column doesn't generate the must be one of statement with the enum values, as it does when only Enum is the field and not the list of enums.
public enum Discipline {
ECONOMICS("economics"),
SOCIOLOGYANTHROPOLOGY("sociologyanthropology");
private final String discipline;
Discipline(final String discipline) {
this.discipline = discipline;
}
public String getId() {
return discipline;
}
}
Above is the enum that I have. It uses tostring correctly to display in the description when the field is used only as enum. But if list of enums i.e.
List<Discipline>
is the field, then it doesn't describe properly as mentioned above.
Please let me know what should be done to generate the document more effectively?
You are right that lists of enums are not properly supported yet.
If you have a request/response like:
class SomeRequest {
public enum EnumTest {
ONE, TWO
}
/**
* List of enums
*/
private List<EnumTest> enumTestList;
}
it is documented as
with Spring Auto REST Docs at the moment.
It would be good if the type would be Array[String] and the description would list the elements of the enum, e.g. "Elements must be one of [...]".
Spring Auto REST Docs 1.0.11 fixes the type issue and thus Array[String] will be shown with this version.
I opened an issue to improve the documentation of lists of enums: https://github.com/ScaCap/spring-auto-restdocs/issues/194. Until this issue is resolved, one can manually add "Elements must be one of [...]" to the Javadoc of the list as a workaround.

Marshalling nested objects with JAXB - unwrapped

I've got a very simple problem here, but after using Google for over an hour now, I still cannot find a good solution and it starts to cost too much money..
In my app I use REST as an API, basically only with JSON as payload type, and Enunciate for documentation of the API. As you might know, enunciate will generate an xsd schema from the classes. I am therefore in the situation, that I need to configure all the DTO's for Jackson/JSON handling with the suitable annotations, and also with JAXB annotation to ensure the generated schema is correct and can be parsed with XJC into the correct classes!
Although that is not very difficult to achieve and works flawless in most of the cases, I have a simple but somehow special case, in which it completely fails.
Assuming the following classes:
#JsonRootName(value = "location")
public class Location {
private String label;
#JsonUnwrapped
private Address address;
// constructors, getters, setters ommited..
}
//// new file
public class Address{
private String city;
private String street;
private String postCode;
}
This works 100% with Jackson/JSON. The embedded Address object will be unwrapped so that the JSON looks like this:
{
"label":"blah",
"street":"Exchange Road",
"city":"Stacktown"
"postCode":"1337"
}
This works forth and back with Jackson.
JAXB on the other hand is able to parse (most of) the Jackson annotations, so that generally you wont have problems with using simple objects in both worlds. #JsonUnwrapped though sadly is NOT supported by JAXB, and strangely that (from my POV) quite simple usecase seems to be not reflectable with any JAXB annotation at all.
What happens is, that the generated schema contains the embedded Address object, without any attributes/elements. Therefore the class generated by XJC will contain that Address object reference. And this ultimately leads to erroneous JSON from a app that will use the schema to generate objects...
Any ideas?
The JAXB (JSR-222) specification does not define an equivalent to Jackson's #JsonUnwrapped. For a long time we have offered that functionality in the EclipseLink MOXy implementation of JAXB via our #XmlPath extension.
#XmlPath(".")
private Address address;
For More Information
I have written more about MOXy's #XmlPath extension on my blog:
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html

How to safely refactor (e.g rename fields) DTO classes returned in JAX-RS web service calls?

I stumbled upon following problem after refactoring of IssueDTO (used as the type of elements in the returned list below):
generated JSON response has changed dictionary key (keys are used as
Strings in our selenium tests so refactoring broke the tests)
jsf page accesses IssueDTO objects using field names (or names converted
to javabeans-named methods, I'm not sure) but the access is textual,
not "typed"
#GET
#Path("/issues/{" + LOCALE_PARAM + "}")
#Produces(MediaType.APPLICATION_JSON)
public List<IssueDTO> getSlides(#PathParam(LOCALE_PARAM) final String locale) {
final Locale currentLocale = (locale == null) ?
Locale.getDefault() : new Locale(locale);
return issues.getIssuesInLocale(currentLocale);
}
How can I be sure my refactoring would neither break tests nor break jsf pages?
Is there any annotation I can apply to IssueDTO fields so that to "freeze" their names i.e. de-couple java code names from those used by non-statically-typed-javaee-specific contexts?
Assuming a plain JavaEE application (i.e. JAX-RS with JAXB annotations used for the JSON generation), you could use #XmlElement(name = "fixedName") to decouple the actual property names from their XML AND JSON representation.

How do you marshall a parameterized type with JAX-WS / JAXB?

Consider the following classes (please assume public getter and setter methods for the private fields).
// contains a bunch of properties
public abstract class Person { private String name; }
// adds some properties specific to teachers
public class Teacher extends Person { private int salary; }
// adds some properties specific to students
public class Student extends Person { private String course; }
// adds some properties that apply to an entire group of people
public class Result<T extends Person> {
private List<T> group;
private String city;
// ...
}
We might have the following web service implementation annotated as follows:
#WebService
public class PersonService {
#WebMethod
public Result<Teacher> getTeachers() { ... }
#WebMethod
public Result<Student> getStudents() { ... }
}
The problem is that JAXB appears to marshall the Result object as a Result<Person> instead of the concrete type. So the Result returned by getTeachers() is serialized as containing a List<Person> instead of List<Teacher>, and the same for getStudents(), mutatis mutandis.
Is this the expected behavior? Do I need to use #XmlSeeAlso on Person?
Thanks!
LES
The answer to this one was rather tricky. It turns out that the version of jettison used by the jax-ws json plugin is a bit old (1.0-beta-1 IIRC). That particular version doesn't handle this case well (it crashes). If you do add the #XmlSeeAlso then the JSON marshalling will crash! Of course, this sucks!
I read on some forum (don't have the link - this is all from memory) that the jax-ws json plugin isn't actively maintained. If you try to 1) exclude the default jettison dependency from the jax-ws json depedency (assuming maven here) and add a newer version you get an error about JSONException not existing. Jax-ws json will NOT work with a newer version of jettison (I tried).
This is documented on another website (someone stated that they would like for someone to port jax-ws json to the latest jettison).
In the end, I switched to DWR for remoting. JAX-WS is best left for system-to-system (backend) integration. It's too heavy-weight for front-end stuff. DWR works AWESOMELY in this case.
Found link to forum I read: http://forums.java.net/jive/thread.jspa?messageID=384385 . Note that Collab.net is currently down for maintenance but they'll be back up soon.
As far as answering the general question (without the JAX-WS JSON plugin part), the answer is yes - you must use the #XmlSeeAlso annotation on the Person class. Otherwise the schema will only contain Person and not Teacher or Student elements. Only the elements defined in Person are marshalled without the #XmlSeeAlso annotation.

Categories