When to use different request methods in spring - java

I've been tasked with creating a simple REST API, where a single double is provided, and another one is derived from it according to some rules.
When creating a controller, I made the method for parsing said base double in two ways.
#GetMapping("calculate/{income:.+}")
public ResponseEntity<?> calculateEAT(#PathVariable double income){
return ResponseEntity.ok(TaxDAO.addResult(income));
}
#PostMapping("calculate/{income:.+}")
public ResponseEntity<?> calculateEAT(#PathVariable double income){
return ResponseEntity.ok(TaxDAO.addResult(income));
}
The only difference is the type of mapping used. The only difference I noticed was that I could type income in the browser address bar with GET mapping - and it worked. With post mapping, I could only get results using Postman.
I'm assuming it's possible to write an entire controller using GET mapping. I don't really feel like it's a good practice though. Are there any rules for using Request Methods in controllers?

GET and POST requests are different HTTP methods. The browser will do a GET request when you type something in the browser address bar, that is why you can only make it work in Postman (where you can select which HTTP method to use).
You should use GET when you want to retrieve something from the REST API. You should use POST when you want to submit something to the REST API, usually creating a resource or triggering some kind of process. You can read more about each HTTP method in the following online resources:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
https://www.restapitutorial.com/lessons/httpmethods.html

Related

Can I create a response object in java without creating a servlet?

Can I create a response object in java without creating a Servlet? I have a regular java class right now called Menu. It contains not only my menus for my application but it also contains my CRUD functionality that is tied to the database. Which works fine on the console. What I want to do now is to display the result set on a webpage. I want to use AJAX (no frameworks like jQuery etc.) to capture the information from the result set. In the Menu class I am going to convert the extracted information into a Json string with Jackson databinding (object mapper). I want to use a PrintWriter to send this information back to AJAX. I am assuming I need a response object. Do I have to re-write my Menu class as a Servlet or is there another way to accomplish this?
For querying data from server you need to have a resource which has
http url
can accept a form of request as input
can give response based on business logic in menu crud class.
For this querying as you said you can do with ajax call to this servlet with specified url pattern from your frontend webpage.
In short servlet will be essential. It can handle all http method types like get post and so on.
So you can map your crud methods to your servlet methods
eg :
doGet - querying items.
doPost- creation of item.
doDelete- delete an item.
and so on.
further you will call your crud methods from these servlet do* methods.
for example refer: https://www.geeksforgeeks.org/servlet-crud-operation-with-example/
Hope this helps.

Spring REST best practice for method types

