[英]How to handle CORS using JAX-RS with Resteasy, Angular and Wildfly10
我在與我的角度客戶端相同的計算機上的wildfly 10上擁有一個resteasy Web服務。
curl -X DELETE http://localhost:8080/resteasyWebServices-1.0-SNAPSHOT/company/57 -i
可以很好地工作,而無需兩次執行請求。 相反,當用角度客戶端調用時, 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;
}
}
我嘗試將選項方法實現到我的Web服務中,但沒有成功...
package com.solarity.rest; // Note your package will be {{ groupId }}.rest
import com.solarity.entities.CompanyEntity;
import com.solarity.entities.PersonEntity;
import com.solarity.service.CompanyService;
import com.solarity.service.PersonService;
import com.solarity.util.ResponseUtil;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*
*
*/
@Path("/company")
public class CompanyRestService {
protected Logger logger = LoggerFactory.getLogger(getClass());
private CompanyService companyService = new CompanyService();
@GET // This annotation indicates GET request
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public Response getAll() {
Object response = null;
String errMsg = null;
int responseStatus = -1;
try {
this.logger.debug("companyServcfindAll----------------debug");
this.logger.warn("companyServcfindAll----------------WARN");
response = companyService.findAll();
} catch (Exception e) {
errMsg = "Error getting all persons";
logger.error(errMsg, e);
}
return ResponseUtil.getAlteredResponse(response, errMsg, responseStatus, HttpMethod.GET);
}
/**
* curl -X DELETE http://localhost:8080/resteasyWebServices-1.0-SNAPSHOT/company/57 -i
*
* @param id
* @return
*/
@DELETE
@Path("/{param}")
public Response delete(@PathParam("param") Integer id){
Object response = null;
String errMsg = null;
int responseStatus = -1;
try {
logger.debug("Deleting entity", id);
companyService.delete(id);
responseStatus = HttpStatus.SC_OK;
} catch (Exception e) {
errMsg = "Error Deleting Entity:" + id;
logger.error(errMsg, e);
response = errMsg;
responseStatus = HttpStatus.SC_METHOD_FAILURE;
}
return ResponseUtil.getAlteredResponse(response, errMsg, responseStatus, HttpMethod.DELETE);
}
/**
* Not working
* @return
*/
@OPTIONS
@Path("{path : .*}")
public Response options() {
return Response.ok("")
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
.header("Access-Control-Max-Age", "1209600")
.build();
}
}//end Class
這是我的ResponseUtils類
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;
}
}
在該線程中添加OPTIONS請求和響應的副本(不是您創建的副本,而是您正在使用的軟件包中的副本,如果您不使用軟件包,則尋找其中一個),以查看配置出了什么問題。
還添加下一個POST,GET,PUT等請求和響應
首先,有一個我必須閱讀的有關CORS的文檔 ,正如我希望的那樣,我無法避免...
我的問題的部分答案實際上是Angular的兩個電話 。
我不明白, 每次完成對httpclient.put()
subscribe
的調用,都完成了!
調用subscribe()方法將執行observable,它是發起DELETE請求的原因。
所以我做的是:
methodResult = httpclient.put('someUrl', someData, someHeader).subscribe({ data => { console.log('added') });
abovePutMethod.subscribe( data => { doSomeThingWithComponentRefresh })
再次調用 因此, 僅執行一次通話即可解決我的兩次通話問題
//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;
}
您可以在“網絡”標簽中使用Chrome DevTools查看流量
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.