Java JAX-RS(Jersey 2实现)使用URL扩展名.xml或.json进行内容协商
我看到了一个JavaRESTfulWebService,它允许在URL中请求内容类型,并在末尾添加一个扩展名,例如Java JAX-RS(Jersey 2实现)使用URL扩展名.xml或.json进行内容协商,java,rest,jax-rs,jersey-2.0,content-type,jersey,Java,Rest,Jax Rs,Jersey 2.0,Content Type,Jersey,我看到了一个JavaRESTfulWebService,它允许在URL中请求内容类型,并在末尾添加一个扩展名,例如 .xml .json 这是我在自己的Web服务中努力实现的内容协商风格 我知道,@产生了注释,而且一个方法可以通过添加一个Accept头,比如说使用Chrome扩展名Postman,用(value={})语法解析多个类型 但我不知道如何有效地从一个方法中提取信息,然后委托给另一个方法 我假设正则表达式可以与@Path和@PathParam一起使用,但我的尝试还没有成功 有人能举
.xml
.json
@产生了
注释,而且一个方法可以通过添加一个Accept头,比如说使用Chrome扩展名Postman,用(value={})
语法解析多个类型
但我不知道如何有效地从一个方法中提取信息,然后委托给另一个方法
我假设正则表达式可以与@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!");
}
}
通过使用以下方法创建Maven项目(类似,但更为最新),可以从Spring工具套件/Eclipse设置该项目:
- org.glassfish.jersey.archetypes
- jersey.quickstart.webapp
- 2.26
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
收益率:
{"log":"JSON!"}
HTTP Status 404 - Not Found
或
收益率:
{"log":"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使用以下语法:
在路径中需要一个“/”不是我想要的,所以我想我可能必须解决servlet过滤器而不是@PathParam方法。您是否尝试过在类级别去掉
@path
注释?然后,您的方法级注释将是:
@Path("et.{format}")
我认为您当前的实现正在创建一个子资源,它与以下路径匹配:
/et/{format}
您的JAX-RS代码有几个问题:
@Path中的正则表达式
@Path
注释的语法仅在参数模板内部和:
字符之后解析正则表达式。您试图在参数模板
“\\.{format}”之外使用正则表达式,因此它不会将其解析为正则表达式
路径分辨率
一个方法的路径包括类路径的段和它自己的路径段。当您试图调用/et.{format}
时,您的代码建议路径/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");
}
}
您的有效请求现在将是:
- (JSON通过
)getJSON
- (XML通过
)getXML
- (XML通过
)getLog
- (JSON通过
)getLog
“otherPath”
,因为它不能与空路径JSON方法冲突。我不推荐这个公约
注意事项:
- 在
语句中使用开关
中断
- 为了减少出现错误的机会,可以像我对自定义格式类型所做的那样,对可重用字符串使用常量等。一个
会更好enum
/et/{format}
。如果我们扩展path参数的范围以包括整个段{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;
}
regex[a-zA-Z0-9.]*
表示任何字母数字或下划线一次或多次。你可以用你想要的任何限制来替换那部分。请参考URL规范以获取允许的字符。当我在Google上搜索“servlet filter with jax rs example”时,它位于列表的顶部。粗略地看一下代码,我认为这符合我的需要
这是我的解决方案(到目前为止……见脚注警告) web.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>
Log.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;
}
}
}
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!");
}
}
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;
}
}
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();
}
}
唯一让我稍感兴趣的是HTTP有两种XML内容类型
- 文本/xml
- 应用程序/xml
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的答案要简单得多,并且使用内置的功能
在看了一些示例之后,我还想知道javax.servlet.filters是否不能很好地与JAX-RS2.0配合使用
根据这个问题的其他相关答案/评论,我最终实现了一个异常处理程序,因此您可以在Jersey获得有关HTTP 500消息的更多信息 下面的代码有助于指出需要无参数构造函数的Log.java的方法 错误消息a
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>
txt : text/plain, xml : application/xml
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);
<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>