I am building a Spring RESTfull service and a I have the following method that retrieves a Place object based on given zipcode:
#RequestMapping(value = "/placeByZip", method = RequestMethod.GET)
public Place getPlaceByZipcode(#RequestParam(value="zipcode") String zipcode) {
Place place = placeService.placeByZip(zipcode);
return place;
}
Is it best practice to have the return type of "Place"? I imagine this is difficult for error handling?
Using the latest versions of Spring for a RESTfull web service I do believe returning the 'Object' is good practise as it allows you to simplify your code and be specific on what you are returning. I see this as strongly typing your API response.
A good practise for error handling is to use the controller advice utility supplied by spring.
Have a read of:
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
This allows you to throw your exceptions at any of your service layers and produce a nice helpful error response.
A better practice would be to create a Data Transfer Object with only the properties you will be using in the front end.
With a proper JS framework you could easily do proper error handling. (for example you could define a service in AngjularJs which would define the DTO's fields).
Also, you might as well do return placeService.placeByZip(zipCode);
As robinsio suggested it is good practice to add controller advice. You can set the status to some http code (for example HttpStatus.conflict) and have an exception handler (ex. BaseServiceException) which you can throw inside your place service if some validation rules you define are broken.
The controller advice could return a map which you handle in the case of the respective http status code in a consistent manner (let's say a modal appears in the interface to notify of the message you sent from the base service exception).

Dynamic URL from database and MVC in JSP

I am learning JAVA and Spring Framework. I wanted to know that is it possible in java to create Dynamic URL in spring framework using values from url and fetching from database.
I am trying to make URL Shortner in Java and I will need to lookup for url's short code in my database and as we all know, url shortner will look like "url/ShorTCode" and my script will look for "ShorTCode" keyword in database and will redirect to associated weblink.
So I wanted to know that is it even possible in JAVA and Spring? And one more thing, if I make something like this "url/yt/VIdeoCode" or "url/fb/UserProfile"
So it will look at yt object which will redirect to youtube link only and fb object which will redirect to facebook user profile.
I want to clarify that I am still learning JAVA, JSP and Spring but I want to keep this thing in my mind while I am learning so I can focus on some particular things.
Thank you all fro helping me.
If you're asking how your controller could respond with a dynamic redirect, the answer is either:
(1) Have the controller return a "redirect:" result instead of view name. It must be followed with an absolute url, and behavior might depend on your spring version and configuration, but basically it looks like this:
#RequestMapping(...)
public String myMethod(){
String url=... // database lookup, e.g. "http://myUrl"
return "redirect:"+url;
}
(2) Less elegant but sometimes useful: get direct access to the response. If your controller method has a parameter of type HttpServletResponse spring will automatically inject it. So:
#RequestMapping(...)
public String myMethod(HttpServletResponse resp){
...
response.sendRedirect(...)
}

Any simple way to test a #RequestBody method?

If I have a #Controller method whose parameter is a #RequestBody param, I usually have to write some jQuery script or something similar to perform an AJAX request with JSON object in order to call that method. If I tried calling that method via a web browser directly, it returns with a Error 415 Unsupported Media Type.
Is there any alternative to just quickly call such method using browser without having to write some jQuery code? Like perhaps a way to write the JSON object in the URL/address bar?
code:
#RequestMapping("testCall")
#ResponseBody
public List<TestObject> getTestCall (#RequestBody TestParams testParams) {
return stuff;
}
public class TestParams {
private Integer testNumber;
//getter/setter for testNumber
}
I thought maybe I could just do:
http://localhost/testCall?testNumber=1
maybe Spring would auto populate a new TestParams instance with that property set to 1 but that didnt work...
maybe I need to do something extra for that?
The whole point of a #RequestBody annotated parameters is for the Spring MVC stack to use the HTTP request body to produce an argument that will be bound to the parameter. As such, you need to provide a request body. Sending a request body is very atypical for a GET request. As such, browsers don't typically support it, at least not when simply entering an address in the address bar and submitting the request.
You'll need to use a different HTTP client, like jQuery. I typically have a small Java project in Eclipse that's setup with an Apache HTTP components client which can send HTTP requests to whatever server. It takes a few seconds/minutes to setup the correct request body and run.
I have spent the last year building a REST API, and by far the best way to exercise that API manually is using the Chrome Extension, Postman. I cannot recommend this tool enough.
https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en
To test your simple example you'll need to invoke a POST (I assume that as you have a request body, but your controller method doesn't define a HTTP Verb) using POSTMAN to your Url (like the following example):
POST /contextRoot/testCall
{
"testNumber": 1
}
If you want to test your API automatically (which I recommend), you can use the excellent Spring Mvc Test project. This allows your to call your API via a rest-like DSL and assert that the response is in the shape you want. More details can be found here:
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html#spring-mvc-test-framework
you can add request params to the getTestCall method:
#RequestParam(value = "testNumber", required = false, defaultValue = "") String testNumber
There is a chrome app called Advanced REST client. You can pass the data in form of json to your controller using this chrome app. For eg. json data is
id:1,
name:"xyz"
whereas the controller can have #RequestBody Person form.
The Person class would be a POJO having id and name as instance variables. The Spring would automatically map the json data to the form.
I think this is the easiest and simplest way of checking your spring controller.
Check the extension Advanced REST client here
From what I know You can send JSON object to the webbrowser and it will be displayed without further need of AJAX.
useful tutorial:
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

Put Rest webservices with just one parameter

I am using Java and Jersey for my REST web services. I want to have a put method that takes just one integer value. From this integer value I can then use business logic to update my database. Usually I am passing a custom DTO from my PUT as they often contain more than one piece of information. It seems a bit wasteful creating a custom DTO for just one value. Is it possible to pass this variable as a #PathParam with a PUT
I have tried
#PUT
#Path("apple/{pearId}")
public void doStuff(#PathParam("pearId") Integer pearId) {...}
but this does not work if I pass in
http://myurl/apple/123
I tried using REST client to PUT this but end up with a HTTP Status 403
Can I pass a variable as a PUT #PathParam?
Thanks
UPDATE: more details on error
The error is from REST Client
HTTP Status 403 -
type Status report
message
descriptionAccess to the specified resource () has been forbidden
I will add logging now to see if I actually get into the method
You can definitely use #PathParam with a PUT. HTTP 403 means Forbidden. This error is probably not coming from Jersey. Where is that error coming from? Does your code throw that error?

Categories