Json Can';不要让GlassFish在JAX-RS中使用我的MessageBodyWriter
我需要在GlassFish 4.0中定制JAX-RS的JSON输出。定制MessageBodyWriter似乎很适合。我的问题是,我无法制作任何示例,例如,由服务器调用。我只是设置断点,看看它是否被击中。我知道它在正确的软件包中,等等,因为我也尝试了自定义WriterInterceptor,而且这个很好。我只需要将@Provider放在正确的包中的WriterInterceptor上,就这样 到目前为止我已经尝试过的事情:Json Can';不要让GlassFish在JAX-RS中使用我的MessageBodyWriter,json,rest,glassfish,jax-rs,jersey-2.0,Json,Rest,Glassfish,Jax Rs,Jersey 2.0,我需要在GlassFish 4.0中定制JAX-RS的JSON输出。定制MessageBodyWriter似乎很适合。我的问题是,我无法制作任何示例,例如,由服务器调用。我只是设置断点,看看它是否被击中。我知道它在正确的软件包中,等等,因为我也尝试了自定义WriterInterceptor,而且这个很好。我只需要将@Provider放在正确的包中的WriterInterceptor上,就这样 到目前为止我已经尝试过的事情: 只需使用@Provider 修改web.xml并使用自定义应用程序注册自
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class WebVisualizationJsonWriter extends MOXyJsonProvider {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return WebVisualizationJsonPayload.class == type
|| WebVisualizationJsonPayload.class == getDomainClass(genericType);
}
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isReadable(type, genericType, annotations, mediaType);
}
@Override
protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, Unmarshaller unmarshaller) throws JAXBException {
unmarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
}
@Override
protected void preWriteTo(Object object, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, Marshaller marshaller)
throws JAXBException {
marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "$");
}
}
@Provider
@产生(MediaType.APPLICATION_JSON)
@使用(MediaType.APPLICATION_JSON)
公共类WebVisualizationJsonWriter扩展了MOXyJsonProvider{
@凌驾
公共布尔值可读取(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回WebVisualizationJsonPayload.class==类型
||WebVisualizationJsonPayload.class==getDomainClass(genericType);
}
@凌驾
公共布尔值可写(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回isReadable(类型、genericType、注释、mediaType);
}
@凌驾
受保护的void preReadFrom(类类型、类型genericType、批注[]批注、MediaType MediaType、,
多值Map httpHeaders、解组器(解组器)抛出JAXBEException{
unmarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER,“$”;
}
@凌驾
受保护的void预写(对象对象、类类型、类型genericType、注释[]注释、,
MediaType MediaType、多值Map httpHeaders、封送器(封送器)
抛出异常{
setProperty(MarshallerProperties.JSON_VALUE_WRAPPER,“$”;
}
}
在RESTful服务调用期间,上面的任何方法都不会被命中。要解决此问题,必须禁用MOXy,然后启用CustomMoxyJsonProvider 例如:
@Provider
public class CustomMoxyFeature implements Feature {
@Override
public boolean configure(final FeatureContext context) {
final String disableMoxy = CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' + context.getConfiguration().getRuntimeType().name().toLowerCase();
context.property(disableMoxy, true);
return true;
}
}
@Provider
public class CustomMoxyJsonProvider extends MOXyJsonProvider {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return WebVisualizationJsonPayload.class == type
|| WebVisualizationJsonPayload.class == getDomainClass(genericType);
}
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isReadable(type, genericType, annotations, mediaType);
@Provider
公共类CustomMoxyJsonProvider扩展了MOXyJsonProvider{
@凌驾
公共布尔值可读取(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回WebVisualizationJsonPayload.class==类型
||WebVisualizationJsonPayload.class==getDomainClass(genericType);
}
@凌驾
公共布尔值可写(类类型、类型genericType、注释[]注释、MediaType MediaType){
返回isReadable(类型、genericType、注释、mediaType);
}
@覆盖
受保护的void preReadFrom(类类型、类型genericType、批注[]批注、MediaType MediaType、,
多值Map httpHeaders、解组器(解组器)抛出JAXBEException{
unmarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER,“$”;
}
@凌驾
受保护的void预写(对象对象、类类型、类型genericType、注释[]注释、,
MediaType MediaType、多值Map httpHeaders、封送器(封送器)
抛出异常{
setProperty(MarshallerProperties.JSON_VALUE_WRAPPER,“$”;
}
}
@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
addRestResourceClasses(resources);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.vinichenkosa.moxyproblem.TestResource.class);
resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyFeature.class);
resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyJsonProvider.class);
}
}
@javax.ws.rs.ApplicationPath(“webresources”)
公共类应用程序配置扩展应用程序{
@凌驾
public Set>resources=new java.util.HashSet();
添加资源类(资源);
归还资源;
}
private void addrestresourcelasses(Set自从升级到Glassfish 4.1以来,我也面临同样的问题。我们还升级了jersey和jax rs依赖项(如下所列)。下面是我们的自定义MessageBodyWriter,在写入流响应之前不会被调用
@Provider
@Produces({"application/xml", "application/vnd.jenzabar.jx-json"})
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<Object> {
// TODO pattern is probably too simple now, was "/paged/(^[/?]+)"
// and didn't work with expected URL, example "/DonationGroup/findAllGroupOriginTypes/paged/0,50"
private static final Pattern pathPattern = Pattern.compile("/paged/(.*)");
private static final Map<Class<?>, Class<?>[]> classMap;
private static final ReadWriteLock classMapLock;
static {
classMap = new HashMap<Class<?>, Class<?>[]>();
classMapLock = new ReentrantReadWriteLock();
}
/*
* Instance fields.
*/
@Context
private volatile ServletContext servletContext;
@Context
private volatile HttpServletRequest request;
@Context
volatile Providers providers;
@Context
private volatile UriInfo uriInfo;
protected volatile Logger logger;
/*
* Constructors.
*/
public RestDataSourceMessageBodyWriter() {
super();
this.logger = this.createLogger();
if (this.logger == null) {
this.logger = this.defaultCreateLogger();
}
assert this.logger != null;
if (this.logger.isLoggable(Level.FINER)) {
this.logger.log(Level.FINER, "created", this);
}
}
/*
* Instance methods.
*/
protected Logger createLogger() {
return this.defaultCreateLogger();
}
private final Logger defaultCreateLogger() {
Class<?> c = this.getClass();
assert c != null;
final String className = c.getName();
String bundleName = null;
Logger logger = Logger.getLogger(className);
assert logger != null;
if (logger.isLoggable(Level.FINER)) {
logger.entering(className, "defaultCreateLogger");
}
while (c != null && bundleName == null) {
bundleName = String.format("%sLogMessages", c.getName());
if (logger.isLoggable(Level.FINEST)) {
logger.logp(Level.FINEST, className, "defaultCreateLogger", "Looking for a ResourceBundle with the following bundle name: {0}", bundleName);
}
ResourceBundle rb = null;
try {
rb = ResourceBundle.getBundle(bundleName);
} catch (final MissingResourceException noBundle) {
if (logger.isLoggable(Level.FINEST)) {
logger.logp(Level.FINEST, className, "defaultCreateLogger", "No ResourceBundle found for name " + bundleName, noBundle);
}
bundleName = null;
rb = null;
}
c = c.getSuperclass();
}
if (bundleName != null) {
logger = Logger.getLogger(className, bundleName);
assert logger != null;
if (logger.isLoggable(Level.CONFIG)) {
logger.logp(Level.CONFIG, className, "defaultCreateLogger", "usingBundleName", bundleName);
}
}
if (logger.isLoggable(Level.FINER)) {
logger.exiting(className, "defaultCreateLogger", logger);
}
return logger;
}
@Override
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
if (this.logger.isLoggable(Level.FINER)) {
this.logger.entering(this.getClass().getName(), "isWriteable", new Object[] { type, genericType, annotations, mediaType });
}
boolean returnValue = false;
if (type != null && !RestDataSourceResponse.class.isAssignableFrom(type)) {
if (annotations != null && annotations.length > 0) {
for (final Annotation a : annotations) {
if (a instanceof Decorate) {
final DecorationType decorationType = ((Decorate)a).value();
if (decorationType != null && decorationType.equals(DecorationType.NONE)) {
if (this.logger.isLoggable(Level.FINER)) {
this.logger.exiting(this.getClass().getName(), "isWriteable", Boolean.FALSE);
}
return false;
}
}
}
}
MediaType modifiedMediaType = null;
if (mediaType.toString().equals("application/vnd.jenzabar.jx-json")) {
modifiedMediaType = MediaType.APPLICATION_JSON_TYPE;
} else {
modifiedMediaType = mediaType;
}
final MessageBodyWriter<RestDataSourceResponse> delegate = this.providers.getMessageBodyWriter(RestDataSourceResponse.class, RestDataSourceResponse.class, annotations, modifiedMediaType);
if (this.logger.isLoggable(Level.FINE)) {
this.logger.logp(Level.FINE, this.getClass().getName(), "isWriteable", "usingDelegate", delegate);
}
returnValue = delegate != null && delegate.isWriteable(RestDataSourceResponse.class, RestDataSourceResponse.class, annotations, modifiedMediaType);
}
if (this.logger.isLoggable(Level.FINER)) {
this.logger.exiting(this.getClass().getName(), "isWriteable", Boolean.valueOf(returnValue));
}
return returnValue;
}
@Provider
@产生({“application/xml”、“application/vnd.jenzabar.jxjson”})
公共类RestDataSourceMessageBodyWriter实现MessageBodyWriter{
//TODO模式现在可能太简单了,是“/paged/(^[/?]+)”
//并且无法使用预期的URL,例如“/DonationGroup/findAllGroupOriginTypes/paged/0,50”
私有静态最终模式pathPattern=Pattern.compile(“/paged/(*)”;
私有静态最终映射[]>classMap;
私有静态最终读写锁类映射锁;
静止的{
classMap=newhashmap[]>();
classMapLock=new ReentrantReadWriteLock();
}
/*
*实例字段。
*/
@上下文
私有易失性ServletContext;
@上下文
私有易失性HttpServletRequest;
@上下文
不稳定的供应商;
@上下文
私有易失性UriInfo-UriInfo;
受保护的易失性记录器;
/*
*构造器。
*/
公共RestDataSourceMessageBodyWriter(){
超级();
this.logger=this.createLogger();
if(this.logger==null){
this.logger=this.defaultCreateLogger();
}
断言this.logger!=null;
if(this.logger.isLoggable(Level.FINER)){
this.logger.log(Level.FINER,“已创建”,this);
}
}
/*
*实例方法。
*/
受保护的记录器createLogger(){
返回这个.defaultCreateLogger();
}
专用最终记录器defaultCreateLogger(){
c类=this.getClass();
断言c!=null;
最后一个字符串className=c.getName();
字符串bundleName=null;
Logger=Logger.getLogger(类名);
断言记录器!=null;
if(记录器isLoggable(级别更精细)){
输入(类名,“defaultCreateLogger”);
}
而(c!=null&&bundleName==null){
bundleName=String.format(“%sLogMessages”,c.getName());
if(记录器isLoggable(最高级)){
@Provider
@Produces({"application/xml", "application/vnd.jenzabar.jx-json"})
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<Object> {
// TODO pattern is probably too simple now, was "/paged/(^[/?]+)"
// and didn't work with expected URL, example "/DonationGroup/findAllGroupOriginTypes/paged/0,50"
private static final Pattern pathPattern = Pattern.compile("/paged/(.*)");
private static final Map<Class<?>, Class<?>[]> classMap;
private static final ReadWriteLock classMapLock;
static {
classMap = new HashMap<Class<?>, Class<?>[]>();
classMapLock = new ReentrantReadWriteLock();
}
/*
* Instance fields.
*/
@Context
private volatile ServletContext servletContext;
@Context
private volatile HttpServletRequest request;
@Context
volatile Providers providers;
@Context
private volatile UriInfo uriInfo;
protected volatile Logger logger;
/*
* Constructors.
*/
public RestDataSourceMessageBodyWriter() {
super();
this.logger = this.createLogger();
if (this.logger == null) {
this.logger = this.defaultCreateLogger();
}
assert this.logger != null;
if (this.logger.isLoggable(Level.FINER)) {
this.logger.log(Level.FINER, "created", this);
}
}
/*
* Instance methods.
*/
protected Logger createLogger() {
return this.defaultCreateLogger();
}
private final Logger defaultCreateLogger() {
Class<?> c = this.getClass();
assert c != null;
final String className = c.getName();
String bundleName = null;
Logger logger = Logger.getLogger(className);
assert logger != null;
if (logger.isLoggable(Level.FINER)) {
logger.entering(className, "defaultCreateLogger");
}
while (c != null && bundleName == null) {
bundleName = String.format("%sLogMessages", c.getName());
if (logger.isLoggable(Level.FINEST)) {
logger.logp(Level.FINEST, className, "defaultCreateLogger", "Looking for a ResourceBundle with the following bundle name: {0}", bundleName);
}
ResourceBundle rb = null;
try {
rb = ResourceBundle.getBundle(bundleName);
} catch (final MissingResourceException noBundle) {
if (logger.isLoggable(Level.FINEST)) {
logger.logp(Level.FINEST, className, "defaultCreateLogger", "No ResourceBundle found for name " + bundleName, noBundle);
}
bundleName = null;
rb = null;
}
c = c.getSuperclass();
}
if (bundleName != null) {
logger = Logger.getLogger(className, bundleName);
assert logger != null;
if (logger.isLoggable(Level.CONFIG)) {
logger.logp(Level.CONFIG, className, "defaultCreateLogger", "usingBundleName", bundleName);
}
}
if (logger.isLoggable(Level.FINER)) {
logger.exiting(className, "defaultCreateLogger", logger);
}
return logger;
}
@Override
public boolean isWriteable(final Class<?> type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) {
if (this.logger.isLoggable(Level.FINER)) {
this.logger.entering(this.getClass().getName(), "isWriteable", new Object[] { type, genericType, annotations, mediaType });
}
boolean returnValue = false;
if (type != null && !RestDataSourceResponse.class.isAssignableFrom(type)) {
if (annotations != null && annotations.length > 0) {
for (final Annotation a : annotations) {
if (a instanceof Decorate) {
final DecorationType decorationType = ((Decorate)a).value();
if (decorationType != null && decorationType.equals(DecorationType.NONE)) {
if (this.logger.isLoggable(Level.FINER)) {
this.logger.exiting(this.getClass().getName(), "isWriteable", Boolean.FALSE);
}
return false;
}
}
}
}
MediaType modifiedMediaType = null;
if (mediaType.toString().equals("application/vnd.jenzabar.jx-json")) {
modifiedMediaType = MediaType.APPLICATION_JSON_TYPE;
} else {
modifiedMediaType = mediaType;
}
final MessageBodyWriter<RestDataSourceResponse> delegate = this.providers.getMessageBodyWriter(RestDataSourceResponse.class, RestDataSourceResponse.class, annotations, modifiedMediaType);
if (this.logger.isLoggable(Level.FINE)) {
this.logger.logp(Level.FINE, this.getClass().getName(), "isWriteable", "usingDelegate", delegate);
}
returnValue = delegate != null && delegate.isWriteable(RestDataSourceResponse.class, RestDataSourceResponse.class, annotations, modifiedMediaType);
}
if (this.logger.isLoggable(Level.FINER)) {
this.logger.exiting(this.getClass().getName(), "isWriteable", Boolean.valueOf(returnValue));
}
return returnValue;
}