Swagger UI with Java Rest Service - java

I am new to using Swagger documentation. I am using Swagger's annotations on Java rest service class. Could you please provide some help on the below problem -
My rest method is as below:
public String testMethod3(#ApiParam(value = "Mailing address of the user", required = true) #FormParam("address") final String address) {}
As you see, I am passing a JSON String parameter - address to my rest method. On the Javascript side, I have the below code to set up the data -
var addressMap = {};
addressMap.city = 'SS';
addressMap.zipCode = '98877';
addressMap.state = 'CA';
I am now sending this to the rest method by calling JSON.stringify(addressMap).
In Swagger-UI, I am only getting one parameter option to enter. How can I let the user to know that this is a complex object and they need to pass city, zipcode and state values.

If you're passing data in a #FormParam, you'll need to add a value for each of the fields. For example, city, zipCode, and state.
But I believe what you really want to do is post the JSON as a HTTP POST method, which case you would remove the #FormParam and consume the values into a java object that has the fields in the payload.

Related

RestTemplate Project: the DTO fields changing on their own

So I made Rest Client using Spring Boot that is consuming a Rest Web Service. I am passing the required requestbody but on printing the requestbody out it is not the same as my input.
For Example: What I entered was TransactionId then it would be changed to transactionId, AB_NAME would be changed to ab_NAME.
So all these fields get assigned null values.
The ResponseEntity being formed also does the same thing. I don't know why this is happening.
The dtos I have made are in line with the input I want to send so I don't know how they are changing on their own.
EDIT: So basically the web service dto fields are not using the Java naming convention but JSON automatically assumes them to be, had to use #JsonProperty to make sure the fields remain the same. Thanks for all of your help.
See your request body properties names and your model properties name should be the same as case. Writing here one example
DTO
publi class SomeName{
private string transactionId;
private string ab_NAME;
}
Sending body format should be
{
"transactionId":"11111",
"ab_NAME":"ABCDE"
}
Thanks.

How do I pass in an object to a rest template?

How do I pass in an object to a RestTemplate? I currently have an object that I am trying to pass in to two different functions. In one way, I want to pass it in as a RequestBody, and in the other I want to pass it in as a RequestParam.
For example, I have the following code:
Student student = new Student("Allison");
Teacher response = restTemplate.getForObject("url for get student's teacher api/{schoolID}", Teacher.class, student);
The getStudentsTeacher takes in paramters (#PathVariable schoolID, #RequestBody Student student).
My code does not work, as I am not specifying the content type (json), so how would I do this? Also, how would this work with #RequestParam instead of #RequestBody?
According to the RestTemplate javadoc, the uri variables can be expanded. So, all you need to do, is to supply to value to expand the variable in the template
Teacher response = restTemplate.getForObject("domain.com/api/{schoolId}", Teacher.class, 123);
Now, it's really strange that you're sending a GET request with body.
If you really need to do so, then you'll have to use the RestTemplate#exchange method.
HttpEntity<Student> request = new HttpEntity<Student>(new Student("Allison"));
// 123 -> it's the schoolId that the exchange method will be using to expand the uri variable
ResponseEntity<Teacher> teacher = restTemplate.exchange("domain.com/api/{schoolId}", HttpMethod.GET, request, Teacher.class, 123);
log.info(teacher.getBody());

Is there any way to create JSON object with keys as upper case?

Project: Android app using REST web service
Using:
Client - Volley
Server API - Jersey
Converter: Gson
This is my first time asking a question here, and i will provide my way of "evading" this code convention. Since i am working on a project where POJO fields are already defined as upper-case (sadly, i cant change that), i had to find a way to fix JSON string and convert it to an instance of uppercase POJO.
So basicaly its: client POJO <--> json object converted to/from gson <--> server POJO
So, lets say that i have a field in Users.class
String USERNAME;
When Jersey sends an instance of via #Produces, it follows the convention of creating JSON and sends an object
{"username": "random_name"}
When it gets converted from JSON via gson.fromJSON, an instance of a client's POJO will get null value for that field (obviously because field is in lower-case in JSONObject).
This is how i managed it by using a method that parses JSONObject and puts each key as upper-case:
public static String fixJSONObject(JSONObject obj) {
String jsonString = obj.toString();
for(int i = 0; i<obj.names().length(); i++){
try{
obj.names().getString(i).toUpperCase());
jsonString=jsonString.replace(obj.names().getString(i),
obj.names().getString(i).toUpperCase());
} catch(JSONException e) {
e.printStackTrace();
}
}
return jsonString;
}
And luckily since gson.fromJSON() requires String (not a JSONObject) as a parameter besides Class, i managed to solve the problem this way.
So, my question would be: Is there any elegant way of making JSON ignore that code convention and create a JSON object with an exact field? In this case:
{"USERNAME": "random_name"}
Jersey uses JAXB internally to marshall beans to xml/json. So you can always use #XmlElement annotation and use name attribute to set the attribute name to be used for marshalling
#XmlElement(name="USERNAME")
String USERNAME;
Just use annotation com.google.gson.annotations.SerializedName
Add in class Users.java:
#SerializedName("username")
String USERNAME;

Limiting Fields in JSON Response for REST API?

I am using Spring and Java and implementing REST Based services. I have a set of developers who develop for mobile,iPad and Web too. Consider I have a bean
Class User{
private String Name;
private Integer id;
private String photoURL;
private ArrayList<String> ProjectName;
private ArrayList<String> TechnologyList;
private ArrayList<String> InterestList;
//Getters and setters
}
While the Web Developers need the entire fields and mobile developers just require two fields from it whereas the iPad requires something in between mobile and web.
Since I am using jackson as a parser, is there a way where while requesting to the controller I can specify which all data I require and avoid the others. For example consider I do a GET request like
GET>http://somedomain.com/users?filter=name,id,photoUrl
Which returns me a JSON structure something like
{
"name":"My Name",
"id":32434,
"photoUrl":"/sss/photo.jpg"
}
Sameway if someone asks for some more fields, they could be filtered. Please let me know how this can be done so that my API remains generic and useable for all.
You can achieve what you want but some extra work is necessary. I can offer you two solutions.
1. Return a Map
Simply put every property that is requested into the map.
2. Use Jacksons Object Mapper directly
Jackson lets you set filters that specify which properties are serialized or ignored.
FilterProvider filter = new SimpleFilterProvider().addFilter("myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept(requestedProperties));
String json = objectMapper.writer(filter).writeValueAsString(value);
You can then return the JSON string directly instead of an object.
For both solutions you would ideally write a class that does the job. But if you do that you could as well write your own message converter. You could extend the MappingJackson2HttpMessageConverter, for instance, and overwrite the writeInternal method to suit your needs. That has the big advantage that you don't need to change your controllers.
The straightforward solution is to implement custom Jackson JSON serializer that will get field names that should be serialized from thread local storage and then serialize only fields which names are presented in that context. For other hand, in controller you can grab all allowed fields names from url and store them into thread local context. Hope this helps.

Struts2 type conversion of a flattened JSON object in a query string

EDIT: Changed question title and content. Upon reading the JSON plugin guide I realize the plugin might be expecting a JSON string instead of this query map, in which case I normally go with GSON instead. I guess the question becomes: how can Struts2 handle type conversion of a query string like this: sort[0][field]=status&sort[0][dir]=asc
I am using Kendo UI grid to interface with my Struts2 backend. The AJAX request being sent to the server follows the following format (GET query string):
take=5&skip=0&page=1&pageSize=5&sort%5B0%5D%5Bfield%5D=status&sort%5B0%5D%5Bdir%5D=asc
or (non-escaped):
take=5&skip=0&page=1&pageSize=5&sort[0][field]=status&sort[0][dir]=asc
Basically, Kendo UI grid is sending a flattened JSON object to the server. So I create a sort model object like so to take the input:
public class SortModel {
private String field;
private String dir;
}
and include this in my Struts2 action as a variable to be populated:
private SortModel[] sort;
However, this never gets populated by Struts2 when the AJAX request comes in. I also tried to add the JSON interceptor, but I think I misunderstood its deserialization process, as explained in the edit.
Anyway, has anyone managed to Struts2 type conversion working using the above query string or similar: sort[0][field]=status&sort[0][dir]=asc?
sort[0][field]=status&sort[0][dir]=asc
The above is not proper JSON, strings should be quoted. With that done the following will work.
In which case a field (or json parameter) in the form name[i]['s'] which has a value of String and where i is an integer and s is any string would be backed by:
private List<Map<String, String>> name = new ArrayList<Map<String, String>>();
//getter AND setter required
PS: With Struts2 you can index into lists of lists of lists... without issue.
Okay.
It turns out that vanilla Struts2 doesn't accept query strings in the format obj[idx][property] (feel free to correct me on this). I was expecting it to convert the query string to an array of that specific object.
What Struts2 does accept is the format obj[idx].property which it will correctly convert to private Object[] obj.
So I guess the possible solutions to this would be:
JSON.stringify(jsonObj) before passing it to the query string, a la &jsonData=[{property:'value'}] - which in this case, I can't do since Kendo UI grid doesn't seem to have an interceptor-like event to let me change the query parameters. Or,
Implement a custom type converter that handles this particular format. Or,
Intercept the AJAX request before it is being sent to the server and re-format the query string, using jQuery.ajaxSend e.g.
$(body).ajaxSend(function(event, req, settings){
console.log(settings.url); //contains the url string to replace
settings.url = settings.url.replace(some_regex, 'correct format');
});

Categories

Resources