How to read data from a website using spring mvc? - rest

I am new to Spring MVC. I am trying to create a REST API in which I have to read data from a website and then parse it.
I am so confused please help.

The question is generic, could you tell where exactly you stopped?
Maybe you want to do something like this in your rest API:
#RequestMapping(value = "yourUrl", method = RequestMethod.GET)
public ResponseEntity<List<Exercicio>> listarExercicios(YourObject object) {
object = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", YourObject.class);
return ResponseEntity.status(HttpStatus.OK).body(object);
}

Related

How to add pagination and extra links in response?

I am using ASP.NET core 1.1, and I am currently creating a Rest API.
In order to respect the conventions of a Rest architecture, I would like to add pagination and extra information before sending response.
This is my controller:
[HttpGet(Name = "GetUniversities")]
public IEnumerable<University> GetUniversities()
{
return _univRepository.GetAll();
}
GetAll():
public IEnumerable<University> GetAll()
{
return _context.Universities.ToList();
}
Actually, what I wanna do is to render something like this.
JSON reponse
But I don't know how to generate this kind of data dynamically.
Thanks!
I am not sure what you mean by extra information. But, you could build a view model to send information back to the user. That way you can tag along any other information you need to send in the response. Here is a simple example to get you started with pagination. You can obviously flow this down to your repository as well.
[HttpGet()]
[Route("api/GetUniversities/Page/{page:int}")]
public IEnumerable<University> GetUniversities(int page)
{
return _univRepository.GetAll().Skip(page*10).Take(10);
}
The above is assuming that you are sending back 10 at a time.

Using Postman to test REST persistence endpoints

I have been trying to build a secured REST endpoint to save (and return) a person object. So far I have a method as below:
#RequestMapping(value = "/save/", method = RequestMethod.POST)
public Person save(#RequestBody Person person) {
return repository.save(person);
}
I have been trying to use Postman to test this endpoint, but don't seem to be able to structure the URL in the correct way. I should say that I have successfully tested find(Long id) (/find/{id}) and findall.
http://localhost:8080/api/save?person={"id":2,"first":"Brian","last":"Smith"}
First, is this the correct way to structure an endpoint for saving an object, and is the Postman structure correct?
Your method is POST. So you should pass on your payload like this.
Also make sure that you have mentioned your web application context root. If api is your context root, then you are correct. But if it is the case then change it to some meaningful name.

With Spring Data REST, how to make custom queries use the HATEOAS output format?

