Issue
I'm trying to edit an existing object in db but logger says that the method is not allowed.
Here is the template:
<html xmlns:th="http://www.thymeleaf.org">
<body>
<form th:action="@{save}" th:object="${opera}" method="POST">
<div class="input-container">
<div>
<div>Name:</div>
<div><input type="text" th:field="*{nome}"></div>
</div>
<div><button type="submit">Save</button></div>
</div>
</form>
</body>
</html>
Here is the handler method to edit the object:
@RequestMapping(value="/save", method=RequestMethod.POST)
public String saveOpera(@ModelAttribute("opera") Opera opera, Model model){
this.operaService.inserisci(opera);
return "opere.html";
}
And here is the handler method which return the edit page:
@RequestMapping(value="/edit/{id}", method=RequestMethod.GET)
public String showEditOpera(@PathVariable(name = "id") Long id, Model model) {
model.addAttribute("opera", operaService.searchOperaById(id));
return "/admin/saveProva";
}
And the stack trace if needed:
[2m2021-08-02 12:52:17.733[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m GET "/edit/15", parameters={}
[2m2021-08-02 12:52:17.734[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36ms.w.s.m.m.a.RequestMappingHandlerMapping[0;39m [2m:[0;39m Mapped to it.uniroma3.siw.controller.OperaController#showEditOpera(Long, Model)
[2m2021-08-02 12:52:17.736[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36morg.hibernate.SQL [0;39m [2m:[0;39m select opera0_.id as id1_4_0_, opera0_.artista_id as artista_4_4_0_, opera0_.collezione_id as collezio5_4_0_, opera0_.nome as nome2_4_0_, opera0_.path as path3_4_0_, artista1_.id as id1_0_1_, artista1_.biografia as biografi2_0_1_, artista1_.cognome as cognome3_0_1_, artista1_.data_di_morte as data_di_4_0_1_, artista1_.data_di_nascita as data_di_5_0_1_, artista1_.luogo_di_morte as luogo_di6_0_1_, artista1_.luogo_di_nascita as luogo_di7_0_1_, artista1_.nome as nome8_0_1_, artista1_.path as path9_0_1_, collezione2_.id as id1_1_2_, collezione2_.curatore_id as curatore4_1_2_, collezione2_.descrizione as descrizi2_1_2_, collezione2_.nome as nome3_1_2_, curatore3_.id as id1_3_3_, curatore3_.cognome as cognome2_3_3_, curatore3_.data_di_nascita as data_di_3_3_3_, curatore3_.nome as nome4_3_3_ from opera opera0_ left outer join artista artista1_ on opera0_.artista_id=artista1_.id left outer join collezione collezione2_ on opera0_.collezione_id=collezione2_.id left outer join curatore curatore3_ on collezione2_.curatore_id=curatore3_.id where opera0_.id=?
Hibernate: select opera0_.id as id1_4_0_, opera0_.artista_id as artista_4_4_0_, opera0_.collezione_id as collezio5_4_0_, opera0_.nome as nome2_4_0_, opera0_.path as path3_4_0_, artista1_.id as id1_0_1_, artista1_.biografia as biografi2_0_1_, artista1_.cognome as cognome3_0_1_, artista1_.data_di_morte as data_di_4_0_1_, artista1_.data_di_nascita as data_di_5_0_1_, artista1_.luogo_di_morte as luogo_di6_0_1_, artista1_.luogo_di_nascita as luogo_di7_0_1_, artista1_.nome as nome8_0_1_, artista1_.path as path9_0_1_, collezione2_.id as id1_1_2_, collezione2_.curatore_id as curatore4_1_2_, collezione2_.descrizione as descrizi2_1_2_, collezione2_.nome as nome3_1_2_, curatore3_.id as id1_3_3_, curatore3_.cognome as cognome2_3_3_, curatore3_.data_di_nascita as data_di_3_3_3_, curatore3_.nome as nome4_3_3_ from opera opera0_ left outer join artista artista1_ on opera0_.artista_id=artista1_.id left outer join collezione collezione2_ on opera0_.collezione_id=collezione2_.id left outer join curatore curatore3_ on collezione2_.curatore_id=curatore3_.id where opera0_.id=?
[2m2021-08-02 12:52:17.737[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicBinder [0;39m [2m:[0;39m binding parameter [1] as [BIGINT] - [15]
[2m2021-08-02 12:52:17.739[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([id1_0_1_] : [BIGINT]) - [null]
[2m2021-08-02 12:52:17.739[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([id1_1_2_] : [BIGINT]) - [null]
[2m2021-08-02 12:52:17.740[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([id1_3_3_] : [BIGINT]) - [null]
[2m2021-08-02 12:52:17.740[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([artista_4_4_0_] : [BIGINT]) - [null]
[2m2021-08-02 12:52:17.740[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([collezio5_4_0_] : [BIGINT]) - [null]
[2m2021-08-02 12:52:17.740[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([nome2_4_0_] : [VARCHAR]) - [rap]
[2m2021-08-02 12:52:17.741[0;39m [32mTRACE[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.h.type.descriptor.sql.BasicExtractor [0;39m [2m:[0;39m extracted value ([path3_4_0_] : [VARCHAR]) - [null]
[2m2021-08-02 12:52:17.743[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.s.w.s.v.ContentNegotiatingViewResolver[0;39m [2m:[0;39m Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
[2m2021-08-02 12:52:17.752[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-1][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Completed 200 OK
[2m2021-08-02 12:52:17.765[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-3][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m GET "/css/style.css", parameters={}
[2m2021-08-02 12:52:17.766[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-3][0;39m [36mo.s.w.s.handler.SimpleUrlHandlerMapping [0;39m [2m:[0;39m Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
[2m2021-08-02 12:52:17.769[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-3][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Completed 200 OK
[2m2021-08-02 12:52:17.773[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-5][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m GET "/img/edificio.jpg", parameters={}
[2m2021-08-02 12:52:17.774[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-5][0;39m [36mo.s.w.s.handler.SimpleUrlHandlerMapping [0;39m [2m:[0;39m Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
[2m2021-08-02 12:52:17.786[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-5][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Completed 200 OK
[2m2021-08-02 12:52:28.482[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m POST "/edit/save", parameters={masked}
[2m2021-08-02 12:52:28.483[0;39m [33m WARN[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36m.w.s.m.s.DefaultHandlerExceptionResolver[0;39m [2m:[0;39m Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
[2m2021-08-02 12:52:28.483[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Completed 405 METHOD_NOT_ALLOWED
[2m2021-08-02 12:52:28.484[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m "ERROR" dispatch for POST "/error", parameters={masked}
[2m2021-08-02 12:52:28.485[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36ms.w.s.m.m.a.RequestMappingHandlerMapping[0;39m [2m:[0;39m Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
[2m2021-08-02 12:52:28.489[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36mo.s.w.s.v.ContentNegotiatingViewResolver[0;39m [2m:[0;39m Selected 'text/html' given [text/html, text/html;q=0.8]
[2m2021-08-02 12:52:28.492[0;39m [32mDEBUG[0;39m [35m17652[0;39m [2m---[0;39m [2m[nio-8090-exec-2][0;39m [36mo.s.web.servlet.DispatcherServlet [0;39m [2m:[0;39m Exiting from "ERROR" dispatch, status 405
Someone knows how to fix it? (I couldn't find similar question, so i just hope it's not just a missing comma or something like that.)
Solution
The following two messages within the logs give a clue about what's happening:
POST "/edit/save", parameters={masked}
Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
As you can see, you're trying to call /edit/save in stead of /save. This happens because the form action attribute uses a relative path in stead of an absolute one.
To solve this, prepend a slash to the form action within the template, eg. th:action="@{/save}"
:
<!-- ... -->
<form th:action="@{/save}" th:object="${opera}" method="POST">
<!-- ... -->
</form>
<!-- ... -->
Answered By - g00glen00b
Answer Checked By - Senaida (JavaFixing Volunteer)