返回值是内置类型 不能更改_选择通过更改内容类型返回的详细程度,第二部分...
返回值是內置類型 不能更改
在上一篇文章中 ,我們研究了如何使用MOXy的功能來控制特定實體的數據輸出級別。 這篇文章著眼于Jersey 2.x提供的抽象,它允許您定義一組自定義的批注以具有相同的效果。
與之前一樣,我們幾乎沒有什么瑣碎的資源可以返回Jersey會為我們轉換為JSON的對象,請注意,目前此代碼中沒有任何內容可以進行過濾–我不會將注釋傳遞給
Response對象,如Jersey示例中所示:
在我的設計中,我將定義四個注釋: NoView , SummaryView , NormalView和DetailedView 。 所有根對象都必須實現NoView注釋,以防止暴露未注釋的字段-您可能覺得設計中沒有必要。 所有這些類看起來都一樣,所以我只顯示一個。 請注意,創建AnnotationLiteral的工廠方法必須優先于創建動態代理以具有相同效果的工廠使用。 2.5中有代碼,將忽略由java.lang.reflect.Proxy對象實現的任何注釋,其中包括您可能從類中檢索到的所有注釋。 我正在為此提交修復程序。
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;import javax.enterprise.util.AnnotationLiteral;import org.glassfish.jersey.message.filtering.EntityFiltering;@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Documented @EntityFiltering public @interface NoView {/*** Factory class for creating instances of the annotation.*/public static class Factory extends AnnotationLiteral<NoView> implements NoView {private Factory() {}public static NoView get() {return new Factory();}}}現在,我們可以快速瀏覽一下Message Bean,這比我以前的示例稍微復雜一點,以非常簡單的形式顯示子圖的過濾。 正如我之前說過的那樣,在類的根部使用NoView注釋進行注釋–這應該意味著privateData永遠不會返回給客戶端,因為它沒有特別注釋。
import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement @NoView public class Message {private String privateData;@SummaryViewprivate String summary;@NormalViewprivate String message;@DetailedViewprivate String subtext;@DetailedViewprivate SubMessage submessage;public Message() {summary = "Some simple summary";message = "This is indeed the message";subtext = "This is the deep and meaningful subtext";submessage = new SubMessage();privateData = "The fox is flying tonight";}// Getters and setters not shown }public class SubMessage {private String message;public SubMessage() {message = "Some sub messages";}// Getters and setters not shown }如前所述,資源類中沒有用于處理過濾的代碼–我認為這是一個橫切關注點,因此我將其抽象為WriterInterceptor。 請注意,如果使用的實體沒有NoView批注,則會拋出該異常。
import java.io.IOException;import java.lang.annotation.Annotation;import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set;import javax.ws.rs.ServerErrorException; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.WriterInterceptor; import javax.ws.rs.ext.WriterInterceptorContext;@Provider public class ViewWriteInterceptor implements WriterInterceptor {private HttpHeaders httpHeaders;public ViewWriteInterceptor(@Context HttpHeaders httpHeaders) {this.httpHeaders = httpHeaders;}@Overridepublic void aroundWriteTo(WriterInterceptorContext writerInterceptorContext) throws IOException,WebApplicationException {// I assume this case will never happen, just to be sureif (writerInterceptorContext.getEntity() == null) {writerInterceptorContext.proceed();return;}else{Class<?> entityType = writerInterceptorContext.getEntity().getClass();String entityTypeString = entityType.getName();// Ignore any Jersey system classes, for example wadl//if (entityType == String.class || entityType.isArray() || entityTypeString.startsWith("com.sun") || entityTypeString.startsWith("org.glassfish")) {writerInterceptorContext.proceed();return;}// Fail if the class doesn't have the default NoView annotation // this prevents any unannotated fields from showing up//else if (!entityType.isAnnotationPresent(NoView.class)) {throw new ServerErrorException("Entity type should be tagged with @NoView annotation " + entityType, Response.Status.INTERNAL_SERVER_ERROR);}}// Get hold of the return media type://MediaType mt = writerInterceptorContext.getMediaType();String level = mt.getParameters().get("level");// Get the annotations and modify as required//Set<Annotation> current = new LinkedHashSet<>();current.addAll(Arrays.asList(writerInterceptorContext.getAnnotations()));switch (level != null ? level : "") {default:case "detailed":current.add(com.example.annotation.DetailedView.Factory.get());case "normal":current.add(com.example.annotation.NormalView.Factory.get());case "summary":current.add(com.example.annotation.SummaryView.Factory.get());}writerInterceptorContext.setAnnotations(current.toArray(new Annotation[current.size()]));//writerInterceptorContext.proceed();} }最后,您必須手動啟用EntityFilterFeature,為此,您可以在Application類中簡單地注冊它
import java.lang.annotation.Annotation;import javax.ws.rs.ApplicationPath;import org.glassfish.jersey.message.filtering.EntityFilteringFeature; import org.glassfish.jersey.server.ResourceConfig;@ApplicationPath("/resources/") public class SelectableApplication extends ResourceConfig {public SelectableApplication() {packages("...");// Set entity-filtering scope via configuration.property(EntityFilteringFeature.ENTITY_FILTERING_SCOPE, new Annotation[] {NormalView.Factory.get(), DetailedView.Factory.get(), NoView.Factory.get(), SummaryView.Factory.get()});register(EntityFilteringFeature.class);}}一旦一切就緒并運行,應用程序將像以前一樣響應:
GET .../hello Accept application/json; level=detailed or application/json {"message" : "This is indeed the message","submessage" : {"message" : "Some sub messages"},"subtext" : "This is the deep and meaningful subtext","summary" : "Some simple summary" }GET .../hello Accept application/json; level=normal {"message" : "This is indeed the message","summary" : "Some simple summary" }GET .../hello Accept application/json; level=summary {"summary" : "Some simple summary" } 這是直接使用MOXy注釋的更好選擇–使用自定義注釋應該更容易將應用程序移植到過度實現中,即使您必須提供自己的過濾器也是如此。 最后,值得探討的是Jersey擴展,它允許基于角色的篩選 ,我認為這在安全方面很有用。
翻譯自: https://www.javacodegeeks.com/2014/02/selecting-level-of-detail-returned-by-varying-the-content-type-part-ii.html
返回值是內置類型 不能更改
總結
以上是生活随笔為你收集整理的返回值是内置类型 不能更改_选择通过更改内容类型返回的详细程度,第二部分...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奇富科技联合信通院发布国内首个金融行业大
- 下一篇: 青叔音是什么意思 什么是青叔音