Home > Software design >  Java Spring There was an unexpected error (type=Method Not Allowed, status=405)
Java Spring There was an unexpected error (type=Method Not Allowed, status=405)

Time:09-12

I'm having this error with my spring boot application

There was an unexpected error (type=Method Not Allowed, status=405). Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]

I've read about it here: https://www.baeldung.com/spring-request-method-not-supported-405

but I can't still figure this one out since I'm new to spring and java

Here what I can do

  1. I can navigate to any page without problem
  2. I can add a new evaluation
  3. I can delete an evaluation

Here what I'm trying to do

  1. After creating an evaluation I want to edit it I can navigate to the update page and the form is filled as expected I can change the value but when I press submit I get the error message and for some reason the URL is this one http://localhost:8080/modifier/modifierEvaluation

  2. The method from the HTTP header is POST as expected and I can see the value of the change in the payload also

Here is my code

The controller

@Controller
public class ModifierController {

    @Autowired
    EvaluationDataContext context;

    @GetMapping("/modifier/{id}")
    public ModelAndView modifier(@PathVariable("id") int id, Model model) {

        Evaluation evaluation = EvaluationDataContext.Rechercher(id);

        // Create the option for the select tags
        Map<String, String> noteItems = new LinkedHashMap<String, String>();
        noteItems.put("Tres bien", "Très bien");
        noteItems.put("Bien", "Bien");
        noteItems.put("Moyen", "Moyen");
        noteItems.put("Mediocre", "Médiocre");
        model.addAttribute("noteItems", noteItems);

        model.addAttribute("evaluation", evaluation);
        return new ModelAndView("modifier", "evaluation", evaluation);
    }
 
    @PutMapping("/modifierEvaluation/{id}")
    public String modifierPost(@ModelAttribute("evaluation") Evaluation evaluation) {
        context.Modifier(evaluation);
        return "redirect:/listeEvaluation";
    }
}

The view

<!DOCTYPE html>
<%@page contentType="text/html" pageEncoding="UTF-8" %> 
<%@ include file="common/include.jsp" %>

<html lang="en">
  <%@ include file="common/header.jsp" %>
  <body>
    <%@ include file="common/navbar.jsp" %>
    <div >
      <h1>Modifier</h1>
      
      <form:form action="modifierEvaluation" modelAttribute="evaluation">
        <div >
          <form:hidden path="numero" value="${evaluation.numero}"></form:hidden>
        </div>
        <div >
          <div >
            <form:label cssClass="form-label" path="prenom">Prénom</form:label>
            <form:input cssClass="form-control" path="prenom" value="${evaluation.prenom}"></form:input>
          </div>
          <div >
            <form:label cssClass="form-label" path="nom">Nom</form:label>
            <form:input cssClass="form-control" path="nom" value="${evaluation.nom}"></form:input>
          </div>
        </div>
        <div>
          <form:label cssClass="form-label" path="courriel">Courriel</form:label>
          <form:input cssClass="form-control" path="courriel" value="${evaluation.courriel}"></form:input>
        </div>
        <div >
          <div >
            <form:label cssClass="form-label" path="telephone">Telephone*</form:label>
            <form:input cssClass="form-control" path="telephone" value="${evaluation.telephone}" required="required"></form:input>
          </div>
          <div >
            <form:label cssClass="form-label" path="dateEvaluation">Date</form:label>
            <fmt:formatDate type="date" value="${evaluation.dateEvaluation.time}" pattern="yyyy-MM-dd" var="formatedDate"></fmt:formatDate>
            <form:input type="date" cssClass="form-control" path="dateEvaluation" value="${formatedDate}"></form:input>
          </div>
        </div>
        <div >
          <c:if test="${evaluation.sexe == 'M'.charAt(0)}">
            <div >
              <div >
                <div >
                  <form:radiobutton cssClass="form-check-input" path="sexe" value="M" checked="checked"></form:radiobutton>
                  <form:label cssClass="form-check-label" path="sexe">Masculin</form:label>
                </div>
                <div >
                  <form:radiobutton cssClass="form-check-input" path="sexe" value="F"></form:radiobutton>
                  <form:label cssClass="form-check-label" path="sexe">Féminin</form:label>
                </div>
              </div>
            </div>
          </c:if>
          <c:if test="${evaluation.sexe == 'F'.charAt(0)}">
            <div >
              <div >
                <div >
                  <form:radiobutton cssClass="form-check-input" path="sexe" value="M"></form:radiobutton>
                  <form:label cssClass="form-check-label" path="sexe">Masculin</form:label>
                </div>
                <div >
                  <form:radiobutton cssClass="form-check-input" path="sexe" value="F" checked="checked"></form:radiobutton>
                  <form:label cssClass="form-check-label" path="sexe">Féminin</form:label>
                </div>
              </div>
            </div>
          </c:if>
          <div >
            <form:select cssClass="form-select" path="note">
              <option hidden="">${evaluation.note}</option>
              <form:options cssClass="form-option" items="${noteItems}"></form:options>
            </form:select>
          </div>
        </div>
        <div >
          <form:label path="commentaire">Commentaire</form:label>
          <form:textarea cssClass="form-control" path="commentaire" rows="5" value="${evaluation.commentaire}"></form:textarea>
        </div>
        <div >
          <form:button cssClass="btn btn-primary">Confirmer</form:button>
          <form:button type="reset" cssClass="btn btn-secondary" onclick="return confirm('Voulez-vous annuler la modification de l\'evaluation')">
            Annuler</form:button></div>
      </form:form>
    </div>
    <%@ include file="common/footer.jsp" %>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script>
 </body>
</html>

POM.xml I'm not sure if this is need but here it is

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.3</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>Laboratoire02</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>Laboratoire02</name>
    <description>Laboratoire02</description>
    <properties>
        <java.version>18</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>13.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

CodePudding user response:

Because you use @PutMapping it is for PUT. You need @PostMapping https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/PostMapping.html

  @PostMapping("/modifierEvaluation/{id}")
    public String modifierPost(@ModelAttribute("evaluation") Evaluation evaluation) {
        context.Modifier(evaluation);
        return "redirect:/listeEvaluation";
    }

Try add to form tag method = "POST"

  <form:form action="modifierEvaluation" modelAttribute="evaluation" method = "POST">

CodePudding user response:

Hey guys i finally found the answers the error was a basic one my the route of my action in my form was this one modifierEvaluation/${id} When it should have been this one /modifierEvaluation/${id}

Which was causing the URL to be appended at the end instead of replaced, that why I had the following URL http://localhost:8080/modifier/modifierEvaluation

  • Related