angular - 带有方法post的rest api中的错误405
问题描述
我的程序 java rest api 中的方法 post 有问题。我用作后端:球衣和休眠,并用作前端:角度。当我通过 Angular 应用程序中的方法 post 和 Web 浏览器中的测试程序使用 Web 服务时,控制台浏览器显示错误:
“加载资源失败:服务器响应状态为 405(不允许的方法)”
我看到一个关于这个问题的教程,它给了我一个使用 CORS 管理 http 方法的解决方案,我了解 CORS,但我的问题是: - 如何在我的 java 程序中编码这个 CORS?- 我应该使用 CORS 方法创建一个类吗?- 我应该在我的程序中哪里调用 CORS?请帮我。非常感谢您
这是休息api
package com.ws.rest;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.ws.dao.DaoFactory;
import com.ws.entity.Personne;
import com.ws.jpa.PersonneJPA;
@Path("/personne")
public class PersonneRest {
private PersonneJPA jpa_personne;
public PersonneRest() {
this.jpa_personne = DaoFactory.getInstance().get_personne();
}
/*
* #########################################################################
* PROCEDURES
* #########################################################################
*/
// Getall
@Path("/getall")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Personne> getAll() {
return jpa_personne.findAll();
}
// Get par ID
@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Personne getById(@PathParam("id") long id) {
List<Personne> h_personne = jpa_personne.findById(id);
if (h_personne == null)
return null;
return h_personne.get(0);
}
// Ajout d'un enregistrement de type Langue
@Path("/add")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void add(Personne personne) {
jpa_personne.add(personne);
}
// Mise a jour d'un enregistrement de type Langue
@Path("/update")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void update(Personne personne) {
jpa_personne.update(personne);
}
// Suppression d'un enregistrement de type Langue
@Path("/delete")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void delete(Personne personne) {
jpa_personne.delete(personne);
}
}
这是 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Define the ResourceConfig class -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ws.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all the URLs to the Jersey ServletContainer -->
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
解决方案
要在服务器上处理 CORS,您应该使用Jersey 请求/响应过滤器。此过滤器正确处理CORS Preflight 请求和常规 CORS 请求。
如果您使用包扫描来注册您的资源和提供者,那么过滤器应该会因为@Provider
注释而自动注册。
@Provider
@PreMatching
public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
if (isPreflightRequest(request)) {
request.abortWith(Response.ok().build());
return;
}
}
private static boolean isPreflightRequest(ContainerRequestContext request) {
return request.getHeaderString("Origin") != null
&& request.getMethod().equalsIgnoreCase("OPTIONS");
}
@Override
public void filter(ContainerRequestContext request, ContainerResponseContext response)
throws IOException {
if (request.getHeaderString("Origin") == null) {
return;
}
if (isPreflightRequest(request)) {
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.getHeaders().add("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, " +
"Accept-Version, Content-Length, Content-MD5, CSRF-Token");
}
response.getHeaders().add("Access-Control-Allow-Origin", "*");
}
}
更新
要注册过滤器,您要做的是将过滤器所在的包放入param-value
for 中init-param
,告诉 Jersey 扫描这些包以查找您的资源和提供者。因此,如果您的过滤器位于 中com.ws.util
,那么您将执行以下操作
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.ws.rest, com.ws.util</param-value>
</init-param>
请注意,我刚刚添加了用逗号分隔的包。您也可以简单地切换列出的两个包com.ws
。包扫描是递归的,因此仅列出父包,将导致扫描同时到达com.ws.rest
和 com.ws.util
。
推荐阅读
- c# - HTMLAgilityPack InnerHTML,解析错误错误
- flutter - 如何解决 OS 错误:Permission denied, errno = 13 in flutter
- java - 在同一个项目中跨多个模块重用测试类
- blazor - Blazor:如何将 ViewModel 从子组件传递到父组件,反之亦然
- pseudocode - 如何找到乘以 i 的语句的时间复杂度
- python - 如何动态且独立地移动 pandas DataFrame 中的列?
- css - 如何突出显示导航的部分?
- angular - 如何在另一个组件中访问一个组件的变量 [Angular]
- c# - 在插入之前检查 DataGridview 中的值是否与数据库表/模式兼容
- ios - 如何以编程方式快速调整视图大小?