0
"timestamp": "2020-01-19T08:36:05.729+0000",
    "status": 405,
    "error": "Method Not Allowed",
    "message": "Request method 'POST' not supported",
    "trace": "org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported\r\n\tat org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:201)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:421)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:449)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:67)\r\n\tat org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:395)\r\n\tat org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1234)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:660)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:741)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.lang.Thread.run(Unknown Source)\r\n",
    "path": "/automobil/6"
}

where trace value unescapes to:

org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:201)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:421)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:367)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:449)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.getHandlerInternal(RequestMappingHandlerMapping.java:67)
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:395)
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1234)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1016)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Here is my Controler class

@Autowired
private AutomobiliDaoService service;

@GetMapping(path = "/automobil")
public List<PolovniAutomobili> getAll() {
    return service.findAll();
}

@GetMapping(path = "/automobil/{id}")
public PolovniAutomobili getAutomobili(@PathVariable int id) {
    return service.findOne(id);
}

@RequestMapping(method = RequestMethod.POST, value = "/automobil")
public void addAutomobili(@RequestBody PolovniAutomobili polovniAutomobili) {
    service.addAutomobil(polovniAutomobili);
}

@RequestMapping(method = RequestMethod.DELETE, value = "/automobil")
public void deleteAutomobili(@RequestBody PolovniAutomobili polovniAutomobili) {
    service.deleteAutomobil(polovniAutomobili);
}

Here is my Component class

public static List<PolovniAutomobili> automobil = new ArrayList<>();

    static {

        automobil.add(new PolovniAutomobili(1, 2012, "Polo", "Volkswagen", 75.00));
        automobil.add(new PolovniAutomobili(2, 2018, "Arteon", "Volkswagen", 155.00));
        automobil.add(new PolovniAutomobili(3, 2006, "Clio", "Renault", 55.00));
        automobil.add(new PolovniAutomobili(4, 2011, "Punto", "Fiat", 60.00));
        automobil.add(new PolovniAutomobili(5, 2010, "Spark", "Chevrollete", 65.00));

    }

    public List<PolovniAutomobili> findAll() {
        return automobil;
    }

    public PolovniAutomobili findOne(int id) {
        for(PolovniAutomobili polovniautomobili : automobil) {
            if(polovniautomobili.getId()==id) {
                return polovniautomobili;
            }
        }

        return null;
    }

    public void addAutomobil(PolovniAutomobili polovniAutomobili) {
        automobil.add(polovniAutomobili);
    }

    public void deleteAutomobil(PolovniAutomobili polovniAutomobili) {
        automobil.remove(polovniAutomobili);
    }
Andreas
  • 154,647
  • 11
  • 152
  • 247
Marko
  • 3
  • 2
  • *Curious:* If you use `@GetMapping`, why use `@RequestMapping(method = RequestMethod.POST)` instead of the simpler `@PostMapping`? Same for `@DeleteMapping`? – Andreas Jan 19 '20 at 09:33
  • Tried to implement it with ```@PostMapping``` and ```@DeleteMapping```, but ran into some problems, because I've switched from database to lists, and i don't really remember how to work with them in this way, if that makes sense – Marko Jan 19 '20 at 09:38
  • Not really, no. – Andreas Jan 19 '20 at 09:40
  • And now that you mention it, eclipse is really not doing me a favor, now it works with ```@PostMapping```, yesterday it was giving me an error – Marko Jan 19 '20 at 09:40

2 Answers2

3

You are posting to /automobil/6 but in your controller you only have a POST mapping for /automobil.

