input发送a.jax_JAX-RS 2.0中的透明PATCH支持
input發送a.jax
PATCH方法是最不受歡迎的HTTP方法之一,因為直到最近才真正沒有一種標準的PATCH格式。 一段時間以來,它已經針對JSON進行了標準化,因此有很多庫可以為您完成繁重的工作。 出于本博客的目的,我將使用json-patch,盡管可以很容易地將此??特定實現適應您選擇的補丁庫。
每個法線可以讓資源和Bean類不受干擾。 在此示例代碼中,我們有一個簡單的資源,它知道如何返回原始對象,并且該資源允許您執行PATCH方法。 請注意,patch方法僅接受bean對象,這是因為我們需要做一些魔術才能預處理補丁。
import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType;@Path("service") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class Service {@GETpublic Bean get() {return new Bean(true);}@PATCH@Consumes("application/json-patch+json")public Bean patch(Bean input) {System.out.println(input.getMessage() + " " + input.getTitle());return input;}}import java.util.ArrayList; import java.util.List;public class Bean {private String title = "title";private String message = "message";private List<String> list = new ArrayList<String>();public Bean() {this(false);}public Bean(boolean init) {if (init) {title = "title";message = "message";list.add("one");list.add("two");}}public void setList(List list) {this.list = list;}public List getList() {return list;}public void setTitle(String title) {this.title = title;}public String getTitle() {return title;}public void setMessage(String message) {this.message = message;}public String getMessage() {return message;}}因此,對于這個示例,我們必須創建@PATCH注釋,幸運的是,JAX-RS為此目的包含了一個擴展元注釋。 我們還將使用@NameBinding因為此示例使用的是JAX-RS 2.0,因此我們可以@NameBinding連接過濾器。
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.ws.rs.HttpMethod; import javax.ws.rs.NameBinding;@Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @HttpMethod("PATCH") @Documented @NameBinding public @interface PATCH { }因此,這里是ReaderInterceptor的實現,該實現將處理傳入的流并將其替換為修補版本。 請注意,還使用@PATCH對該類進行了注釋,以使@NamedBinding魔術起作用,并且還缺少許多錯誤處理,因為這是一個簡單的POC。
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper;import com.github.fge.jsonpatch.JsonPatch; import com.github.fge.jsonpatch.JsonPatchException;import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException;import java.lang.annotation.Annotation; import java.lang.reflect.Method;import javax.ws.rs.GET; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.ReaderInterceptor; import javax.ws.rs.ext.ReaderInterceptorContext;import org.glassfish.jersey.message.MessageBodyWorkers;@Provider @PATCH public class PatchReader implements ReaderInterceptor {private UriInfo info;private MessageBodyWorkers workers;@Contextpublic void setInfo(UriInfo info) {this.info = info;}@Contextpublic void setWorkers(MessageBodyWorkers workers) {this.workers = workers;}@Overridepublic Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException,WebApplicationException {// Get the resource we are being called on, // and find the GET methodObject resource = info.getMatchedResources().get(0);Method found = null;for (Method next : resource.getClass().getMethods()) {if (next.getAnnotation(GET.class) != null) {found = next;break;}}if (found != null) {// Invoke the get method to get the state we are trying to patch//Object bean;try {bean = found.invoke(resource);} catch (Exception e) {throw new WebApplicationException(e);}// Convert this object to a an aray of bytes ByteArrayOutputStream baos = new ByteArrayOutputStream();MessageBodyWriter<? super Object> bodyWriter =workers.getMessageBodyWriter(Object.class, bean.getClass(), new Annotation[0], MediaType.APPLICATION_JSON_TYPE);bodyWriter.writeTo(bean, bean.getClass(), bean.getClass(), new Annotation[0], MediaType.APPLICATION_JSON_TYPE,new MultivaluedHashMap<String, Object>(), baos);// Use the Jackson 2.x classes to convert both the incoming patch // and the current state of the object into a JsonNode / JsonPatchObjectMapper mapper = new ObjectMapper();JsonNode serverState = mapper.readValue(baos.toByteArray(), JsonNode.class);JsonNode patchAsNode = mapper.readValue(readerInterceptorContext.getInputStream(), JsonNode.class);JsonPatch patch = JsonPatch.fromJson(patchAsNode);try {// Apply the patchJsonNode result = patch.apply(serverState);// Stream the result & modify the stream on the readerInterceptorByteArrayOutputStream resultAsByteArray = new ByteArrayOutputStream();mapper.writeValue(resultAsByteArray, result);readerInterceptorContext.setInputStream(new ByteArrayInputStream(resultAsByteArray.toByteArray()));// Pass control back to the Jersey codereturn readerInterceptorContext.proceed();} catch (JsonPatchException e) {throw new WebApplicationException(Response.status(500).type("text/plain").entity(e.getMessage()).build());}} else {throw new IllegalArgumentException("No matching GET method on resource");}} }因此,一旦部署了此功能,就可以開始處理數據,因此原始消息是:
{"list" : ["one","two"],"message" : "message","title" : "title" }因此,如果應用以下修補程序,則返回的結果是:
[{"op" : "replace","path" : "/message","value" : "otherMessage"},{"op" : "add","path" : "/list/-","value" : "three"} ]{"list" : ["one","two","three"],"message" : "otherMessage","title" : "title" }此示例說明,遵循簡單的編碼模式并使用簡單的注釋,將PATCH支持添加到您的類中相對比較簡單。 這樣,由于實現可以僅委托給您現有的PUT方法,因此PATCH支持變得微不足道。
更新: Jersey團隊的Mirsolav Fuksa提醒我,為了使此實現符合PATCH RFC,它應在客戶端執行OPTIONS請求時提供Accept-Patch標頭。 您可以使用簡單的CotnainerResponseFilter來做到這一點:
import java.io.IOException;import java.util.Collections;import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.Provider;@Provider public class OptionsAcceptHeader implements ContainerResponseFilter {@Overridepublic void filter(ContainerRequestContext requestContext,ContainerResponseContext responseContext) throws IOException {if ("OPTIONS".equals(requestContext.getMethod())) {if (responseContext.getHeaderString("Accept-Patch")==null) {responseContext.getHeaders().put("Accept-Patch", Collections.<Object>singletonList("application/json-patch+json")); }}} } 參考:來自Gerard Davison博客博客的JCG合作伙伴 Gerard Davison 對JAX-RS 2.0的透明PATCH支持 。翻譯自: https://www.javacodegeeks.com/2014/02/transparent-patch-support-in-jax-rs-2-0.html
input發送a.jax
總結
以上是生活随笔為你收集整理的input发送a.jax_JAX-RS 2.0中的透明PATCH支持的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 11:JOIN表,获取Java
- 下一篇: 荣耀新品发布会直播平台汇总 荣耀V Pu