使用方法发布的REST API中出现错误405

时间:2018-08-13 08:56:38

标签: angular hibernate cors jersey

我在我的程序Java rest api中有关于方法发布的问题。我用作后端:球衣和冬眠,用作前端:棱角分明。当我通过角度应用程序中的方法发布使用Web服务并在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>

1 个答案:

答案 0 :(得分:0)

要在服务器上处理CORS,应使用Jersey request/response filter。此过滤器可以正确处理CORS Preflight request和常规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的{​​{1}}中,这告诉Jersey扫描这些软件包中的资源和提供者。因此,如果您的过滤器位于init-param中,则可以执行以下操作

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 { {1}}。