Method Not Allowed REST Java when trying to do POST - java

I just want to create a simple REST service and it uses #GET and #POST.
for the #GET function, everything is ok but for #POST, when I want to create a new user on my server the browser just keeps sating (METHOD NOT ALLOWED).
I read so many articles about how to fix this error but I haven't got anything yet.
My code for #POST :
#Path("/hello")
public class HelloResource(){
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("/post")
public Response createUser(#PathParam("name") String name,#PathParam("address") String address,#PathParam("birthYear") String birth,#PathParam("ps") String password) throws NotAllowedException,MethodNotFoundException,Exception {
DataStore.getInstance().putPerson(new Person(name, address, Integer.parseInt(birth), password));
String json = "{\n";
json += "\"status\": " + '"'+"CREATED" +'"'+ ",\n";
json+="}";
return Response.status(200).entity(json).build();
}}
I also tried adding #Consumes function with (MediaType.APPLICATION.JSON) and (MediaType.TEXT_PLAIN) but nothing changed.
Also the URL I enter for posting is :
http://localhost:8080/HelloREST/rest/hello/post?name=PouYad&address=mustbejsonlater&birthYear=2005&ps=12345
As you see I also tried so many exception handlers.
Can someone please help?

if you enter your URL in the browser URL address field, it won't work because the browser will send a "GET" request. So you must use a client that will allow you to send a "POST" like PostMan. Or write your own small httpConnection function that sends a "POST"
You also have to change the #PathParam to #FormParam for it to work (#QueryParam will also work, but because it is POST, it is best to use #FormParm).

Access URL directly through browser can only create Get Request, not POST Request
You should
Create HTML Form, set the action to your service url with POST method, and then submit it.
Use Rest Client like postman to access your service with POST method.
Write your own Http Client using java.net.http api or just simply use
one of the handy libraries/frameworks (Like Spring has RestTemplate).

Related

Cross Site Scripting support on Rest based POST Web service

I have designed a REST based post Service using Spring 3.
The service method consumes parameter as String and responds data as String. The param and response can be json or string
#RequestMapping(value = "/service", method = RequestMethod.POST)
public #ResponseBody String Service(#RequestParam("param") String param) {
Sample POST Request:
http://IP:PORT/test-project/service
param={"name":"John"}
Sample response to above request:
{"age":"31"}
Is there a way to safeguard this request against Cross Site Scripting?
If yes then how can I achieve XSS support once I receive request on param parameter??
If you aren't returning the parameter value (or any manipulation of it) in the response, you don't have an XSS vulnerability.
Not that it means that your service is completely secure, of course.

GET call with request body - request body not accessible at controller

