Java 如何使用JAX-RS和Resteasy、Angular和Wildfly10处理CORS
我在wildfly 10上有一个resteasy Web服务,与我的angular客户端在同一台机器上 获取请求工作 Put和delete被调用了2次,据我所知,这是因为飞行前的请求已经完成。curl-X删除http://localhost:8080/resteasyWebServices-1.0-SNAPSHOT/company/57-我可以很好地处理它,无需执行两次请求。相反,当使用angular客户端调用时,restWebService会被调用两次! 我试图添加一个corsFilter,但它不仅帮助我获取请求,而且没有帮助我解决问题Java 如何使用JAX-RS和Resteasy、Angular和Wildfly10处理CORS,java,cors,resteasy,wildfly-10,Java,Cors,Resteasy,Wildfly 10,我在wildfly 10上有一个resteasy Web服务,与我的angular客户端在同一台机器上 获取请求工作 Put和delete被调用了2次,据我所知,这是因为飞行前的请求已经完成。curl-X删除http://localhost:8080/resteasyWebServices-1.0-SNAPSHOT/company/57-我可以很好地处理它,无需执行两次请求。相反,当使用angular客户端调用时,restWebService会被调用两次! 我试图添加一个corsFilter,但
package com.solarity.app; // {{ groupId}}.app
import com.solarity.rest.CompanyRestService;
import com.solarity.rest.PersonRestService;
import org.jboss.resteasy.plugins.interceptors.CorsFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
@ApplicationPath("/")
public class InitApplication extends Application {
/**
*
*/
Set<Object> singletons;
HashSet<Class<?>> webServiceClasses;
public InitApplication() {
super();
webServiceClasses = new HashSet<>();
webServiceClasses.add(PersonRestService.class);
webServiceClasses.add(CompanyRestService.class);
singletons = new LinkedHashSet<>();
singletons.add(this.getCorsFilter());
}
@Override
public Set<Class<?>> getClasses() {
return webServiceClasses;
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
private CorsFilter getCorsFilter() {
CorsFilter result = new CorsFilter();
result.getAllowedOrigins().add("http://localhost:4200");
return result;
}
}
这是我的回答课
package com.solarity.util;
import org.apache.http.HttpStatus;
import javax.ws.rs.core.Response;
public class ResponseUtil {
/**
*
Built to counter a Angular cross-reference problem
Adapted for Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/dlssResteasy1-1.0-SNAPSHOT/person/getPersonsAsJSON. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
source answer https://stackoverflow.com/questions/23450494/how-to-enable-cross-domain-requests-on-jax-rs-web-services?answertab=votes#tab-top
More Documentation about CORS on https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
* @param param the object to send if errorMsg is null
* @param errorMsg if not null sends an error code with error Message
* @param responseStatus response status which can be found from HttpStatus.* (if <= 0 will be taken from errorMsg, or ok)
* @return an altered response which is customized
*/
public static Response getAlteredResponse( Object param, String errorMsg, int responseStatus, String httpMethod ) {
Response result = null;
int rStatus = responseStatus;
if (errorMsg != null && responseStatus <= 0) {
rStatus = HttpStatus.SC_UNPROCESSABLE_ENTITY;
} else if (errorMsg == null && responseStatus <= 0){
rStatus = HttpStatus.SC_OK;
}
if ( errorMsg == null ) {
result = Response
.status(rStatus)
.entity(param)
.build();
}else{
result = Response.status(rStatus)
.entity(errorMsg)
.build();
}
return result;
}
}
下面是调试到FF的结果
观察选项请求和响应,并确保来自服务器的选项响应包含正确的信息。它告诉客户端服务器正在接受什么
稍后观察真正的请求PUT GET POST等进入服务器。它是否具有您想要的所有头文件?
您不需要创建和选择路由。请参阅此处的RFC
将选项请求和响应的副本(不是您创建的副本,而是您正在使用的包中的副本)添加到此线程中。如果您没有使用包,请查找一个副本,以查看配置有何问题
同时添加下一篇文章、GET、PUT等。请求和响应都是这样的首先,我必须阅读一篇文章才能理解,正如我所希望的那样,我无法避免
两个来自Angular的电话
事实上,我问题的部分答案是来自Angular的两个电话
我不明白,每次在httpclient.put上进行订阅调用时,调用都已完成
调用subscribe方法执行observable,这就是
启动删除请求
所以我所做的是:
callmethodresult=httpclient.put'someUrl',someData,someHeader.subscribe{data=>{console.log'added'};
在该方法的调用方上,使用UpperPutMethod.subscribe data=>{doSomeThingWithComponentRefresh}再次调用
所以,只做一次呼叫订阅解决了我的两次呼叫问题
对于CORS协议的其余部分
棱角客户端
Java Resteasy服务器
你可以在网络选项卡中看到Chrome DevTools的流量!我在哪里可以观察到?wireshark的唯一解决方案是什么?一切都如你所愿吗?你在Java中使用了什么软件包?在python Flask中,我使用了resteasy附带的Flask cors.cors。一切都如你所愿……很高兴听到这个消息
package com.solarity.util;
import org.apache.http.HttpStatus;
import javax.ws.rs.core.Response;
public class ResponseUtil {
/**
*
Built to counter a Angular cross-reference problem
Adapted for Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/dlssResteasy1-1.0-SNAPSHOT/person/getPersonsAsJSON. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
source answer https://stackoverflow.com/questions/23450494/how-to-enable-cross-domain-requests-on-jax-rs-web-services?answertab=votes#tab-top
More Documentation about CORS on https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
* @param param the object to send if errorMsg is null
* @param errorMsg if not null sends an error code with error Message
* @param responseStatus response status which can be found from HttpStatus.* (if <= 0 will be taken from errorMsg, or ok)
* @return an altered response which is customized
*/
public static Response getAlteredResponse( Object param, String errorMsg, int responseStatus, String httpMethod ) {
Response result = null;
int rStatus = responseStatus;
if (errorMsg != null && responseStatus <= 0) {
rStatus = HttpStatus.SC_UNPROCESSABLE_ENTITY;
} else if (errorMsg == null && responseStatus <= 0){
rStatus = HttpStatus.SC_OK;
}
if ( errorMsg == null ) {
result = Response
.status(rStatus)
.entity(param)
.build();
}else{
result = Response.status(rStatus)
.entity(errorMsg)
.build();
}
return result;
}
}
//UrlHelper
public static putHttpRequestOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
//Function call somewhere
const result = this.httpClient.put(url, jsonStringValues, UrlHelper.putHttpRequestOptions);
// InitApplication extends Application
public InitApplication() {
super();
webServiceClasses = new HashSet<>();
webServiceClasses.add(PersonRestService.class);
webServiceClasses.add(CompanyRestService.class);
singletons = new LinkedHashSet<>();
singletons.add(this.getCorsFilter());
}
private CorsFilter getCorsFilter() {
CorsFilter result = new CorsFilter();
result.getAllowedOrigins().add("*");
result.setAllowedMethods("OPTIONS, GET, POST, DELETE, PUT, PATCH");
result.setCorsMaxAge(86400);//Max in FF 86400=24h https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
//
return result;
}
// RestWebService
@PUT
@Path("/")
@Consumes(MediaType.APPLICATION_JSON)
public Response put(CompanyEntity entity ){
Object response = null;
String errMsg = null;
int responseStatus = -1;
try {
logger.debug("Received entity", entity);
companyService.persist(entity);
responseStatus = HttpStatus.SC_CREATED;
} catch (Exception e) {
errMsg = "Error adding Entity:" + entity;
logger.error(errMsg, e);
response = errMsg;
responseStatus = HttpStatus.SC_METHOD_FAILURE;
}
return ResponseUtil.getAlteredResponse(response, errMsg, responseStatus, HttpMethod.PUT);
}
// Called on result of all RestWebServices (I'm sure there are better/best practices, feel free to comment me this section)
/**
* @param param the object to send if errorMsg is null
* @param errorMsg if not null sends an error code with error Message
* @param responseStatus response status which can be found from HttpStatus.* (if <= 0 will be taken from errorMsg, or ok)
* @return an altered response which is customized
*/
public static Response getAlteredResponse( Object param, String errorMsg, int responseStatus, String httpMethod ) {
Response result = null;
int rStatus = responseStatus;
if (errorMsg != null && responseStatus <= 0) {
rStatus = HttpStatus.SC_UNPROCESSABLE_ENTITY;
} else if (errorMsg == null && responseStatus <= 0){
rStatus = HttpStatus.SC_OK;
}
String accessControlAllowMethods = "GET, POST, PUT, DELETE, OPTIONS, HEAD";
if ( errorMsg == null ) {
result = Response
.status(rStatus)
.header("Access-Control-Allow-Origin", "*") //TODO: fix permission here!
.header("Access-Control-Allow-Methods", accessControlAllowMethods)
.header("Access-Control-Max-Age", "1728000")
.entity(param)
.build();
}else{
result = Response.status(rStatus)
.header("Access-Control-Allow-Origin", "*") //TODO: fix permission here!
.header("Access-Control-Allow-Methods", accessControlAllowMethods)
.header("Access-Control-Max-Age", "1728000")
.entity(errorMsg)
.build();
}
return result;
}