Error 404 on PUT request while having a GET - spring

Got a small problem on my rest server. It's based on spring web framework.
Here's the code that poses me problems :
#RestController
#RequestMapping("users")
public class usersWS {
//some other functions
//works
#RequestMapping(
value="/{iduser}/functions/",
method=RequestMethod.GET,
produces={"application/json"})
public ResponseEntity<String> getUserFunctions(#PathVariable("iduser") String iduser){
//do stuff
return stuff;
}
//Don't works
#RequestMapping(
value="/{iduser}/functions/"
method=RequestMethod.PUT,
consumes={"application/json"})
public ResponseEntity<String> addUserFunctions(#RequestBody String json, #PathVariable("iduser") String iduser){
//do stuff
return stuff;
}
}
Server is launched by :
#SpringBootApplication()
#ImportResource("classpath*:**/jdbc-context.xml")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
To call this server, I use the HTML handler found here : Spring HTTP Client
When I call the get verb, everything is working fine. I get the iduser, get the data I want, no problem.
When I call the put verb... I have an error 404. I checked, the url (http://localhost:8080/users/xxx/functions/) are exactly the same, I do send the body.
I would understand to get a 405 error, but I really don't understand how I can have a 404. If the mapping was wrong, the server should at least see that there is a function on the get verb and throw me a 405.
I have other functions using the PUT/POST that are working but they don't have a #PathVariable. Is it possible to mix #RequestBody and #PathVariable ?
Any help is gladly welcome.

Related

Spring Boot Tries to Access A Post Request URL but shows GET not supported

I just started to learn Spring Boot today, and I wanted to create a GET/POST request for my Spring Boot Project. When I tried to access the URL that has the post request it shows 405 error saying that "Request method 'GET' not supported".
I think it is something wrong about my code for the POST request, but I don't know where I did wrong. I tried to search for the a tutorial that teaches how to write a proper GET/POST request, so I couldn't find anything good.
If you guys have any good website that teaches basic HTTP requests in Spring Boot, that will be great. I tried to find answers at StackOverflow, but I didn't find anything answers.
The Spring Boot project I have been using is the one from the official Spring.io website: https://spring.io/guides/gs/rest-service/
I wanted to call the POST request for my project so I have a better understanding of the HTTP.
Here is the source code for the controller:
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.*;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
#RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
// GET Request
#RequestMapping(value="/greeting", method = GET)
public Greeting greeting(#RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(), name);
}
#RequestMapping(value = "/testpost", method = RequestMethod.POST)
public String testpost() {
return "ok";
}
}
Here is the source code for the Application:
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And here is the source code for the Greeting Object
package hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
I can get the GET request working by using the "/greeting" URL.
I tried to access the "/testpost" url but it shows 405 error that the GET method is not supported.
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
If you try to open the http://localhost:8080/testpost by directly opening in browser, it won't work because opening in browser makes a GET request.
I am not sure how you are trying to do a post request, I tried to do the same post request from postman and able to get the response. Below is the screenshot.
It looks like you are trying to make post request directly from web browser which will not work.
When you hit a URL directly from web browser address bar, it is considered as GET request. Since in your case, there is no GET API as /testpost , it is giving error.
Try to use rest client such as Postman or curl command to make post request.
I tried your post end-point with postman and it is working properly. PFA snapshot for your reference.
Hope this helps.
From where you are trying POST request. If from browser windows you calling POST call, then it will not work, browser will send only GET request. Have you tried from postman or from UI side. It will work.

ajax Spring liferay

