首页 > 解决方案 > 带有方法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>

标签: angularhibernatecorsjersey

解决方案


要在服务器上处理 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-valuefor 中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


推荐阅读