Java 不允许使用Spring Boot-Post方法,但可以使用GET-works
我的spring boot mysql项目有问题, 控制器类只为find方法GET(GET all)工作,但我似乎无法发布 和获取错误405:不允许使用方法“POST” 这是我的控制器类:Java 不允许使用Spring Boot-Post方法,但可以使用GET-works,java,spring,spring-boot,jpa,Java,Spring,Spring Boot,Jpa,我的spring boot mysql项目有问题, 控制器类只为find方法GET(GET all)工作,但我似乎无法发布 和获取错误405:不允许使用方法“POST” 这是我的控制器类: package com.example.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; i
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;
}
}
package com.example.demo.controller;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.web.bind.annotation.*;
导入com.example.demo.Blog;
导入com.example.demo.repository.blogrepository;
导入java.util.List;
导入java.util.Map;
@RestController
公共类BlogController{
@自动连线
blogrepository blogrepository;
@GetMapping(“/blog”)
公共列表索引(){
返回blogrepository.findAll();
}
@GetMapping(“/blog/{id}”)
公共博客显示(@PathVariable字符串id){
intblogid=Integer.parseInt(id);
返回blogrepository.findById(blogId)
.orelsetrow(()->新的IllegalArgumentException(
“请求的结果id[”+id+
“]不存在。”);
}
@后期映射(“/blog/search”)
公共列表搜索(@RequestBody-Map-body){
字符串searchTerm=body.get(“文本”);
返回blogrepository.findBytleteContainingorContentContaining(searchTerm,searchTerm);
}
@后映射(“/blog”)
公共博客创建(@RequestBody-Map-body){
字符串title=body.get(“title”);
字符串内容=body.get(“内容”);
返回blogrepository.save(新博客(标题、内容));
}
@PutMapping(“/blog/{id}”)
公共博客更新(@PathVariable字符串id,@RequestBody映射体){
intblogid=Integer.parseInt(id);
//获取博客
Blog Blog=blogrepository.findById(blogId)
.orelsetrow(()->新的IllegalArgumentException(
“请求的结果id[”+id+
“]不存在。”);
blog.setTitle(body.get(“title”);
blog.setContent(body.get(“content”);
返回blogrepository.save(blog);
}
@DeleteMapping(“blog/{id}”)
公共布尔删除(@PathVariable字符串id){
intblogid=Integer.parseInt(id);
blogrepository.delete(blogId);
返回true;
}
}
这是我的存储库类,如果你需要的话
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);
}
package com.example.demo.repository;
导入org.springframework.data.jpa.repository.JpaRepository;
导入org.springframework.stereotype.Repository;
导入com.example.demo.Blog;
导入java.util.List;
@存储库
公共接口blogrepository扩展了JpaRepository{
//按标题或内容搜索博客文章的自定义查询
列出FindBytleteContainingorContentContaining(字符串文本,字符串文本再次);
}
我尝试使用SOAPUI进行POST请求,但似乎无法找到解决方案,多谢
< P>您可能希望在搜索方法上考虑<代码>消费< /代码>属性来通知Spring哪一个<代码>内容类型< /C> >您希望该方法被消费。e、 g.@PostMapping(value=“/blog/search”,consumes=org.springframework.http.MediaType.APPLICATION\u FORM\u URLENCODED\u value)
看看org.springframework.http.converter.HttpMessageConverter的实现。类似于org.springframework.http.converter.FormHttpMessageConverter
impl的东西将请求主体转换为多值映射
您还可以遵循以下示例:它使用@RequestParam
注释而不是@RequestBody
您可以发布一个示例
curl
请求来演示HTTP 405
响应吗?我假定您正在发布到/blog/search
端点?如果配置或启用了csrf,将不允许方法发布
然后,您需要在发布表单或数据时提供有效的csrf
请检查您的spring安全配置以了解此信息
比如说
@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
}
谢谢我试图通过编写一个伪代码来重现这个问题,但它对我来说工作得非常好 请在下面找到我尝试的代码片段-
package com.pradeep.rest.controller;
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RestRequestController {
@GetMapping("/blog")
public String show() {
String result = "Hello from show";
return result;
}
@PostMapping("/blog")
public String create(@RequestBody Map<String, String> body) {
String title = body.get("title");
String content = body.get("content");
String result = "title= " + title + " : content= " + content;
return result;
}
}
package com.pradeep.rest.controller;
导入java.util.Map;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.PostMapping;
导入org.springframework.web.bind.annotation.RequestBody;
导入org.springframework.web.bind.annotation.RestController;
@RestController
公共类RestRequestController{
@GetMapping(“/blog”)
公共字符串显示(){
String result=“Hello from show”;
返回结果;
}
@后映射(“/blog”)
创建公共字符串(@RequestBody映射体){
字符串title=body.get(“title”);
字符串内容=body.get(“内容”);
字符串结果=“title=“+title+”:content=“+content;
返回结果;
}
}
pom.xml:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pradeep.rest</groupId>
<artifactId>RestApi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- to ease development environment -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
4.0.0
com.pradeep.rest
我的试验非常成功
这是我的控制器。
我遵循了这个教程
包io.crzn.myNotes.controller;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入javax.validation.Valid;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.http.ResponseEntity;
导入org.springframework.web.bind.annotation.CrossOrigin;
导入org.springframework.web.bind.annotation.DeleteMapping;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.PathVariable;
导入org.springframework.web.bind.annotation.PostMapping;
导入org.springframework.web.bind.annotation.PutMapping;
导入org.springframework.web.bind.annotation.RequestBody;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RestController;
导入io.crzn.myNotes.exception.ResourceNotFoundException;
导入io.crzn.myNotes.model.myNotes;
导入io.crzn.myNotes.repository.myNotesRepository;
@雷斯科
package io.crzn.myNotes.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.crzn.myNotes.exception.ResourceNotFoundException;
import io.crzn.myNotes.model.MyNotes;
import io.crzn.myNotes.repository.myNotesRepository;
@RestController
@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping("/api/v1")
public class myNotesController {
@Autowired
private myNotesRepository mynotesRepository;
@GetMapping("/mynotes")
public List<MyNotes> getAllmyNotes(){
return mynotesRepository.findAll();
}
@GetMapping("/mynotes/{id}")
public ResponseEntity<MyNotes> getEmployeeById(@PathVariable(value = "id") Long mynotesId)
throws ResourceNotFoundException{
MyNotes mynotes = mynotesRepository.findById(mynotesId)
.orElseThrow(() -> new ResourceNotFoundException("Note not found for this id : :" + mynotesId));
return ResponseEntity.ok().body(mynotes);
}
@PostMapping("/mynotes")
public MyNotes createMyNotes(@Valid @RequestBody MyNotes mynotes) {
return mynotesRepository.save(mynotes);
}
@PutMapping("/mynotes/{id}")
public ResponseEntity<MyNotes> updateMyNotes(@PathVariable(value = "id") Long mynotesId,
@Valid @RequestBody MyNotes mynotesDetails)
throws ResourceNotFoundException{
MyNotes mynotes = mynotesRepository.findById(mynotesId)
.orElseThrow(() -> new ResourceNotFoundException("Not not found for this id : : " + mynotesId));
mynotes.setstatus(mynotesDetails.getstatus());
mynotes.setbody(mynotesDetails.getbody());
mynotes.settitle(mynotesDetails.gettitle());
final MyNotes updatedMyNotes = mynotesRepository.save(mynotes);
return ResponseEntity.ok(updatedMyNotes);
}
@DeleteMapping("/mynotes/{id}")
public Map<String, Boolean> deleteMyNotes(@PathVariable(value = "id") Long mynotesId)
throws ResourceNotFoundException{
MyNotes mynotes = mynotesRepository.findById(mynotesId)
.orElseThrow(() -> new ResourceNotFoundException("Not not found for this id : : " + mynotesId));
mynotesRepository.delete(mynotes);
Map<String, Boolean> response = new HashMap<>();
response.put("deleted", Boolean.TRUE);
return response;
}
}