I'm using an architetture that has: AJAX, Liferay 6.2, Spring 4.3.18.RELEASE;
From AJAX i make a call to the backend, that pass throu liferay and reach my controller;
Now, I want to generete an exception in the controller in order to reach the the failure of the ajax call; I've googled a lot but I wasn't able to find the solution.
my controller:
#Controller("movemementCon")
#RequestMapping("VIEW")
public class movemementCon {
#ResourceMapping("getDis")
#ResponseBody
public ResponseEntity<BenException> getImp(ResourceRequest request, ResourceResponse response, Model model) throws BenException{
return new ResponseEntity<BenException>(HttpStatus.NOT_ACCEPTABLE);
}
But when i reach the code in javascript (the AJAX call) it ignored definitively that I've throw an exception;
The desidered behaviur is that i force to go to the error statment in the AJAX call.
In web browser you can't catch java errors on client side, because client doesn't know anything about backend. You have to catch that error in spring controller method and then return ResponseEntity with some status, response body, custom response headers, so you can notify client that something went wrong and handle it correctly there.
#Controller("movemementCon")
#RequestMapping("VIEW")
public class movemementCon {
#ResourceMapping("getDis")
#ResponseBody
public ResponseEntity<SomeClass> getImp(ResourceRequest request, ResourceResponse response, Model model) {
try{
deleteFromDatabase(model);
} catch(BenException e) {
return new ResponseEntity<>(HttpStatus.NOT_ACCEPTABLE);
}
return new ResponseEntity<>(HttpStatus.OK);
}
}
Then in your JS read the status and execute right action.

Zuul proxy server throwing Internal Server Error when request takes more time to process

Zuul Proxy Error
I am getting this error when the request takes more time to process in the service.But Zuul returns response of Internal Server Error
Using zuul 2.0.0.RC2 release
As far as I understand, in case of a service not responding, a missing route, etc. you can setup the /error endpoint to deliver a custom response to the user.
For example:
#Controller
public class CustomErrorController implements ErrorController {
#RequestMapping(value = "/error", produces = "application/json")
public #ResponseBody
ResponseEntity error(HttpServletRequest request) {
// consider putting these in a try catch
Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
Throwable exception = (Throwable)request.getAttribute("javax.servlet.error.exception");
// maybe add some error logging here, e.g. original status code, exception, traceid, etc.
// consider a better error to the user here
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("{'message':'some error happened', 'trace_id':'some-trace-id-here'}");
}
#Override
public String getErrorPath() {
return "/error";
}
}

How can i ignore some path of vaadin ? /HEARTBEAT /UIDL /VAADIN

I am using a vaadin application with the dashboardemo example
My class does not use a VaadinSevlet but, a VaadinCDIServlet
My webServlet 3.0 I have it so
#WebServlet (asyncSupported = false, urlPatterns = {"/*"},
I will not serve any static content otherwise I would write another
urlpattern as well /VAADIN/*
The problem is that when I visit the path as
/HEARTBEAT/?v-uid=0
/HEARTBEAT
/UIDL/?v-uiId=2
/VAADIN/
/VAADIN/themes/valo/fonts
I get different errors, as I can show some errorView or redirect users to a main view,
The demo dashboard actually redirects some incorrect url or fragments !#blalbla, redirect to
https://domain/myapp/#!dashboard
but with these path does not it, I have reviewed many applications and it happens just the same, whether we are demos or not.please some help?
Update
The solution I recommend for this in case of handling errors 4xx 5xx etc, is to use spring framework, example:. redirect to an external url
#RestController
public class MyController implements ErrorController {
private static final String URL = "http://www.blablaba.com";
#RequestMapping(method = RequestMethod.GET)
#ExceptionHandler(RuntimeException.class)
public void handle(final RuntimeException rex, final HttpServletResponse
hsp) throws IOException {
hsp.sendRedirect(getErrorPath());
}
#Override
public String getErrorPath() {
return URL;
}
}
Im not sure the approach they took in the demo but this is what comes to my mind. In your ErrorView you can call UI.getCurrent().getNavigator() and then redirect to the desired URL by getting the URL from the Page.getCurrent() object then running Navigator.navigateTo().

get error HTTP Status 405 for rest web service POST method

I load at browser as
localhost:8080/picking/addPick get error HTTP Status 405 - Request method 'GET' not supported.
What wrong?Hope advice thanks
#Controller
#RequestMapping("/picking")
public class PickerController {
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody ArrayList getAllPickingItems()throws SQLException, ClassNotFoundException{
//....
}
#RequestMapping(value="/addPick",method=RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public Boolean add(#RequestBody PickingInfo pickingInfo,HttpServletResponse response){
try{
Boolean success = pickerMethod.addPickingInfo(pickingInfo);
response.setHeader("addPickingInfo", success+"");
return true;
}catch(Exception ex){
System.out.println(ex.getMessage());
}
return false;
}
}
You limited URI/picking/addPick to POST requests :
#RequestMapping(value="/addPick",method=RequestMethod.POST)
When you try to open that URI from your browser you're sending a GET request, not a POST. If you want to be able to access /picking/addPick from your browser you must either :
remove the restriction method=RequestMethod.POST
allow explicitely GET requests : method = { RequestMethod.POST, RequestMethod.GET }
If you just want to test a POST method, use SoapUI. Simply create a "New REST Project", paste your service URI, and send any type of HTTP Request you want.
You have mapped /addPick to the add method only for POST requests. Therefor GET is not mapped to anything (and in this case there is no point in mapping get to the method since you are also using #RequestBody)

Resources