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
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
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With