I'm learning the Spring 4 stuff by converting an existing Spring 3 project. In that project I have a custom query. That query fetches data in a straightforward way, after which some heavy editing is done to the query results. Now the data is sent to the caller.
I plan on extending CrudRepository for most of my simple query needs. The data will be output in HATEOAS format.
For this custom query I think I should be adding custom behavior (spring.io, "Working with Spring Data Repositories", Section 1.3.1, "Adding custom behavior to single repositories").
As an example:
#Transactional(readOnly = true)
public List<Offer> getFiltered(List<Org> orgs, OfferSearch criteria) {
List<Offer> filteredOffers = getDateTypeFiltered(criteria);
filteredOffers = applyOrgInfo(orgs, filteredOffers);
filteredOffers = applyFilterMatches(filteredOffers, criteria);
return sortByFilterMatches(filteredOffers);
}
(The code merely illustrates that I don't have a simple value fetch going on.)
If I could use the raw results of getDateTypeFiltered(criteria) then I could put that into a CrudRepository interface and the output would be massaged into HATEOAS by the Spring libraries. But I must do my massaging in an actual Java object, and I don't know how to tell Spring to take my output and emit it in my desired output format.
Is there an easy way to get there from here? Or must I try things like do my filtering in the browser?
Thanks,
Jerome.
To properly get HAL formatted results, your query controllers must return some form of Spring HATEOAS Resource type.
#RequestMapping(method = RequestMethod.GET, value = "/documents/search/findAll")
public ResponseEntity<?> findAll() {
List<Resource<Document>> docs = new ArrayList<>();
docs.add(new Resource<Document>(new Document("doc1"), new Link("localhost")));
docs.add(new Resource<Document>(new Document("doc2"), new Link("localhost")));
Resources<Resource<Document>> resources = new Resources<Resource<Document>>(docs);
resources.add(linkTo(methodOn(ApplicationController.class).findAll()).withSelfRel());
resources.add(entityLinks.linkToCollectionResource(Document.class).withRel("documents"));
return ResponseEntity.ok(resources);
}
I have submitted a pull request to Spring Data REST to update its reference docs to specify this in http://docs.spring.io/spring-data/rest/docs/2.4.0.RELEASE/reference/html/#customizing-sdr.overriding-sdr-response-handlers
I am not sure I perfectly got your question. If I did this should be the answer: http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#repositories.custom-implementations

Difference between redirect:prefix and forward:prefix in Spring MVC3.0

Hi I am new to Spring MVC i am following Spring reference documentaion I have doubt in view resolver. Here is my sample code.
#Controller
#RequestMapping("/form")
public class MyController {
#RequestMapping(method = RequestMethod.GET)
public String setupForm() {
// do my stuff
return "myform";
}
#RequestMapping(method = RequestMethod.POST)
public String processForm(ModelMap model) {
// process form data
model.addAttribute("notification", "Successfully did it!");
return "redirect:/form";
}
}
here i am using two controllers, the first one returns "myform" and second one returns "redirect:/form". My question is, what is the difference between these two and how it works?
If you are familiar with jsp servlet, I think you can know the difference between redirect and forward, or you can get tons of answers from google. Then I want to explain a bit about how Spring does this. in setupForm method, it returns myform, then according to your view resovler configuration, it will try to find a myform.jsp or another likes this, and if your view resovler is internalresourceviewresovler, Spring will do a forward automatically and try to find this jsp in web-inf directory, if not, you have to specify a forward prefix. and for processForm method, that after return redirect:/form, it will force browser to send a new request /form to server which can be got by spring mvc and it will handle it with the related method.

Complex (non string) return type for Jersey REST method

I'm having trouble setting something up that I'm pretty sure /should/ be easy, so I thought I'd throw it to the crowd. I can't seem to find what I'm looking for elsewhere on the web or on SE.
I am simplifying my project of course, but basically I have a JAX-WS annontated Jersey resource class that looks something like this:
#Path("myresource")
public class MyResource {
#Autowired
MyComplexObjectDAO daoInstance;
#Path("findObject/{id}")
#GET
public MyComplexObject findObject( #PathParam(value="id") String id ) {
return daoInstance.findObject( id );
}
#Path("saveObject")
#PUT
public MyComplexObject saveObject( MyComplexObject objectToSave ) {
MyComplexObject savedObject = daoInstance.saveObject( objectToSave );
return savedObject;
}
}
So you can see I'm autowiring a DAO object using spring, and then I use the DAO methods in the REST handlers.
The 'findObject' call seems to work fine - so far it works exactly as I expect it to.
The 'saveObject' call is not working the way I want and that's what I need some advice on.
You can see that I'm trying to directly take an instance of my complex object as a parameter to the REST method. Additionally I would like to return an instance of the complex object after it's been saved.
I put together some 'client' code for testing this out.
#Test
public void saveTest() {
WebResource wsClient = createWebServiceClient();
MyComplexObject unsavedInstance = createMyComplexObject();
MyComplexObject savedInstance =
wsClient
.path("saveObject")
.accept(MediaType.APPLICATION_XML)
.put(MyComplexObject.class, unsavedInstance);
assertNotNull(savedIntent);
}
Which is returning the following error:
com.sun.jersey.api.client.UniformInterfaceException: PUT http://localhost:8081/rest/myresource/save returned a response status of 400 Bad Request
I don't see why this isn't working and I think I've tried just about everything I can think of. Any help or direction would be very much appreciated.
Thanks so much!
I see that you call the accept() method in your test client (which means that a "Accept:" header is added to the request, indicating the server what type of representation you would like). However, you don't call the type() method to add a "Content-type:" header and inform the server that you are sending XML data. See http://jersey.java.net/nonav/documentation/latest/client-api.html#d4e644 for examples.
Side remark: your URLs are not RESTful - you should avoid verbs in your path:
So, instead of:
/api/findObject/{id}
/api/saveObject
You should use:
/api/objects/{id}
/api/objects
Last note: to create an object on calling /api/objects, you should do a POST and not a PUT to adhere to REST best practices and widely adopted patterns.
switching to the 'concrete class' solution I alluded to in my earlier comment is what fixed things up for me.