代码之家  ›  专栏  ›  技术社区  ›  JGFMK

JAX-RS(Jersey 2实现)带有URL扩展的内容协商。xml或。json

  •  3
  • JGFMK  · 技术社区  · 7 年前

    我看到了一个Java RESTFUL webservice,它允许在URL中请求内容类型,并在末尾添加一个扩展,例如

    • .xml
    • .json

    这就是我在自己的Web服务中努力实现的内容协商风格。

    我知道 @Produces 注释,以及一个方法可以使用 (value = {}) 语法,通过添加一个Accept头,例如使用Postman,Chrome扩展。

    但我不知道如何有效地从一种方法中提取信息,并委托给另一种方法。

    我假设正则表达式可以用于 @Path @PathParam ,但我的尝试尚未取得成果。

    有人能举个例子吗?


    这是我迄今为止的尝试:

    package com.extratechnology.caaews;
    
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    
    import com.extratechnology.caaews.model.Log;
    
    
    @Path("et")
    @Produces(MediaType.APPLICATION_JSON)
    public class CAAEWS {
    
    
        @GET
        @Path("\\.{format}")
        @Produces(value = {MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
        public Log getLog(
                @PathParam("format") String format
        ){
            Log result = null;
            switch (format) {
            case "json":
                result = this.getJSON();
            case "xml":
                result = this.getXML();
            }
            return result;
        }
    
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Log getJSON() {
            return new Log("JSON!");
        }
    
        @GET
        @Produces(MediaType.TEXT_XML)
        public Log getXML() {
            return new Log("XML!");
        }
    
    }
    

    package com.extratechnology.caaews.model;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Log {
        private String log;
    
        public Log(String log) {
            this.log = log;
        }
    
        public String getLog() {
            return log;
        }
    
        public void setLog(String log) {
            this.log = log;
        }
    
    }
    

    该项目可以通过创建Maven项目(类似于,但比 here circa 4:50 )使用以下各项:

    • 组织。玻璃鱼。运动衫原型
    • 运动衫快速启动。网络应用程序
    • 2.26

    然后取消对pom部分的注释。提供xml以支持JSON,这有效地为WAR添加了更多JAR。

    我发现我也有一些严重的BCEL错误,不得不在 卡特琳娜。属性 文件,键下:

    tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\
    ....
    javax.json-api-1.1.jar, javax.json.bind-api-1.0.jar, javax.json-1.1.jar, \
    yasson-1.0.jar
    

    http://localhost:18080/caaews/webapi/et

    产量:

    {"log":"JSON!"}
    

    http://localhost:18080/caaews/webapi/et.xml

    http://localhost:18080/caaews/webapi/et.json

    产量:

    HTTP Status 404 - Not Found
    

    我还想知道是否有某种HTTP侦听器类型的方法来实现这一点。我的Java有点过时了,但它是servlet过滤器,还是类似于AOP的建议。


    多亏了@user1803551,我在switch语句中加入了中断符。

    多亏了@callmepills,我对代码进行了一些调整。

    类级别的@Path注释现在具有此功能。 @产生(值={MediaType.APPLICATION\u JSON,MediaType.TEXT\u XML})

    getLog@Path注释是“{format}”。

    为了调用和委托getLog,必须对URL使用以下语法:

    http://localhost:18080/caaews/webapi/et

    http://localhost:18080/caaews/webapi/et/.xml

    http://localhost:18080/caaews/webapi/et/.json

    路径中需要一个“/”不是我想要的,所以我认为我可能必须解决servlet过滤器,而不是@PathParam方法。。

    4 回复  |  直到 7 年前
        1
  •  1
  •   Community Dai    4 年前

    即使你没有标记 ,您的问题表明您正在使用Jersey,因此我将发布一个特定于Jersey的解决方案。Jersey提供的是 property that you can use to set the media type mappings

    ServerPropeties.MEDIA_TYPE_MAPPINGS

    public static final String MEDIA_TYPE_MAPPINGS

    定义URI扩展到媒体类型的映射。该属性由使用 UriConnegFilter . 有关媒体类型映射的更多信息,请参阅javadoc。

    属性值必须是的实例 String , String[] Map<String, MediaType> . 每个字符串实例表示媒体类型映射项的一个或多个uri扩展,用逗号(“,”)分隔。每个映射条目都是一个由冒号(“:”)分隔的键值对。下面是一个可接受的字符串值映射示例,该字符串值将txt扩展名映射为text/plain,将xml扩展名映射为application/xml:

    txt : text/plain, xml : application/xml
    

    未设置默认值。

    Java配置示例

    final Map<String, MediaType> mediaTypeMappings = new HashMap<>();
    mediaTypeMappings.put("xml", MediaType.APPLICATION_XML_TYPE);
    mediaTypeMappings.put("json", MediaType.APPLICATION_JSON_TYPE);
    
    final ResourceConfig rc = new ResourceConfig()
            .packages("com.example.jersey")
            .property(ServerProperties.MEDIA_TYPE_MAPPINGS, mediaTypeMappings);
    

    web示例。xml配置

    <servlet>
        <servlet-name>JerseyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.example</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.server.mediaTypeMappings</param-name>
            <param-value>xml:application/xml, json:application/json</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
        2
  •  1
  •   user1803551    7 年前

    JAX-RS代码有几个问题:

    正则表达式in @Path

    这个 value @路径 注释仅在参数模板内和之后解析正则表达式 : 性格您试图在参数模板之外使用正则表达式, "\\.{format}" ,因此它没有将其解析为正则表达式。

    路径分辨率

    一个方法的路径包括类路径的段,然后是它自己的路径段。您的代码建议路径 /et/.{format} /et 当你打电话的时候 /et.{format} ,这在任何地方都没有定义,因此404。


    下面是一个符合您的代码的示例:

    @Path("et")
    public class Resource {
    
        private static final String JSON = "json";
        private static final String XML = "xml";
    
        @GET
        @Path(".{format:(" + JSON + "|" + XML + ")}")
        @Produces(value = { MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) // not XML?
        public String getLog(@PathParam("format") String format) {
            switch (format) {
                case JSON:
                    this.getJSON();
                    break;
                case XML:
                    this.getXML();
            }
            return format;
        }
    
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public void getJSON() {
            System.out.println("in JSON");
        }
    
        @GET
        @Path("otherPath")
        @Produces(MediaType.APPLICATION_XML)
        public void getXML() {
            System.out.println("in XML");
        }
    }
    

    您的有效请求现在是:

    根据需要更改路径。我用过 "otherPath" 因为它不能与空路径JSON方法冲突。我不建议这样做。

    笔记:

    • 使用 break switch 陈述
    • 为了减少出现错误的机会,请像我对自定义格式类型所做的那样,对可重用字符串等使用常量。一 enum 会更好。

    编辑:

    请求现在需要有一个路径 /et/<something>.{format} . 如果我们将路径参数的范围扩大到包括整个线段,就可以实现这一点 <something>.{format} 然后以编程方式提取格式:

    @GET
    @Path("{segment:[a-zA-Z0-9_]*\\.(" + JSON + "|" + XML + ")}")
    @Produces(value = { MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
    public String getLog(@PathParam("segment") String segment) {
        String format = segment.substring(segment.indexOf('.') + 1);
        switch (format) {
            case JSON:
                this.getJSON();
                break;
            case XML:
                this.getXML();
        }
        return format;
    }
    

    正则表达式 [a-zA-Z0-9_]* 指任何字母数字或下划线一次或多次。你可以用你想要的任何限制来替换那个部分。有关允许的字符,请参阅URL规范。

        3
  •  0
  •   callmepills    7 年前

    你试过摆脱 @Path 类级别的注释?然后,您的方法级注释将是:

    @Path("et.{format}")
    

    我认为您当前的实现正在创建一个子资源,该子资源与以下路径匹配:

    /et/{format}
    
        4
  •  -1
  •   JGFMK    7 年前

    当我在谷歌上搜索“带有jax rs示例的servlet过滤器”时, this 排在榜首。粗略地看一下代码,我认为这符合我的需要。


    这是我的解决方案(到目前为止……请参阅脚注告诫)

    网状物xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- This web.xml file is not required when using Servlet 3.0 container,
         see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
      <filter>
            <filter-name>accept-filter</filter-name>
            <filter-class>com.extratechnology.filters.AcceptFilter</filter-class>
            <init-param>
                <param-name>xml</param-name>
                <param-value>text/xml</param-value>
            </init-param>
            <init-param>
                <param-name>json</param-name>
                <param-value>application/json</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>accept-filter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>com.extratechnology.caaews</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/webapi/*</url-pattern>
        </servlet-mapping>
    </web-app>
    

    AcceptFilter。Java语言

    package com.extratechnology.filters;
    import java.io.IOException;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class AcceptFilter implements Filter  {
        private final Map<String,String> extensions = new HashMap<String,String>();
    
        public void init(FilterConfig config) throws ServletException {
            Enumeration<String> exts = config.getInitParameterNames();
            while (exts.hasMoreElements()) {
                String ext = exts.nextElement();
                if (ext != null && !ext.isEmpty()) {
                    this.extensions.put(ext.toLowerCase(), config.getInitParameter(ext));
                }
            }
        }
    
        public void destroy() {}
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpRequest = (HttpServletRequest)request;
            String uri = httpRequest.getRequestURI();
            String ext = this.getExtension(uri);
            String accept = this.extensions.get(ext);
    
            if (accept == null) {
                accept = httpRequest.getHeader("accept");
                if (accept != null && accept.indexOf("text/html") > 0) {
                    // patch WebKit-style Accept headers by elevating "text/html"
                    accept = "text/html,"+accept;
                    request = new RequestWrapper(httpRequest, uri, accept);
                }
            } else {
                // remove extension and remap the Accept header
                uri = uri.substring(0, uri.length() - ext.length()-1);
                request = new RequestWrapper(httpRequest, uri, accept);
            }
    
            // add "Vary: accept" to the response headers
            HttpServletResponse httpResponse = (HttpServletResponse)response;
            httpResponse.addHeader("Vary", "accept");
    
            chain.doFilter(request, response);
        }
    
        private String getExtension(String path) {
            String result = "";
            int index = path.lastIndexOf('.');
            if (!(index < 0 || path.lastIndexOf('/') > index)) {
                result =  path.substring(index+1).toLowerCase();
            }
            return result;
        }
    
        private static class RequestWrapper extends HttpServletRequestWrapper {
    
            private final String uri;
            private final String accept;
    
            public RequestWrapper(HttpServletRequest request, String uri, String accept) {
                super(request);
    
                this.uri = uri;
                this.accept = accept;
            }
    
            @Override
            public String getRequestURI() {
                return this.uri;
            }
            @Override
            public Enumeration<String> getHeaders(String name) {
                Enumeration<String> result;
                if ("accept".equalsIgnoreCase(name)) {
                    Vector<String> values = new Vector<String>(1);
                    values.add(this.accept);
                    result = values.elements();
                } else {
                    result =  super.getHeaders(name);       
                }
                return result;
            }
        }
    }
    

    CAAEWS。Java语言

    package com.extratechnology.caaews;
    
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    
    import com.extratechnology.caaews.model.Log;
    
    
    @Path("et")
    @Produces(value = {MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
    public class CAAEWS {
    
        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Log getJSON() {
            return new Log("JSON!");
        }
    
        @GET
        @Produces(MediaType.TEXT_XML)
        public Log getXML() {
            return new Log("XML!");
        }
    
    }
    

    日志Java语言

    package com.extratechnology.caaews.model;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Log {
        private String log;
    
        public Log(String log) {
            this.log = log;
        }
    
        public String getLog() {
            return log;
        }
    
        public void setLog(String log) {
            this.log = log;
        }
    
    }
    

    唯一让我稍感兴趣的是HTTP有两种XML内容类型。

    • 文本/xml
    • 应用程序/xml

    它可以在网络上配置。xml,但我必须调整注释。为什么是这两个?

    --

    脚注:

    在写了这篇文章之后,我现在发现我收到了HTTP 500错误。

    Documents\workspace-sts-3.8.3.RELEASE\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\logs
    

    我把它写进日志:

    0:0:0:0:0:0:0:1 - - [25/Nov/2017:16:56:00 +0000] "GET /caaews/webapi/et.xml HTTP/1.1" 500 1082
    

    有人知道如何获得更合理的日志信息吗?或者我需要做什么来捕捉更有意义的堆栈跟踪?


    似乎Log类需要一个无参数构造函数来克服这一问题。但我承认,@peeskillet答案远没有那么麻烦,并且使用了内置的Jersey功能。


    我还想知道javax。servlet。在查看示例后,过滤器无法很好地与JAX-RS 2.0配合使用 here ...


    根据这个问题的其他相关答案/评论,我最终实现了一个异常处理程序,因此您可以在Jersey中获得有关HTTP 500消息的更多信息。。

    下面的代码有助于指明登录的方式。java需要无参数构造函数。。

    错误消息

    package com.extratechnology.caaews.model;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class ErrorMessage {
        private String errorMessage;
        private String errorStackTrace;
        private String cause;
        private String causeStackTrace;
        private int    errorCode;
    
        public ErrorMessage() {
        }
    
        public ErrorMessage(
            String errorMessage, 
            String errorStackTrace, 
            String cause,
            String causeStackTrace,
            int errorCode
        ) {
            this.errorMessage = errorMessage;
            this.errorStackTrace = errorStackTrace;
            this.cause = cause;
            this.causeStackTrace = causeStackTrace;
            this.errorCode = errorCode;
        }
    
        public String getErrorMessage() {
            return errorMessage;
        }
    
        public void setErrorMessage(String errorMessage) {
            this.errorMessage = errorMessage;
        }
    
        public String getErrorStackTrace() {
            return errorStackTrace;
        }
    
        public void setErrorStackTrace(String errorStackTrace) {
            this.errorStackTrace = errorStackTrace;
        }
    
        public String getCause() {
            return cause;
        }
    
        public void setCause(String cause) {
            this.cause = cause;
        }
    
        public String getCauseStackTrace() {
            return causeStackTrace;
        }
    
        public void setCauseStackTrace(String causeStackTrace) {
            this.causeStackTrace = causeStackTrace;
        }
    
        public int getErrorCode() {
            return errorCode;
        }
    
        public void setErrorCode(int errorCode) {
            this.errorCode = errorCode;
        }
    
    }
    

    package com.extratechnology.caaews.exception;
    
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.Response.Status;
    import javax.ws.rs.ext.ExceptionMapper;
    import javax.ws.rs.ext.Provider;
    
    import com.extratechnology.caaews.model.ErrorMessage;
    
    @Provider
    public class GenericExceptionMapper implements ExceptionMapper<Throwable>{
    
        @Override
        public Response toResponse(Throwable ex) {
            System.out.println("Stack Trace:");
            ex.printStackTrace();
            System.out.println("Cause:");
            Throwable cause = ex.getCause();
            if (cause != null) {
                cause.printStackTrace();    
            }
            ErrorMessage message = new ErrorMessage(
                    ex.getMessage(),
                    GenericExceptionMapper.getStackTrack(ex),
                    cause.getMessage(),
                    GenericExceptionMapper.getStackTrack(cause),
                    Status.INTERNAL_SERVER_ERROR.getStatusCode()
                    );
            return Response
                    .status(Status.INTERNAL_SERVER_ERROR)
                    .entity(message)
                    .build();
        }
    
        private static String getStackTrack(Throwable ex) {
            StringBuilder sb = new StringBuilder();
            String ls = System.lineSeparator();
            if (ex != null) {
                StackTraceElement[] steAll = ex.getStackTrace();
                for (StackTraceElement ste : steAll) {
                    sb.append(ste.toString());
                    sb.append(ls);
                }   
            }
            return sb.toString();
        }
    }
    

    系统。出来println在调试时提供控制台消息,当出现错误时,您也会在web浏览器中获得负载。

    如:

    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <errorMessage>
    <cause>1 counts of IllegalAnnotationExceptions</cause>
    <causeStackTrace>
    com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source) com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source) com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source) com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source) com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source) com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source) sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) javax.xml.bind.ContextFinder.newInstance(Unknown Source) javax.xml.bind.ContextFinder.newInstance(Unknown Source) javax.xml.bind.ContextFinder.find(Unknown Source) javax.xml.bind.JAXBContext.newInstance(Unknown Source) javax.xml.bind.JAXBContext.newInstance(Unknown Source) org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getStoredJaxbContext(AbstractJaxbProvider.java:312) org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getJAXBContext(AbstractJaxbProvider.java:297) org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:264) org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:231) org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.writeTo(AbstractRootElementJaxbProvider.java:175) org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266) org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1135) org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662) org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:395) org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:385) org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:280) org.glassfish.jersey.internal.Errors$1.call(Errors.java:272) org.glassfish.jersey.internal.Errors$1.call(Errors.java:268) org.glassfish.jersey.internal.Errors.process(Errors.java:316) org.glassfish.jersey.internal.Errors.process(Errors.java:298) org.glassfish.jersey.internal.Errors.process(Errors.java:268) org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289) org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256) org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703) org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416) org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Unknown Source)
    </causeStackTrace>
    <errorCode>500</errorCode>
    <errorMessage>HTTP 500 Internal Server Error</errorMessage>
    <errorStackTrace>
    org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.writeTo(AbstractRootElementJaxbProvider.java:183) org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266) org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85) org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163) org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1135) org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662) org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:395) org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:385) org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:280) org.glassfish.jersey.internal.Errors$1.call(Errors.java:272) org.glassfish.jersey.internal.Errors$1.call(Errors.java:268) org.glassfish.jersey.internal.Errors.process(Errors.java:316) org.glassfish.jersey.internal.Errors.process(Errors.java:298) org.glassfish.jersey.internal.Errors.process(Errors.java:268) org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289) org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256) org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703) org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416) org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342) org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Unknown Source)
    </errorStackTrace>
    </errorMessage>