Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot - Post Method Not Allowed, but GET works

I'm having a problem with my spring boot mysql project, the controller class works just find for METHOD GET(get all), but I can't seem to post and get error 405: Method "POST" Not Allowed

Heres my controller class:

 package com.example.demo.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.example.demo.Blog;
import com.example.demo.repository.BlogRespository;

import java.util.List;
import java.util.Map;

@RestController
public class BlogController {

    @Autowired
    BlogRespository blogRespository;

    @GetMapping("/blog")
    public List<Blog> index(){
        return blogRespository.findAll();
    }

    @GetMapping("/blog/{id}")
    public Blog show(@PathVariable String id){
        int blogId = Integer.parseInt(id);
        return blogRespository.findById(blogId)
                 .orElseThrow(() -> new IllegalArgumentException(
                 "The requested resultId [" + id +
                 "] does not exist."));
    }

    @PostMapping("/blog/search")
    public List<Blog> search(@RequestBody Map<String, String> body){
        String searchTerm = body.get("text");
        return blogRespository.findByTitleContainingOrContentContaining(searchTerm, searchTerm);
    }

    @PostMapping("/blog")
    public Blog create(@RequestBody Map<String, String> body){
        String title = body.get("title");
        String content = body.get("content");
        return blogRespository.save(new Blog(title, content));
    }

    @PutMapping("/blog/{id}")
    public Blog update(@PathVariable String id, @RequestBody Map<String, String> body){
        int blogId = Integer.parseInt(id);
        // getting blog
        Blog blog = blogRespository.findById(blogId)
             .orElseThrow(() -> new IllegalArgumentException(
             "The requested resultId [" + id +
             "] does not exist."));
        blog.setTitle(body.get("title"));
        blog.setContent(body.get("content"));
        return blogRespository.save(blog);
    }


    @DeleteMapping("blog/{id}")
    public boolean delete(@PathVariable String id){
        int blogId = Integer.parseInt(id);
        blogRespository.delete(blogId);
        return true;
    }


}

and heres my repository class if you need it

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.Blog;

import java.util.List;

@Repository
public interface BlogRespository extends JpaRepository<Blog, Integer> {

    // custom query to search to blog post by title or content
    List<Blog> findByTitleContainingOrContentContaining(String text, String textAgain);

}

Im trying the POST request with SoapUI, and just cant seem to find the solution, many thanks

like image 360
Drason Avatar asked Oct 28 '25 00:10

Drason


2 Answers

The method post will be not Allowed if you have csrf configured or enabled then your need to provided a valid csrf while posting your form or data

Check your spring security config for this For example

    @Configuration
    @EnableWebSecurity
    @ComponentScan(basePackageClasses = CustomUserDetailsService.class)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    .....

RequestMatcher csrfRequestMatcher = new RequestMatcher() {
        // Enabled CSFR protection on the following urls:
        //@formatter:off
        private AntPathRequestMatcher[] requestMatchers = 
            {
                new AntPathRequestMatcher("/**/verify"),
                        new AntPathRequestMatcher("/**/login*")
            };
        //@formatter:off

        @Override
        public boolean matches(final HttpServletRequest request) {
            // If the request match one url the CSFR protection will be enabled
            for (final AntPathRequestMatcher rm : requestMatchers) {
                if (rm.matches(request)) {
                    System.out.println();
                    /* return true; */
                }
            }
            return false;
        } // method matches
    };
@Override
    protected void configure(final HttpSecurity http) throws Exception {
        //@formatter:off

        http.headers().frameOptions().sameOrigin()
        .and()
        .authorizeRequests()
        .antMatchers("/","/css/**", "/static/**", "/view/**", "**/error/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin().loginPage("/mvc/login").permitAll() 
        .authenticationDetailsSource(authenticationDetailsSource())
        .successHandler(authenticationSuccessHandler)
        .usernameParameter("username").passwordParameter("password")
        .and()
        .logout().permitAll()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .addLogoutHandler(customLogoutHandler)
        .logoutSuccessHandler(customLogoutSuccessHandler)
        .logoutSuccessUrl("/login?logout")
        .and()
        .exceptionHandling()
        .accessDeniedPage("/403")
                .and()
                .csrf()/* .requireCsrfProtectionMatcher(csrfRequestMatcher) */
        .ignoringAntMatchers("/crud/**","/view/**")
    ;
        // @formatter:off


    }

Thanks

like image 63
adia Avatar answered Oct 29 '25 15:10

adia


You may wish to consider the consumes attribute on the search method to inform spring which Content-Type you expect the method to consume. e.g. @PostMapping(value="/blog/search", consumes=org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE).

Take a look at implementations of org.springframework.http.converter.HttpMessageConverter. Something like the org.springframework.http.converter.FormHttpMessageConverter impl will convert a request body into a MultiValueMap<String,?>

You can also follow this example: Spring MVC - How to get all request params in a map in Spring controller? which uses the @RequestParam annotation instead of @RequestBody.

Can you post a sample curl request that demonstrates the HTTP 405 response - I presume you are posting to the /blog/search endpoint?

like image 25
David Avatar answered Oct 29 '25 14:10

David



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!