How to get JSON response from controller to another controller in Spring - json

I have one controller in an app that returns JSON data, like so:
#RequestMapping(value = "/{number}", method = RequestMethod.GET)
#ResponseBody
public String number(
HttpServletRequest request,
HttpServletResponse response,
#PathVariable int number
) {
JSONObject dataObject = new JSONObject();
dataObject.put("firstName", "Sheelten");
dataObject.put("lastName", "Pestay");
JSONArray data = new JSONArray();
data.put(dataObject);
return data.toString();
}
I have another controller on a different app, that I want to receive the JSON data, like so:
#RequestMapping(
value = "/data/test/",
method = RequestMethod.GET
)
#ResponseBody
public String testService(
HttpServletRequest request,
HttpServletResponse response,
Model model
) {
return response.toString();
}
I'm not really sure how I would go about receiving the JSON data into my testService controller method. I've tried googling and using the response object with no luck.
Anyone have an idea how I'd do this?

Found an answer, in case anyone else is ever looking for a solution to this.
If you are using Java with Spring, use the RestTemplate class. See below:
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://yoururl/here", String.class);
The string result will be your JSON string.

Related

Spring Boot REST multi part request (file + json) throwing 415 Unsupported Media Type exception

I am using spring boot version = 1.5.2.RELEASE.
When I am sending multi part file with json object to upload file in postman, It throwing 415 Unsupported Media Type exception.
This is my controller class.
#RestController
#RequestMapping("/service/promotion/")
public class JobController {
....
....
....
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> createJobTest(#Valid #RequestBody JobRequest jobRequest,
#RequestParam(value = "file", required = false) MultipartFile multiPartFile) throws Exception {
My json request class.
public class JobRequest {
private String campaignKey;
private String communicationId;
private Integer channelId;
private String templateType;
private String subject;
private String frequencyControl;
private Integer leadsRequested;
private String keywordRelavance;
private String scheduledAt;
private String file;
private String updatedBy;
//getter and setter
}
Json request in postman
Multipart file request in postman
Header Content-type
But when I removed consumes from controller class and from postman as well like
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json")
then debugger coming in controller class but multi part file value coming
null in request object like
I googled a lot there are many similar questions which already posted but none of them helped me.
Please help me to sort out this mystery.
Thank you.
Check this File upload along with other object in Jersey restful web service
Another way is you can pass whole object in text like you are passing file in form-data and convert in object.
#RequestMapping(value = "/uploadDocs", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> methodName(#RequestParam("files") MultipartFile file, #RequestParam("anyKeyName") String objectString)
Than you can convert string to object using
Class object = new ObjectMapper().readValue(objectString, Class.class);

Trying to receive JSON in Spring controller for a post but it is coming in as null, how do I fix this?

I want to receive a JSONObject which I will later convert to my own Object within Spring. This is my controller code where objJson has null values:
#RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, value ="postObj")
public void postObj(#RequestBody JSONObject objJson){
objCompleteService.insertObj(objJson);
}
I'm sending this with postman:
{"obj":"Test","objId":0,"definition":"post","languageId":0,"meaning":"post","submitterId":0}
and have set the Content-Type to application/json; charset=UTF-8
objJson is coming in as null.
You will get JSON as map. Paylod is the whole JSON object. You can deserialize the object as you like. if you are sending raw data use #RequestBody but if you are sending form data use #RequestParam
#PostMapping(value = "/postObj")
#Timed
public void postObj(#RequestBody Map<String, Object> payload){
JSONObject jsonObject = new JSONObject(new ObjectMapper().writeValueAsString(payload));
}

Spring Boot controller to forward general json

In a Spring Boot controller, I am receiving json and want to "forward" it without any processing:
#RequestMapping(value = "/forward", method = RequestMethod.POST)
public void abc(#RequestBody GeneralJsonRepresentation json, HttpServletRequest request) {
restTemplate.postForEntity(endpoint, json, Object.class)
}
Is it possible to accomplish this, for instance with an implementation of GeneralJsonRepresentation, assuming the controller has no knowledge of the json format and that the received content type is application/json?
You may not even need the GeneralJsonRepresentation if you just use a String.
I created a small working snippet:
#RequestMapping(path="/forward", method = RequestMethod.POST)
public ResponseEntity<String> forward(#RequestBody String postData) {
// maybe needed configuration
final RestTemplate restTemplate = new RestTemplateBuilder().basicAuthorization("user", "password").build();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(postData, headers);
final String targetUrl = "http://targethost/endpoint";
final ResponseEntity<String> response = restTemplate.postForEntity(targetUrl, entity, String.class);
return ResponseEntity.created(...).build();
}

Backbone.js Collection.sync & spring endpoints

I have a backbone.js client app and Spring on the app tier. In Backbone I'm using a Collection of 'ServerConfig' objects... the URL of the backbone collection points to a spring endpoint.
The 'GET' request returns an ArrayList of a POJO called 'ServerRuntimeConfig' which ultimately ends up returning a JSON response with the following response body:
[{"useIUX":true,"serverDomainName":"localhost","selected":true}]
The 'PUT' request, which is called when I do a 'sync' on the collection sends the following JSON request with the below request body (same as the GET):
[{"useIUX":true,"serverDomainName":"localhost","selected":true}]
The problem is that I can't get spring to automatically map the JSON collection into a collection of POJOs on the PUT... so I've had to do it manually.
Here is the GET end point
#RequestMapping(value = "/runtimeConfigs",
method = RequestMethod.GET,
produces = "application/json")
#ResponseBody
public ArrayList<ServerRuntimeConfig> handleConfigRequest(
HttpServletRequest request,
HttpServletResponse response) {
// first grab all of the hostnames from the properties file
ArrayList<String> allServersDomains = new ArrayList();
List<String> servers = Arrays.asList(
StringUtils.tokenizeToStringArray(
this.getAppProperties().get("serverList"), ","));
allServersDomains.addAll(servers);
MyTTJMXClient jmxClient = new MyTTJMXClient();
return jmxClient.readRemoteConfigurations(allServersDomains);
}
Here is the PUT endpoint
#RequestMapping(value = "/runtimeConfigs",
method = RequestMethod.PUT,
consumes = "application/json",
produces = "application/json")
#ResponseBody
public ArrayList<ServerRuntimeConfig> handleConfigUpdate(
#RequestBody String body,
HttpServletRequest request,
HttpServletResponse response) {
String jsonSource = body;
ObjectMapper mapper = new ObjectMapper();
ArrayList<ServerRuntimeConfig> serverConfigs = new ArrayList();
try {
serverConfigs = mapper.readValue(jsonSource,
new TypeReference<ArrayList<ServerRuntimeConfig>>() { } );
} catch (IOException e) {
e.printStackTrace();
}
MyTTJMXClient jmxClient;
jmxClient = new MyTTJMXClient();
return jmxClient.setRemoteConfigurations(serverConfigs);
}
Is there a way to avoid the manual Jackson mapping I'm doing in the PUT endpoint? I tried the following endpoint signature but serverConfigs is always null
#RequestMapping(value = "/runtimeConfigs",
method = RequestMethod.PUT,
consumes = "application/json",
produces = "application/json")
#ResponseBody
public ArrayList<ServerRuntimeConfig> handleConfigUpdate(
ArrayList<ServerRuntimeConfig> serverConfigs,
HttpServletRequest request,
HttpServletResponse response) {
Again, the manual Jackson mapping does the trick, but it's not using the awesomeness that is Spring.
Has anyone else out there built a Spring end point that automatically maps Backbone/JSON collections to POJOs?
Assuming the mapping you've used in your PUT method works,
Try to change your method signature from:
#ResponseBody
public ArrayList<ServerRuntimeConfig> handleConfigUpdate(
ArrayList<ServerRuntimeConfig> serverConfigs,
HttpServletRequest request,
HttpServletResponse response) {
to:
#ResponseBody
public ArrayList<ServerRuntimeConfig> handleConfigUpdate(
#RequestBody ArrayList<ServerRuntimeConfig> serverConfigs,
HttpServletRequest request,
HttpServletResponse response) {
The #RequestBody annotation is the important part here. It will automatically use spring's converter (in this case, jackson) to populate the variable.

Serve JSON "as is" from Spring controller using content negotiation

In my webapp, all my message converters are in place, and if I change getContent below to return a bean/pojo, it returns as " application/json;charset=UTF-8", which is expected, but I now want to serve JSON "as is".
E.g. I have a simple stub web service with which users can PUT a blob of JSON content which is persisted somewhere, and then an equivalent GET call to read it back.
#Controller
public class StubController {
#Autowired
#Qualifier("keyValueStore")
private KVStore kv;
#RequestMapping(value = "/stub/{id}", method = RequestMethod.GET)
public #ResponseBody
String getContent(#PathVariable("id") final String id) {
return kv.get(id);
}
#RequestMapping(value = "/stub/{id}", method = RequestMethod.PUT)
public String putContent(#PathVariable("id") final String id, #RequestBody String body) {
kv.set(id, body);
return "redirect:/stub/"+id;
}
}
However, the getter returns header "Content-Type: text/html;charset=UTF-8" if I call http://host/stub/123.json in the browser. My guess that this is happening is because I'm not returning anything that is "converted" by the Jackson converter, hence the return header isn't modified.
I need it to be application/json -- any ideas what to do? Perhaps an annotation with which I can specify the return headers?
I managed to get around this by adding an HttpServletResponse param to my getContent() method and setting the content type directly.
http://forum.springsource.org/showthread.php?t=97140
#RequestMapping(value = "/stub/{id}", method = RequestMethod.GET)
public #ResponseBody String getContent(#PathVariable("id") final String id, HttpServletResponse response) {
response.setContentType("application/json");
return kv.get(id);
}