【问题标题】:Apache CXF handle enum path variable error and return custom responseApache CXF 处理枚举路径变量错误并返回自定义响应
【发布时间】:2019-05-12 06:48:26
【问题描述】:

我有一个路径变量作为枚举。部署在 JBoss 上,如果 productType 的值无效,则会显示带有堆栈跟踪的 HTML 错误页面。我想要做的是处理这个错误并返回一个标准的GenericApiResponse JSON 对象。

@Path("product")
@Produces({ APPLICATION_JSON })
public class ProductEndpoint {

    @GET
    @Path("/{productType}/info")
    public GenericApiResponse info(@PathParam("productType") ProductType productType) {
        // Get product info and return
    }


}

枚举类:

public enum ProductType {

    GLOBAL,
    INTERNAL

    public static ProductType fromString(String value) {
        for(ProductType t : ProductType.class.getEnumConstants()) {
            if(t.name().toLowerCase().equals(value)) {
                return t;
            }
        }

        throw new InvalidProductTypeException();
    }
}

HTML 堆栈跟踪(没什么用)

JBWEB000071: root cause

java.lang.NoSuchMethodError: javax.ws.rs.core.Response.hasEntity()Z
    org.apache.cxf.jaxrs.utils.ExceptionUtils.convertFaultToResponse(ExceptionUtils.java:67)
    org.apache.cxf.jaxrs.utils.JAXRSUtils.convertFaultToResponse(JAXRSUtils.java:1516)
    org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.convertExceptionToResponseIfPossible(JAXRSInInterceptor.java:261)
    org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:92)
    org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:241)
    org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

所以我尝试制作自己的ExceptionMapper,只是它不起作用。我的课程永远不会被调用,并且仍然显示 HTML 错误页面。

InvalidProductTypeExceptionMapper.java

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class InvalidProductTypeExceptionMapper implements ExceptionMapper<InvalidProductTypeException> {

    @Override
    public Response toResponse(InvalidProductTypeExceptione) {
        // This is never being called
        return Response.status(Response.Status.OK)
                .entity(new GenericApiResponse(ResultCode.INVALID_PARAMETERS))
                .build();
    }

}

cxf.xml

<jaxrs:providers>
    <bean class="com.my.mapper.InvalidProductTypeExceptionMapper "/>
</jaxrs:providers>

我的问题:如何处理此类错误并返回自定义响应?

【问题讨论】:

    标签: jakarta-ee jboss cxf


    【解决方案1】:

    我不认为将fromString 方法添加到您的枚举类中对 CXF 有任何作用。

    要进行转换,请考虑使用 ParamConverter 和 ParamConverterProvider:

        public class ProductTypeConverter implements ParamConverter<ProductType> {
    
            @Override
            public ProductType fromString(String value) {
                // throw your exception here.
                ...
            }
    
            @Override
            public String toString(ProductType value) {
                ...
            }
        }
    

    然后添加

        @Provider
        public class MyParamConverterProvider implements ParamConverterProvider{
            @Override
            public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
                if(rawType.equals(ProductType.class)) {
                    return (ParamConverter<T>) new ProductTypeConverter();
                }
                return null;
            }
        }
    

    将提供程序与您的 ExceptionMapper 一起添加到您的端点。它应该会得到你想要的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 2021-01-08
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多