How to return JSON from spring RESTful service and access it using RestTemplate class - spring

I made a spring RESTful web service for giving list of top songs in JSON formate, for this I added song names in a List and I returned this from the #Restcontroller of my Spring RESTful web service.SO #RestController will automatically process this List and rturns me this JSON form ["song1","song2","song3"].
Now can any body tell me how I can return song names with some more attribute like
- (Song Name , Film, Lyricist, Singer(s), Total hits)
For Example - (“Lungi Dance”, “Chennai Express”, "Honey Singh", "Honey Singh”, 5000).Also tell me how can I access it my spring MVC application calling this web service using RestTemplate.
Please tell me the changes in below files.
Inside my #RestController class of my Spring RESTful web service
#RequestMapping(value = "/topsongsWS", headers="Accept=application/json")
Public List<?> getTopSongsWS()
{
List<String> l1 = new ArrayList<String>();
l1.add("mann mera (Table No 21)");
l1.add("Lazy lad (Ghanchakkar)");
l1.add("Oye boy Charlie (Matru Ki Bijli Ka Mandola)");
l1.add("Blue Hai Pani Pani");
l1.add("Latt lag gayi (Race 2)");
return l1;
}
Inside my config-servlet.xml
<context:component-scan base-package="com.songs.service.controller" />
<mvc:annotation-driven />
Inside the controller of my spring MVC app calling this above RESTful web service
#RequestMapping(value="/topsongs",method=RequestMethod.POST)
public String getTopSongs(ModelMap md)
{
//did stuff to configure headers & entity
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
//this is the URL of my RESTfulservice returning JSON format ["song1","song2","song3"]
String url="http://localhost:7001/SongAppWS/songappWS/topsongsWS";
RestTemplate rt=new RestTemplate();
ResponseEntity<?> listoftopmovies=rt.exchange(url,HttpMethod.GET,entity, List.class);
md.addAttribute("listname", "Top 5 Songs of The Week:");
String response=listoftopmovies.getBody().toString();
List<String> listed = new ArrayList<String>(Arrays.asList(response.split(", ")));
md.addAttribute("res",listed);
return "Sucess";
}

To return your songs with more attribute, you should create a resource representation class.In your case,it could look like
class Song {
private String name
private String film
//other fields and methods...
Then in your restfull ws
#RequestMapping(value = "/topsongsWS", headers="Accept=application/json")
public List<?> getTopSongsWS()
{
List<Song> l1 = new ArrayList<Song>();
l1.add(new Song(atr1,atr2....));
l1.add(new Song(atr1,atr2....));
l1.add(new Song(atr1,atr2....));
return l1;
}
In your spring mvc app, you should have too the resource representation class, and the response type will now be Song instead of String
To consume your ws, this should work
#RequestMapping(value="/topsongs",method=RequestMethod.POST)
public String getTopSongs(ModelMap md)
{
String url="http://localhost:7001/SongAppWS/songappWS/topsongsWS";
RestTemplate rt=new RestTemplate();
Song[] songs = template.getForObject(url, Song[].class);
md.addAttribute("listname", "Top 5 Songs of The Week:");
md.addAttribute("res", Arrays.asList(songs));
return "Sucess";
}

you have to use model class like List
Please have a look this below source code in github. It has json response as object. Hope it will help.
https://github.com/mohansaravanan/spring
https://github.com/mohansaravanan/spring/tree/master/springmvc-3.2.2

Related

How to fetch url api "http://terriblytinytales.com/test.txt" in spring boot

I am using Rest Template :- TO fetch The data
#RestController
public class apicontroller {
#Autowired
public RestTemplate restTemplate;
#RequestMapping(value="/movies",method = RequestMethod.GET,consumes = MediaType.TEXT_PLAIN)
public List<Object> getobject(){
Object[] movies=restTemplate.getForObject("http://terriblytinytales.com/test.txt",Object[].class);
return Arrays.asList(movies);
}
}
It is not fetching the data as its content type is text/plain
What should i do to change Content type here
Text content can't be assigned to an array. Change Object[] to String.
String movies = restTemplate.getForObject("https://terriblytinytales.com/test.txt", String.class);

Camel rest API to provide dynamic download

How can we provide document download using camel API, I need to provide an api using camel rest to response the file as download and I have the logic to create the pdf using apache fop, but i need to get some information how to respond the file as rest response using camel rest.
#RestController
public class MyController {
#Autowired
ICityService cityService;
#RequestMapping(
value = "/pdfreport",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_PDF_VALUE
)
public ResponseEntity<InputStreamResource> citiesReport() throws IOException {
List<City> cities = (List<City>) cityService.findAll();
ByteArrayInputStream bis = GeneratePdfReport.citiesReport(cities);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline;
filename = citiesreport.pdf");
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
}

Spring boot/Spring MVC - How to forward a response from another request

I need a rest end point whose response is HTML. But instead of a view defined in my project, i would like to forward the HTML response from another request made inside that rest end point.
For example, my rest end point makes a http request to an internal service and returns the HTML returned from that service? Is it possible? Any thoughts?
Here is a code example
#RequestMapping("/test")
public String testMe(Model model, #RequestParam("param1") String param1, #RequestParam("param2") String param2)
{
//Make a Http call to an internal service and return the response from that call
return "<RESPONSE_FROM_THAT_CALL>";
}
I would like to return the HTML response from the internal service
You can use a RestTemplate to fetch the result from the other service and just return it as a String:
#Controller
public class MyController {
private RestTemplate restTemplate = new RestTemplate();
#ResponseBody
#RequestMapping("/test")
public String testMe(Model model, #RequestParam("param1") String param1, #RequestParam("param2") String param2) {
URI uri = UriComponentsBuilder.fromHttpUrl("http://www.example.com");
.queryParam("param1", param1)
.queryParam("param2", param2)
.build()
.toUri());
return restTemplate.getForObject(uri, String.class);
}
}
If you'll have more endpoints that you wanna proxy to another service, you should consider using e.g. Zuul as a micro proxy. See e.g. this blog post explaining how you can easily create such a proxy.

Multiple scenarios #RequestMapping produces JSON/XML together with Accept or ResponseEntity

I am working with Spring 4.0.7
About Spring MVC, for research purposes, I have the following:
#RequestMapping(value="/getjsonperson",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody Person getJSONPerson(){
logger.info("getJSONPerson - getjsonperson");
return PersonFactory.createPerson();
}
#RequestMapping(value="/getperson.json", method=RequestMethod.GET)
public #ResponseBody Person getPersonJSON(){
logger.info("getPerson - getpersonJSON");
return PersonFactory.createPerson();
}
Each one works fine, observe both for JSON, with and without extension:
/getjsonperson
/getperson.json
Same for XML
#RequestMapping(value="/getxmlperson",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_XML_VALUE
)
public #ResponseBody Person getXMLPerson(){
logger.info("getXMLPerson - getxmlperson");
return PersonFactory.createPerson();
}
#RequestMapping(value="/getperson.xml", method=RequestMethod.GET)
#ResponseBody
public Person getPersonXML(){
logger.info("getPerson - getpersonXML");
return PersonFactory.createPerson();
}
Each one works fine, observe both for XML, with and without extension:
/getxmlperson
/getperson.xml
Now about Restful I have the following:
#RequestMapping(value="/person/{id}/",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Person> getPersonCustomizedRestrict(#PathVariable Integer id){
Person person = personMapRepository.findPerson(id);
return new ResponseEntity<>(person, HttpStatus.FOUND);//302
}
Observe the MediaType, it is mixed, for JSON and XML
Through RestTemplate I can indicate the Accept value
if(type.equals("JSON")){
logger.info("JSON");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
}
else if(type.equals("XML")){
logger.info("XML");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
}
….
ResponseEntity<Person> response =
restTemplate.exchange("http://localhost:8080/spring-utility/person/{id}/customizedrestrict",
HttpMethod.GET,
new HttpEntity<Person>(headers),
Person.class,
id
);
Until here, therefore I am able to use one URL/URI to get some data in either XML or JSON formats. It works fine
My problem is with Spring MVC … just consider
#RequestMapping(value="/{id}/person",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public #ResponseBody Person getPerson(#PathVariable Integer id){
return personMapRepository.findPerson(id);
}
I can call or activate that handler method (#RequestMapping) through:
jQuery working with Ajax, I am able to indicate the Accept value (JSON for example)
Poster, through the Headers button, I can set the Accept
Question One:
But for a common link? how I can set the Accept value? is possible?
I thought in other way to around this problem.
http://localhost:8080/spring-utility/person/getpersonformat?format=json
http://localhost:8080/spring-utility/person/getpersonformat?format=xml
Observe:
?format
Therefore
#RequestMapping(value="/getpersonformat",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public #ResponseBody Person getPerson(#RequestParam String format){
return personMapRepository.findPerson(id);
}
Question Two:
What code for the method shown above must be added to customize the return type format?
I mean, JSON or XML, Is possible?
I thought in the following:
#RequestMapping(value="/getpersonformataltern",
method=RequestMethod.GET
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE}
)
public ResponseEntity<Person> getPersonFormat(#RequestParam String format){
logger.info("getPersonFormat - format: {}", format);
HttpHeaders httpHeaders = new HttpHeaders();
if(format.equals("json")){
logger.info("Ok JSON");
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
}
else{
logger.info("Ok XML");
httpHeaders.setContentType(MediaType.APPLICATION_XML);
}
return new ResponseEntity<>(PersonFactory.createPerson(), httpHeaders, HttpStatus.OK);
}
But:
If I execute the URL:
http://localhost:8080/spring-utility/person/getpersonformataltern?format=json
I get
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id>1</id>
<firstName>Manuel</firstName>
<lastName>Jordan</lastName>
…
</person>
Yes in XML!
Note: I can confirm the Console prints Ok JSON
If I execute the URL:
http://localhost:8080/spring-utility/person/getpersonformataltern?format=xml
I get
This XML file does not appear to have any style information associated with it.
The document tree is shown below.
<person>
<id>1</id>
<firstName>Manuel</firstName>
<lastName>Jordan</lastName>
…
</person>
Question Three
What code for the method shown above must be added to fix the JSON output?
I don't know what is wrong or is missing..
There are three questions.
Thank You
Alpha
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Map<String,MediaType> mediaTypes = new LinkedHashMap<>();
mediaTypes.put("json", MediaType.APPLICATION_JSON);
mediaTypes.put("xml", MediaType.APPLICATION_XML);
configurer.mediaTypes(mediaTypes);
configurer.defaultContentType(MediaType.TEXT_HTML);
}
Using Accept header is really easy to get the format json or xml from the REST service.
This is my Controller, take a look produces section.
#RequestMapping(value = "properties", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}, method = RequestMethod.GET)
public UIProperty getProperties() {
return uiProperty;
}
In order to consume the REST service we can use the code below where header can be MediaType.APPLICATION_JSON_VALUE or MediaType.APPLICATION_XML_VALUE
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", header);
HttpEntity entity = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/properties", HttpMethod.GET, entity,String.class);
return response.getBody();
Edit 01:
In order to work with application/xml, add this dependency
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
All your problems are that you are mixing content type negotiation with parameter passing. They are things at different levels. More specific, for your question 2, you constructed the response header with the media type your want to return. The actual content negotiation is based on the accept media type in your request header, not response header. At the point the execution reaches the implementation of the method getPersonFormat, I am not sure whether the content negotiation has been done or not. Depends on the implementation. If not and you want to make the thing work, you can overwrite the request header accept type with what you want to return.
return new ResponseEntity<>(PersonFactory.createPerson(), httpHeaders, HttpStatus.OK);
I've preferred using the params filter for parameter-centric content-type.. I believe that should work in conjunction with the produces attribute.
#GetMapping(value="/person/{id}/",
params="format=json",
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Person> getPerson(#PathVariable Integer id){
Person person = personMapRepository.findPerson(id);
return ResponseEntity.ok(person);
}
#GetMapping(value="/person/{id}/",
params="format=xml",
produces=MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<Person> getPersonXML(#PathVariable Integer id){
return GetPerson(id); // delegate
}

Make Rest Client using Spring Rest Template

Here is my spring controller code..
#RequestMapping(value= "/save_item",
method = RequestMethod.POST,produces="application/json")
public #ResponseBody ModelMap saveItem(ModelMap model,
#RequestParam("id") String itemId,
#RequestParam("name") String itemName) {
model.addAttribute("itemId",itemId);
return model;
}
How can i make a rest client using spring rest tempalte?.
I need to send two parameters from my rest client(id,name).
Anyone Please help me.
Thanks.
You can create a RestTemplate object and execute as this
ResponseEntity<List<City>> result = restTemplate.exchange(
new StringBuilder(URL).append(city).toString(),
HttpMethod.GET, null, responseType);
In this project you can find a maven project with spring-boot and sptring-web that uses this restTemplate snippet and jackson for the json response
https://github.com/voliveirajr/dev-test

Resources