Java Jersey CORS 不允许外部请求

Posted

技术标签:

【中文标题】Java Jersey CORS 不允许外部请求【英文标题】:Java Jersey CORS not allowed external requests 【发布时间】:2021-09-03 21:01:09 【问题描述】:

我在 http://localhost:8093 上使用 Java Jersey 制作了一个简单的 REST API 接口,但是当我通过不同的服务(例如 http://localhost:80/)通过 javascript 发送 XmlHTTPRequest 时,不允许使用 CORS。 这是我非常简单的 sn-p 代码:

//---------------------------------------------应用程序.java:

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@ApplicationPath("rest")
public class Application extends ResourceConfig 
    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);    
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() 
            public void run() 
            
        ));    
    
    
    public Application() 
        register(new UserAPI());
    

//---------------------------------------------用户API.java:

import java.text.ParseException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;


@Consumes("application/json")
@Produces("application/json")
@Path("user")
public class UserAPI 
    @POST
    @Path("add")    
    public void addUser(UserBean ub) throws ParseException, UserException, NullPasswordException        
        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        User u= new User(ub.getUsername(), ub.getRole());
        (new MongoDataManager()).addUser(u);

    
    @POST
    @Path("edit")    
    public void editUser(UserBean ub) throws ParseException, UserException, NullPasswordException        
        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        User u= new User(ub.getUsername(), ub.getPassword());
        u.setRole(Role.valueOf(ub.getRole()));
        u.setPasswordLastUpdate(new Date());
        
        (new MongoDataManager()).editUser(u);
        

    
    
    @POST
    @Path("delete")    
    public void deleteUser(UserBean ub) throws ParseException         

        Logger mongoLogger = Logger.getLogger( "org.mongodb.driver" );
        mongoLogger.setLevel(Level.SEVERE);
        
        
        
        (new MongoDataManager()).deleteUser(ub.getUsername());    
         

//--------------------------------------------- UserBean.java:

public class UserBean 
    private String         username, password, temppass;
    private String    residence;
    private String        role;
    private String        password_lastupdate;
    public String getUsername() 
        return username;
    
    public void setUsername(String username) 
        this.username = username;
    
    public String getPassword() 
        return password;
    
    public void setPassword(String password) 
        this.password = password;
    
    public String getTemppass() 
        return temppass;
    
    public void setTemppass(String temppass) 
        this.temppass = temppass;
    
    public String getResidence() 
        return residence;
    
    public void setResidence(String residence) 
        this.residence = residence;
    
    public String getRole() 
        return role;
    
    public void setRole(String role) 
        this.role = role;
    
    public String getPassword_lastupdate() 
        return password_lastupdate;
    
    public void setPassword_lastupdate(String password_lastupdate) 
        this.password_lastupdate = password_lastupdate;
    
    

//--------------------------------------------- Javascript函数:

 function create() 
    event.preventDefault()           
    let isNew = document.getElementById("createNuovoUser").checked;
    console.log(isNew)       
let url;
let request = new XMLHttpRequest();   // new HttpRequest instance


if (isNew)
    url = 'http://localhost:8093/rest/user/delete'
    request.open("POST", url, true);
    request.setRequestHeader("content-type", "application/json");

    request.onreadystatechange = function() 
        if (this.readyState === 4) 
            document.getElementById("createTextArea").value = username + "\n";
            alert("User eliminato");
        
    ;
     let username = document.getElementById("username").value 
     let role = document.getElementById("role").value
    request.send(JSON.stringify("username": username));
 else
    url = 'http://localhost:8093/rest/user/add'
    request.open("POST", url, true);
    request.setRequestHeader("content-type", "application/json");

    request.onreadystatechange = function() 
        if (this.readyState === 4) 
            document.getElementById("createTextArea").value = username + "\n" + role;
            alert("User cereato");

        
    ;
    
   let username = document.getElementById("username").value
   let role = document.getElementById("role").value
    request.send(JSON.stringify("username": username, "role": role));

感谢任何建议或解决方案 谢谢

【问题讨论】:

您的服务器代码需要设置一些 CORS 标头 - learn cors in 6 minutes 由于您正在执行的 javascript 从不同的端口提供服务,因此它被认为是不同的来源。当您发送 XHR 或 ajax 请求(在用户不知情的情况下)时,浏览器将应用 CORS 策略。您需要在服务器中设置 CORS 标头,以允许从其他端口访问。 Yoy 可以在 MDN 页面developer.mozilla.org/es/docs/Web/HTTP/CORS 中找到更多相关信息 【参考方案1】:

这是球衣的正常问题。 您只需要添加一个允许“选项”请求的请求过滤器

看看这个话题 How to handle CORS using JAX-RS with Jersey

在实践中,你需要实现一个类来扩展服务器配置

import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

@Provider
public class CORSFilter implements ContainerResponseFilter 

@Override
public void filter(ContainerRequestContext request,
        ContainerResponseContext response) throws IOException 
    response.getHeaders().add("Access-Control-Allow-Origin", "*");
    response.getHeaders().add("Access-Control-Allow-Headers",
            "CSRF-Token, X-Requested-By, Authorization, Content-Type");
    response.getHeaders().add("Access-Control-Allow-Credentials", "true");
    response.getHeaders().add("Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS, HEAD");

然后在服务器类中使用此代码显式选择它

final ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(new CORSFilter());

【讨论】:

我尝试了很多指南,但结果总是否定的。你能为我的代码提供一个解决方案吗?

以上是关于Java Jersey CORS 不允许外部请求的主要内容,如果未能解决你的问题,请参考以下文章

启用从 AngularJS 到 Jersey 的 CORS 发布请求

无法在 JavaScript 中向 Java Web 服务(球衣)发出 CORS POST 请求?

跨域请求被阻止:同源策略不允许读取远程资源,CORS 标头中缺少令牌“缓存控制”

CORS 允许以管理员身份登录,但不允许 put 请求

Jersey REST GET 正在工作,但 PUT 没有。请求的资源不允许指定的 HTTP 方法

自定义 HTTP 标头块 Jersey CORS 过滤器