javascript
moxy json介绍_使用MOXy 2.5.1快速且有点脏的JSON模式生成
moxy json介紹
因此,這些天我正在為即將推出的Oracle云服務(wù)開(kāi)發(fā)新的REST API,因此我需要做的事情之一就是能夠?yàn)槟P椭械腷ean自動(dòng)生成JSON模式。 我正在使用MOXy從POJO生成JSON,從EclipseLink 2.5.1版本開(kāi)始,它現(xiàn)在具有從bean模型生成JSON模式的能力。
將來(lái)會(huì)有一個(gè)更加正式的解決方案集成到Jersey 2.x; 但是如果您想嘗試一下,此解決方案目前就可以使用。
因此,我們需要設(shè)置的第一類(lèi)是模型處理器,這是非常內(nèi)部的Jersey類(lèi),它允許我們使用額外的方法和資源來(lái)修改資源模型。 我們可以向模型中的每個(gè)資源添加JsonSchemaHandler ,以完成生成新模式的艱苦工作。 由于這是一個(gè)簡(jiǎn)單的POC,因此這里沒(méi)有緩存,如果要在生產(chǎn)代碼中使用它,請(qǐng)注意這一點(diǎn)。
import com.google.common.collect.Lists;import example.Bean;import java.io.IOException; import java.io.StringWriter;import java.text.SimpleDateFormat;import java.util.Date; import java.util.List;import javax.inject.Inject;import javax.ws.rs.HttpMethod; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.core.Configuration; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response;import javax.xml.bind.JAXBException; import javax.xml.bind.SchemaOutputResolver; import javax.xml.transform.Result; import javax.xml.transform.stream.StreamResult;import org.eclipse.persistence.jaxb.JAXBContext;import org.glassfish.jersey.process.Inflector; import org.glassfish.jersey.server.ExtendedUriInfo; import org.glassfish.jersey.server.model.ModelProcessor; import org.glassfish.jersey.server.model.ResourceMethod; import org.glassfish.jersey.server.model.ResourceModel; import org.glassfish.jersey.server.model.RuntimeResource; import org.glassfish.jersey.server.model.internal.ModelProcessorUtil; import org.glassfish.jersey.server.wadl.internal.WadlResource;public class JsonSchemaModelProcessor implements ModelProcessor {private static final MediaType JSON_SCHEMA_TYPE = MediaType.valueOf("application/schema+json");private final List<ModelProcessorUtil.Method> methodList;public JsonSchemaModelProcessor() {methodList = Lists.newArrayList();methodList.add(new ModelProcessorUtil.Method("$schema", HttpMethod.GET, MediaType.WILDCARD_TYPE, JSON_SCHEMA_TYPE,JsonSchemaHandler.class));}@Overridepublic ResourceModel processResourceModel(ResourceModel resourceModel, Configuration configuration) {return ModelProcessorUtil.enhanceResourceModel(resourceModel, true, methodList, true).build();}@Overridepublic ResourceModel processSubResource(ResourceModel resourceModel, Configuration configuration) {return ModelProcessorUtil.enhanceResourceModel(resourceModel, true, methodList, true).build();}public static class JsonSchemaHandler implements Inflector<ContainerRequestContext, Response> {private final String lastModified = new SimpleDateFormat(WadlResource.HTTPDATEFORMAT).format(new Date());@Injectprivate ExtendedUriInfo extendedUriInfo;@Overridepublic Response apply(ContainerRequestContext containerRequestContext) {// Find the resource that we are decorating, then work out the// return type on the first GETList<RuntimeResource> ms = extendedUriInfo.getMatchedRuntimeResources();List<ResourceMethod> rms = ms.get(1).getResourceMethods();Class responseType = null;found:for (ResourceMethod rm : rms) {if ("GET".equals(rm.getHttpMethod())) {responseType = (Class) rm.getInvocable().getResponseType();break found;}}if (responseType == null) {throw new WebApplicationException("Cannot resolve type for schema generation");}//try {JAXBContext context = (JAXBContext) JAXBContext.newInstance(responseType);StringWriter sw = new StringWriter();final StreamResult sr = new StreamResult(sw);context.generateJsonSchema(new SchemaOutputResolver() {@Overridepublic Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {return sr;}}, responseType);return Response.ok().type(JSON_SCHEMA_TYPE).header("Last-modified", lastModified).entity(sw.toString()).build();} catch (JAXBException jaxb) {throw new WebApplicationException(jaxb);}}}}請(qǐng)注意, JsonSchemaHandler代碼中的非常簡(jiǎn)單的啟發(fā)式方法假定每個(gè)資源都有1:1映射到單個(gè)JSON Schema元素。 當(dāng)然,這可能不適用于您的特定應(yīng)用程序。
現(xiàn)在,我們已經(jīng)在一個(gè)已知的位置生成了架構(gòu),我們需要將其告知客戶(hù),我們要做的第一件事是確保當(dāng)用戶(hù)在特定資源上調(diào)用OPTIONS時(shí),有一個(gè)合適的鏈接頭:
import java.io.IOException;import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Context; import javax.ws.rs.core.Link; import javax.ws.rs.core.UriInfo;public class JsonSchemaResponseFilter implements ContainerResponseFilter {@Contextprivate UriInfo uriInfo;@Overridepublic void filter(ContainerRequestContext containerRequestContext,ContainerResponseContext containerResponseContext) throws IOException {String method = containerRequestContext.getMethod();if ("OPTIONS".equals(method)) {Link schemaUriLink =Link.fromUriBuilder(uriInfo.getRequestUriBuilder().path("$schema")).rel("describedBy").build();containerResponseContext.getHeaders().add("Link", schemaUriLink);}} }由于這是JAX-RS 2.x,因此我們正在與之合作,將所有內(nèi)容捆綁為一個(gè)功能:
import javax.ws.rs.core.Feature; import javax.ws.rs.core.FeatureContext;public class JsonSchemaFeature implements Feature {@Overridepublic boolean configure(FeatureContext featureContext) {if (!featureContext.getConfiguration().isRegistered(JsonSchemaModelProcessor.class)) {featureContext.register(JsonSchemaModelProcessor.class);featureContext.register(JsonSchemaResponseFilter.class);return true;}return false;} }我不會(huì)展示我的整個(gè)POJO類(lèi)集。 但是很快,這就是模式生成代碼所需的帶有@GET方法的Resource類(lèi):
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType;@Path("/bean") public class BeanResource {@GET@Produces(MediaType.APPLICATION_JSON)public Bean getBean() {return new Bean();} }最后,如果對(duì)資源執(zhí)行GET,將看到以下內(nèi)容:
GET .../resources/bean Content-Type: application/json{"message" : "hello","other" : {"message" : "OtherBean"},"strings" : ["one","two","three","four"] }和選項(xiàng):
OPTIONS .../resources/bean Content-Type: text/plain Link: <http://.../resources/bean/$schema>; rel="describedBy"GET, OPTIONS, HEAD最后,如果您解析模式資源:
GET .../resources/bean/$schema Content-Type: application/schema+json{"$schema" : "http://json-schema.org/draft-04/schema#","title" : "example.Bean","type" : "object","properties" : {"message" : {"type" : "string"},"other" : {"$ref" : "#/definitions/OtherBean"},"strings" : {"type" : "array","items" : {"type" : "string"}}},"additionalProperties" : false,"definitions" : {"OtherBean" : {"type" : "object","properties" : {"message" : {"type" : "string"}},"additionalProperties" : false}} }這里有很多工作要做,特別是根據(jù)我不久前轉(zhuǎn)發(fā)到Jersey 2.xa的聲明性鏈接注釋生成超媒體擴(kuò)展。 但這確實(shí)指向解決方案,我們可以運(yùn)用各種解決方案使某些事情現(xiàn)在起作用。
翻譯自: https://www.javacodegeeks.com/2014/04/quick-and-a-bit-dirty-json-schema-generation-with-moxy-2-5-1.html
moxy json介紹
總結(jié)
以上是生活随笔為你收集整理的moxy json介绍_使用MOXy 2.5.1快速且有点脏的JSON模式生成的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 电脑监测流量的软件(电脑网络流量监控软件
- 下一篇: Java中的责任链设计模式