How to send Large POJO response from spring boot to client - java

Hey I am having a POJO Class, after some code execution it contain result to be sent as Response from sprint controller.
PojoClass {
List<String> list = new ArrayList<String>();
// other variable
}
#RequestMapping(value="/someUrl", method=RequestMethod.GET)
public PojoClass getResult(#RequestParam(PRRQConstants.BUG_ID) String
bugId,HttpServletRequest request) throws Exception
{
// call service
// processing in service
return PojoClass;
}
Everything works fine if the size of list is small. But if it contain more than 2 million or a million elements, also after processing everything it stuck in sending Response back from controller to client.
Why this is happening ?

Related

Test of endpoint that sends a request to external api

There is a small method mymethod that gets the response from the external api data in json format, which will be Dto and
then there is a getEnums method that selects which data to leave and returns a list of strings and as a result mymethod itself returns a list of strings.
I tried to write a test, but I get :
Expected :200
Actual :302
As I understand the problem is in the redirection, but how to solve it I do not understand, maybe you have an answer?
controller
#GetMapping(value = "api/mymethod", produces = "application/json")
public ResponseEntity<List<String>> mymethod(#RequestHeader(value = "Enum") String Enum,
#RequestParam(value = "Type") String Type) {
URI uri = UriComponentsBuilder.fromUriString("...url...").build().toUri();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(null, headers);
ResponseEntity<myDto> response =
restTemplate.exchange(uri, HttpMethod.GET, entity, myDto.class);
List<String> currencies =
getEnums(response, Type); // <- custom method
return new ResponseEntity<>(currencies, HttpStatus.OK);
}
// (The test is not written in full, left exactly the problem area)
test
#Test
public void mytest() throws Exception{
ResultActions getResult = mockMvc.perform(get("/api/mymethod")
.header("Enum", "OOL")
.param("Type", "Counter"))
.andExpect(status().isOk());
}
The problem with testing against an external service is that you do not manage it's state. Therefore your test cases may show varying results even if you did not change anything.
Usually you'd create a mock of the REST api your test object would access. Then you can send requests to your test object and check in the mocked api whether the expected requests did come in. You can also fake success or error responses and check how your test object reacts.
To finally answer your question: How do you want your client to treat a redirection? Should it follow or error out? Looking at the meaning of status 302 it means the resource has moved temporarily or at least was found at a new location. This might mean a valid redirect if the server is trying to loadbalance or tries to point out a url that is closer to you network-wise. Therefore I believe the client should follow a 302.

How i can pass a list<String> to the server with url

