Java JSON数据的CORS问题

Java JSON数据的CORS问题,java,angular,maven,cors,jersey-2.0,Java,Angular,Maven,Cors,Jersey 2.0,在本地运行时,我在Angular 7应用程序中遇到以下CORS问题 访问位于的XMLHttpRequest'http://localhost:8080/OnlineOrganicMarket/api/changeorderstatus“起源”http://localhost:4200'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在'access control Allow Origin'标头。 我在后端使用Jersey RESTful Web服务框架。这仅在头类

在本地运行时,我在Angular 7应用程序中遇到以下CORS问题

访问位于的XMLHttpRequest'http://localhost:8080/OnlineOrganicMarket/api/changeorderstatus“起源”http://localhost:4200'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在'access control Allow Origin'标头。

我在后端使用Jersey RESTful Web服务框架。这仅在头类型为
application/json
时发生。它正在为
应用程序/x-www-form-urlencoded
工作

我认为我的CORSFilter课程有问题

package com.oom.services.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

import org.glassfish.jersey.server.ExtendedUriInfo;

@Provider
@Priority(Priorities.HEADER_DECORATOR)
public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter {
 private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
 private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
 private static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
 private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
 private static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
 private static final String AUTHORIZATION = "authorization";
 private static final String ORIGIN = "Origin";

 private static String extractAllowedMethods(final ExtendedUriInfo extendedUriInfo) {
  final Optional<Class<?>> optional = extendedUriInfo.getMatchedRuntimeResources().stream()
    .flatMap(r -> r.getResources().stream()).flatMap(r -> r.getHandlerClasses().stream())
    .filter(r -> r.getPackage().getName().startsWith("com.oom.services")).findFirst();

  if (optional.isPresent()) {
   return Arrays.stream(optional.get().getDeclaredMethods())//
     .flatMap(m -> Arrays.stream(m.getAnnotations()))//
     .map(a -> a.annotationType().getAnnotation(javax.ws.rs.HttpMethod.class))//
     .filter(Objects::nonNull)//
     .map(HttpMethod::value)//
     .distinct()//
     .collect(Collectors.joining(", "));
  }
  // Returning OPTIONS is a bit shady, as ACAM is about *real*, actual methods only.
  return "OPTIONS";
 }

 @Context
 private HttpServletRequest request;

 @Context
 private ExtendedUriInfo extendedUriInfo;

 @Override
 public void filter(final ContainerRequestContext requestContext) throws IOException {
  final String origin = requestContext.getHeaderString(ORIGIN);
  if (origin != null && "OPTIONS".equals(requestContext.getMethod())) {
   request.setAttribute(this.getClass().getName(), true);
   requestContext.abortWith(Response.ok("CORS OK, carry on.", MediaType.TEXT_PLAIN_TYPE).build());
  }
 }

 /**
  * @see https://www.w3.org/TR/cors/
  * @see https://jmchung.github.io/blog/2013/08/11/cross-domain-on-jersey-restful-web-services/
  * @see https://solutionsisee.wordpress.com/2016/06/30/adding-cors-support-in-jersey-server/
  */
 @Override
 public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
   throws IOException {

  final MultivaluedMap<String, Object> responseHeaders = responseContext.getHeaders();
  final String origin = requestContext.getHeaderString(ORIGIN);

  if (origin != null) {
   // The presence of the Origin header marks a CORS request.
   responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
   responseHeaders.add(ACCESS_CONTROL_ALLOW_METHODS, extractAllowedMethods(extendedUriInfo));
   responseHeaders.add(ACCESS_CONTROL_ALLOW_HEADERS, AUTHORIZATION + ", X-Requested-With, Content-Type");
   if (requestContext.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS) != null) {
    responseHeaders.add(ACCESS_CONTROL_ALLOW_CREDENTIALS, requestContext
      .getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS).toLowerCase().contains(AUTHORIZATION));
   }
  }

  if (request.getAttribute(this.getClass().getName()) != null) {
   // We are in a CORS Preflight answer, fast tracked. The entity (== response body) is not
   // relevant.
  }
 }
}

我尝试通过一些扩展禁用CORS,并在chrome浏览器中禁用它。没有任何效果。

正如@mamounothman所评论的,我尝试了Paul Samsotha的以下代码

当我在访问控制允许标题中添加
内容类型
键时,它开始工作

最初由Paul Samsotha回答


我仍然不明白为什么我之前使用的代码不能与头类型内容类型-application/json一起工作,即使它在访问控制允许头的列表中有头类型
内容类型

这将有所帮助,请查看此代码:@mamounothman感谢您的参考。它确实起到了作用。多谢各位
    @POST
    @Path("/changeorderstatus")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateOrderStatus(OrderBean orderStatus) {

        JSONArray responseJson = new OrderDAO().updateOrderStatus(orderStatus);

        return Response.ok(responseJson, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS").build();
    }
package com.oom.services.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

import org.glassfish.jersey.server.ExtendedUriInfo;


@Provider
@PreMatching
public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter {

    /**
     * Method for ContainerRequestFilter.
     */
    @Override
    public void filter(ContainerRequestContext request) throws IOException {

        // If it's a preflight request, we abort the request with
        // a 200 status, and the CORS headers are added in the
        // response filter method below.
        if (isPreflightRequest(request)) {
            request.abortWith(Response.ok().build());
            return;
        }
    }

    /**
     * A preflight request is an OPTIONS request
     * with an Origin header.
     */
    private static boolean isPreflightRequest(ContainerRequestContext request) {
        return request.getHeaderString("Origin") != null
                && request.getMethod().equalsIgnoreCase("OPTIONS");
    }

    /**
     * Method for ContainerResponseFilter.
     */
    @Override
    public void filter(ContainerRequestContext request, ContainerResponseContext response)
            throws IOException {

        // if there is no Origin header, then it is not a
        // cross origin request. We don't do anything.
        if (request.getHeaderString("Origin") == null) {
            return;
        }

        // If it is a preflight request, then we add all
        // the CORS headers here.
        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",
                // Whatever other non-standard/safe headers (see list above) 
                // you want the client to be able to send to the server,
                // put it in this list. And remove the ones you don't want.
                "X-Requested-With, Authorization, " +
                "Accept-Version, Content-type, Content-MD5, CSRF-Token");
        }

        // Cross origin requests can be either simple requests
        // or preflight request. We need to add this header
        // to both type of requests. Only preflight requests
        // need the previously added headers.
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
    }
}