I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
#GET
#Path("\path")
#Consumes(APPLICATION_JSON)
#Produces(APPLICATION_JSON)
public Response getResponse(String requestBody) throws IOException { }
When I replaced #GET with #POST, requestBody has value. For GET call do we need to add anything more?
I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
One thing you are missing is the fact that the semantics of a request body with GET are not well defined.
RFC 7231, Section 4.3.1:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
There are two ways for sending parameters in an Http Get method. PathVariable and RequestParam. In this way, sent parameters are visible in the request URL. for example:
www.sampleAddress.com/countries/{parameter1}/get-time?city=someValues
In the above request, parameter1 is a path variable and parameter2 is a request parameter. So an example of a valid URL would be:
www.sampleAddress.com/countries/Germany/get-time?city=berlin
To access these parameters in a java controller, you need to define a specific name for the parameters. For example the following controller will receive this type of requests:
#GetMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCities(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city
){
return "the method is not implemented yet";
}
You are able to send RequestBody through a Get request but it is not recommended according to this link.
yes, you can send a body with GET, and no, it is never useful
to do so.
This elaboration in elasticsearch website is nice too:
The HTTP libraries of certain languages (notably JavaScript) don’t allow GET requests to have a request body. In fact, some users are suprised that GET requests are ever allowed to have a body.
The truth is that RFC 7231—the RFC that deals with HTTP semantics and
content—does not define what should happen to a GET request with a
body! As a result, some HTTP servers allow it, and some—especially
caching proxies—don’t.
If you want to use Post method, you are able to have RequestBody too. In the case you want to send data by a post request, an appropriate controller would be like this:
#PostMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCitiesByPost(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city,
#RequestBody Object myCustomObject
){
return "the method is not implemented yet";
}
myCustomObject could have any type of data you defined in your code. Note that in this way, you should send request body as a Json string.
put #RequestBody on String requestBody parameter
#RequestMapping("/path/{requestBody}")
public Response getResponse(#PathVariable String requestBody) throws IOException { }

What is format from url in AJAX to send POST method with RESPONSE ENTITY

I already search tutorial in spring for method POST, insert the data with response entity (without query) and I getting error in ajax. I want to confirm, What is format url from ajax to java? below my assumption:
localhost:8080/name-project/insert?id=1&name=bobby
is the above url is correct? because I failed with this url. the parameter is id and name.
mycontroller:
#PostMapping(value={"/insertuser"}, consumes={"application/json"})
#ResponseStatus(HttpStatus.OK)
public ResponseEntity<?> insertUser(#RequestBody UserEntity user) throws Exception {
Map result = new HashMap();
userService.insertTabelUser(user);
return new ResponseEntity<>(result, HttpStatus.CREATED);
}
my daoimpl:
#Transactional
public String insertUser(UserEntity user) {
return (String) this.sessionFactory.getCurrentSession().save(user);
}
the code running in swagger (plugin maven) but not run in postman with above url.
Thanks.
Bobby
I'm not sure, but it seems that you try to pass data via get params (id=1&name=bobby), but using POST http method implies to pass data inside body of http request (in get params, as you did, data is passed in GET method) . So you have to serialize your user data on client side and add this serialized data to request body and sent it to localhost:8080/name-project/insert.
As above answer suggest. You are trying to pass data as query parameters.but you are not reading those values in your rest API.either you need to read those query parameters in your API and then form an object or try to pass a json serialized object to your Post api as recommendation. Hope it helps.

How to send parameters to a restful service from a java web project

I have 2 java projects. The first one is a RESTFUL webservice, that should handle CRUD requests. The second is a dynamic web project (which has the gui).
Let's say I have this html gui in my web project.
(Remember I don't care about security and authority principles, I just wan't to understand this first).
When I fill the information and click "Sign in" I call my login_servlet inside the web project. Inside the servlet I create a client object and call the RESTFUL web service (inside the doPost method):
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Client client = Client.create();
WebResource webR = client.resource("http://localhost:8080/MyNote/api/login/get");
ClientResponse resp = webR.accept("text/html").get(ClientResponse.class);
if (resp.getStatus() == 200){
System.out.println("****** 200 ******");
String output = resp.getEntity(String.class);
//System.out.println("****" + output + "****");
}
}
As for now the provided URL calls the following code inside the RESTFUL web service, which successfully get printed out:
#Path("/login")
public class UserLogin {
#GET
#Path("/get")
public void login(){
System.out.println("**** I'm checking if user exist in DB *****");
}
}
What I instead want to do, is to send the inserted username and password from the login_servlet as parameters to the Restful web service, and then return a response. How can I do that? (Just the part of sending parameters from one place to another + Response)
All security aside, you have a few options to send params.
As query params as Duran mentioned above.
In your Jersey request method you would handle those as:
#GET
#Path("/get")
public void login(#QueryParam("foo") String var1, #QueryParam("bar") String var2){
// do something
}
Note that the variable names do not have to match, the string you pass to #QueryParam() is what gets matched and the value injected into the variable.
As path params you would do:
#GET
#Path("/get/{foo}/{bar}")
public void login(#PathParam("foo") String var1, #PathParam("bar") String var2){
// do something
}
Here make sure that what you have as var name in {} matches what you pass to #PathParam.
As far as Jersey/JAX-RS goes this is only the tip of the iceberg, there are other options. Hope this helps you get started.
EDIT: People seem to take issue with password being passed openly so let me say this: NO, you should never pass a password in the url, this is just to serve as an example
EDIT2: Changed username to foo and password to bar.
Using path params:
//Rest API
#GET
#Path("/get/{username}/{password}")
public void login(#PathParam("username") String userName, #PathParam("password") String pwd){
}
//Jersey
ClientResponse resp = webR.accept("text/html")
.path(userName)
.path(password)
.get(ClientResponse.class);
Using Query params
//Rest API
#GET
#Path("/get")
public void login(#QueryParam("username") String username, #QueryParam("password") String pwd){
//Jersey
ClientResponse resp = webR.accept("text/html")
.queryParam("username", userName)
.queryParam("password", pwd)
.get(ClientResponse.class);
Just append the parameters to the service url like:
http://localhost:8080/MyNote/api/login/get&username=duran&password=password
Although it is possible to send parameters in a GET request (as described in previous answers), it is usually better to send a POST request and to send a JSON payload in the body.
Here, you only have 2 parameters (login and password), so it's not too bad, but I still prefer to send an object in a POST. If you want to do that, then in your RESTful service, you just have to have method annotated with POST (and check the annotations that allow you to retrieve the de-serialized object).
Having said that, 2 comments/questions:
1) why do you mix servlets and JAX-RS? You could implement everything with JAX-RS and I would recommend that. Move the registration to a JAX-RS resource.
2) #Path("/get") is an anti-pattern: you don't want to have /get in the url. You rarely want VERBS in URLs (purists would say never). Typically, to register a new user, I would send a POST request to /api/registrations, because I want to create a new registration.

What should my url be for JAX-RS API

Pardon for the amateur question, however, I am struggling with testing a java Rest Api Locally.
#Path("/Product") //URL to call
public class ProductSearch {
#Path("/item")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces({MediaType.APPLICATION_JSON})
public List<ProductObject> getProjects(Credentials login) throws ConnectionException{
Assuming credentials has username, password, url, itemname, What should the localhost url look like? I get a 404 when I go to http://localhost:8080/productsearchapi/Product/item
I am able to deploy to heroku and test by sending json string but I need to be able to test and debug locally.
You could use postman to test your POST call to the API without deploying to heroku.
Your request in postman would look similar to the following, and under the body tab you would have to create the valid JSON that your path is consuming.
Postman Call
After hitting send with providing a valid JSON you should get the response json returned to you

Categories

Resources