I am trying to pass the List of String from one server to the another server in spring boot.
How i can get that list at the another server?
The code i have tried-
public void addNewMostPopular(List<String> totalList){
try {
HttpHeaders httpHeaders = getHttpHeaders();
HttpEntity<String> httpEntity = new HttpEntity<String>(null, httpHeaders);
ResponseEntity responseEntity = restTemplate.exchange(
BASE_URL + "addMostPopular/"+new ArrayList<>(totalList), HttpMethod.POST, httpEntity,TrendingCategoryDTO.class);
}
and at server side i tried to get like-
#RequestMapping(value="/addMostPopular/[{totalList}]", method = RequestMethod.POST)
public void addMostPopularProduct( #PathVariable List<String> totalList) {}
Past long object in the url is a bad praxis, thats because spring url interpreter has a maximun lenght, so if you pass more than 2048 or 4096 char in some cases your request will return Response 400 bad request and won't execute anycode on your spring server.
After this aclaration, is there any option to pass a list? Yes, of course! But we need use #RequestBodylike this:
#PostMapping("/addMostPopular")
public void addMostPopularProduct(#RequestBody List<String> totalList) {
// Your function
}
Now we need to add to our other server the List we want to pass to this request in the body of the request.
If you like to pass a List of values in the url one possibility is to pass them as url parameters.
You have to create a link similar to the followings:
http://youserver/youraction?param=first&param=second&param=third
or
http://youserver/youraction?param=first,second,third
Your controller in spring must be something like
#Controller
public class MyController {
#GetMapping("/youraction")
public String yourAction(#RequestParam("param") List<String> params) {
// Here params is tre list with the values first, second, third
}
}
This action is able to handle both kind of requests that I wrote before.
There are many ways to pass infomation between servers.
The simple way is to initiate an http request, based on your request method get or post put the parameters to the appropriate location : reuqest header or request body. You can do like #Davide Lorenzo MARINO.
Or use a message queue, like ActiveMq.
In the case of the same registry center, you can also use #feign to resolve it.

How to create generic json response Object in java?

I am new to java and creating some Restful services in netbeans using jersey framework.
I have created many GET, POST web services which is having different different type of responses which are basically Model Objects and depending upon media type I am getting JSON or XML.
Some response is having only a single object which is being shown in JSON inside {}, and some are list which are in [].
I want to see a generic response format for all api responses.
Example-
{"status":"0 or 1", "message":"any string message","result":"it can be a single object or a list of objects which is dynamic depending upon each web service response"}.
Since here in java we need to created model objects for getting responses so I have created a ResponseModel which is having a status property , message property but don't know the type of result property because sometime it can have a single object or sometime a list so what type should I set for this property so that I can assign any thing to this and response will always be in same format for JSON or XML.
I have created a static method with constructor which takes all these three parameters and create a ResponseModel object.
Thanks in advance
EDITED- Code after Using "Object" as generic type
public static Response getResponseObjectIsValid(boolean isValid, String message,Object result)
{
if (isValid == true) {
LGSResponse response = new LGSResponse();
response.setStatus(1);
response.setMessage(message.length()>0 ? message : "Success");
response.setResult(result);
return Response.status(Status.OK).entity(response).build();
}
else
{
LGSResponse response = new LGSResponse();
response.setStatus(1);
response.setMessage(message.length()>0 ? message : "Failed");
response.setResult(result);
return Response.status(Status.OK).entity(response).build();
}
}
Result Parameter is a normal model object.
You can simply create your class as you've said.
public class ResponseModel {
int status;
String message;
Object result;
// contructor, getters, setters go here...
// (probably consider using lombok, but that is a story for another time)
}
Then you can pass either a single object or an array as the 3rd param and the json/xml serializer should take care of the conversion for you unless your objects are very complex(I rarely run into that problem)
For example, your Jersey methods would look something like this:
// returning a single object within the response model
#GET
#Path("/myMethod")
public Response aJerseyMethod() {
Book aBookObject = new Book("The Title", "Name of Author");
ResponseModel responseModel = new ResponseModel(1, "This is a book", aBookObject);
return Response.ok(responseModel)
.build();
}
// returning an array within the response model
#GET
#Path("/myOtherMethod")
public Response anotherJerseyMethod() {
Book aBookObject = new Book("The Title", "Name of Author");
Book anotherBookObject = new Book("The Other Title", "Name of another Author");
ArrayList<Book> aBookArray = new Arraylist();
aBookArray.add(aBookObject);
aBookArray.add(anotherBookObject);
ResponseModel responseModel = new ResponseModel(1, "These are books", aBookArray);
return Response.ok(responseModel)
.build();
}
In both cases you should get the expected output you were talking about and you do not have to do any additional checks or conversions yourself.
I just wrote this here, so try it out with your own classes instead of "Book" (which is not a real class) and let me know if it works.
You should not maintains status code, message and result within json body.
Response message should only contain the result of that api.
Httpstatus code will be the status code (Ex.200 is success, 404 is notfound)
All the other info should be maintained in response headers, not within json body

How to post JSON to Spring server?

I get a list of object from server. One key of this objects is called body, and it is a json. It is almost impossible for me to know its keys : the key name and size of it (body) are different.
Example of data
data from server = [object, object, object,.....]
object = {
id: 1,
name: "xyz",
body": {
x: "xyz",
y: "xyz",
z: "xys",
}
}
I edit the body and then post it to the server together with the id of the object. Until here it is fine. I can send the request but can not handle the Requestparam which is of type json.
How to handle this post request on the backend built in Java and Spring?
You have to add a #RequestBody annotation to the method on the Controller such as:
#RequestMapping ("url/to/save")
#ResponseBody
public ResponseObject send (#RequestBody RequestObject myRequestObject)
{
//do something
return new ResponseObject ();
}
The RequestObject would be the Java Class mapping to the JSON you want to save. The ResponseObject is whatever you want to return, you could also return void but Firefox has issues with that sometimes.

list with error:badcfg Angularjs

I'm writing applications with Java backend and frontend in AngularJS. My problem is that I can not get data in JavaScript Controller. Although Java server sends the data correctly.
Java - Service:
#GET
#Path("/get/list/{id}")
#Produces("application/json")
public List<Room> getList(#PathParam("id") int id) {
List<Room> list = service.getList(id);
return list;
}
JavaScript - Service:
app.factory("BuildingService", function($resource, $q) {
var BuildingService,
Rooms = $resource("/api/rest/room/get/list/:id", {
id: "#id"
});
BuildingService = {
getListRooms: function(id) {
return Rooms.get({id: id}).$promise;
}
};
return BuildingService;
});
JavaScript - Controller:
app.controller("BuildingController", function($scope, $routeParams, BuildingService) {
BuildingService.getListRooms($routeParams.id).then(function(list) {
$scope.rooms = list;
}, function(err) {
console.error(err);
});
});
error in console:
Error: [$resource:badcfg] http://errors.angularjs.org/1.2.14/$resource/badcfg?p0=object&p1=array
I do not understand this error.
Please help
Regards,
You are returning from backend side List i.e. collection of rooms , so you should use query method of angular js instead of get. In your BuildingRoomService change get to query
The link that the angular error tells you what the problem is
"To resolve this error, make sure your $resource configuration matches
the actual format of the data returned from the server."
the $resource call is expecting a json array response but apparently receives an object. Check to see what is actually returned by the server, the actual json response.
Your issue may be related to this other issue: Spring 3 ArrayList serialization to JSON with Jackson without wrapping to object (without name)

Categories