Either post your data to /autmobil or change your post mapping to /autmobil/{id} with a path variable for the id.

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66
  • I've tried changing post mapping to ```/automobil/{id}``` , the same error still persists – Marko Jan 19 '20 at 09:16
  • did you add a `@PathVariable` parameter to your method? – P.J.Meisch Jan 19 '20 at 09:18
  • Oh sorry, it's changed now to "timestamp": "2020-01-19T09:14:56.145+0000", "status": 400, "error": "Bad Request", "message": "Required request body is missing: public void rs.ac.singidunum.singidunumboot.AutomobiliController.addAutomobili(rs.ac.singidunum.singidunumboot.PolovniAutomobili)" – Marko Jan 19 '20 at 09:18
  • so you are not sending data in your request? – P.J.Meisch Jan 19 '20 at 09:20
  • I am trying to add a new one, by setting the keys and values in query params (in Postman) if that's what you mean by sending data ? – Marko Jan 19 '20 at 09:26
  • @Marko Query params is not a request body. Please *learn* more about HTTP to learn what a request body is, e.g. see [What does it mean http request body?](https://stackoverflow.com/q/22034144/5221149) – Andreas Jan 19 '20 at 09:35
  • You were refering to this right ? e.g. ```localhost:8080/automobil/6?id=6&godisteAuta=2010&model="Stilo"&marka="Fiat"&konjskeSnage=75.00 ``` – Marko Jan 19 '20 at 09:49
  • if you send them this way, you need to have a function parameter for each of these and annotate each with `@RequestParam`. If you use `@RequestBody` then you post must have a (normally JSON) body which must match the `PolovniAutomobili` class you expect. – P.J.Meisch Jan 19 '20 at 10:08
0

When you want to add new contents, you must use POST method, while when you want to retrieve an existing content, you must use GET method; when you want to remove an existing content, you must use DELETE method.


Add a new car

You need a POST method.

@PostMapping("automobil")
public void addAutomobili(@RequestBody PolovniAutomobili polovniAutomobili) {
    service.addAutomobil(polovniAutomobili);
}

You can provide those data in postman (based on what you add in the comments) like this: enter image description here

Delete an existing car

You need the DELETE method. To follow RESTfull guidelines, is better to refere to the resource with the path variable.

@DeleteMapping("automobil/{automobilId}")
    public void addAutomobili(@PathVariable Integer automobilId) {
        service.deleteAutomobil(automobilId);
    }

You have to modify the method deleteAutomobil of your component (which usually is called Service). It could be better to use a Map instead of a List (because you manage ids to identify cars). In this case delete would be also easier:

public void deleteAutomobili(Integer automobilId) {
            if(automobilMap.containsKey(automobilId))
                 automobilMap.remove(automobilId);
            else {
               // notify that resource doesn't exists
            }
    }

And this is the call with Postman (note that there's no more a body): enter image description here


A Map is a structure where elements are stored as key-value pairs. You can access to a element through a key. Remember that each key has to be unique. Your Service class should look like this:

public static Map<Integer, PolovniAutomobili> automobil = new HashMap<>();
static {

    automobil.put(1, new PolovniAutomobili(1, 2012, "Polo", "Volkswagen", 75.00));
    automobil.put(2, new PolovniAutomobili(2, 2018, "Arteon", "Volkswagen", 155.00));
    automobil.put(3, new PolovniAutomobili(3, 2006, "Clio", "Renault", 55.00));
    automobil.put(4, new PolovniAutomobili(4, 2011, "Punto", "Fiat", 60.00));
    automobil.put(5, new PolovniAutomobili(5, 2010, "Spark", "Chevrollete", 65.00));

}

public List<PolovniAutomobili> findAll() {
    return automobil.values();
}

public PolovniAutomobili findOne(int id) {
    // if id is not a ky, it will return null (you can manage it)
    return automobil.get(id);
}

public void addAutomobil(PolovniAutomobili polovniAutomobili) {
    automobil.put(polovniAutomobili.getId(), polovniAutomobili);
}

public void deleteAutomobil(int id) { 
    if(automobil.containsKey(id))
        automobil.remove(id);
    else
        System.out.println("Id not found");
}           
A. Wolf
  • 1,309
  • 17
  • 39
  • 1
    Thank you this helped me a lot, tho i now have problems with ```DELETE``` not working properly, would you have the time to send me an entire update using ```Map``` insted of ```List``` – Marko Jan 20 '20 at 16:11
  • I added the code that uses ```Map```. Let me know if now it's working or you need more help, no problem :) – A. Wolf Jan 21 '20 at 07:43
  • You put ```public List findAll()```, shouldn't ```List``` be deleted, cause we are using ```Map``` ? sorry for the late anwser – Marko Jan 26 '20 at 11:38
  • Don't worry! No, because I returned ```automobil.values()```, which returns a Collection (i.e. ```List``` in this case), I didn't return the map itself. It gets only the values of the map as a List, without getting the keys. – A. Wolf Jan 26 '20 at 13:33
  • If the answer helped you, please upvote it and consider to accept it. :) It will help people which search something like you problem to find a solution in a simpler way :) – A. Wolf Jan 26 '20 at 13:35
  • 1
    You have helped me a lot, thank you, I'll upvote it and accept it :D – Marko Jan 30 '20 at 17:21