2016-04-17 4 views
10

मैं चाहूँगा अपने आवेदन सर्वर पर अनुरोध से JAX-आरएस 2 JSON पेलोड मुद्रित करने के लिए, वास्तविक क्रियान्वयन की परवाह किए बिना सक्षम होने के लिए।JAX-आरएस 2 प्रिंट JSON अनुरोध

मैं कोशिश की है सुझाव दिया इतने पर समाधान लेकिन सभी (जर्सी और इसी तरह) की तरह वास्तविक क्रियान्वयन से बाइनरी में शामिल हैं, और मैं सिर्फ अपने आवेदन में javaee-api v 7.0 उपयोग करने की अनुमति कर रहा हूँ।

मैं अपने क्लाइंट पर ClientRequestFilter और ClientResponseFilter को लागू करने की कोशिश की है, लेकिन वे धारावाहिक संस्थाओं शामिल नहीं है।

यहाँ ग्राहक का एक उदाहरण है:

WebTarget target = ClientBuilder.newClient().register(MyLoggingFilter.class).target("http://localhost:8080/loggingtest/resources/accounts"); 
Account acc = target.request().accept(MediaType.APPLICATION_JSON).get(account.Account.class); 

और यहाँ MyLoggingFilter के कार्यान्वयन है:

@Provider 
public class MyLoggingFilter implements ClientRequestFilter, ClientResponseFilter { 

    private static final Logger LOGGER = Logger.getLogger(MyLoggingFilter.class.getName()); 

    @Override 
    public void filter(ClientRequestContext requestContext) throws IOException { 

     LOGGER.log(Level.SEVERE, "Request method: {0}", requestContext.getMethod()); 

    } 

    @Override 
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { 
     LOGGER.log(Level.SEVERE, "Response status: {0}", responseContext.getStatus()); 
    }   
} 

उत्तर

15

तो नीचे दिए कुछ जब इस

  1. लागू करने के लिए समय ध्यान रखने

    अनुरोध इकाई के लिए, आप चाहते हैं कि सीरियलाइजेशन ढांचे द्वारा संभाला जाए, मतलब जैसे

    @Override 
    public void filter(ClientRequestContext requestContext) { 
        Object entity = requestContext.getEntity(); 
        String serialized = serializeEntity(entity); 
        log(serialized); 
    

    यहाँ आप यह अपने आप serializing कर रहे हैं, हो सकता है जैक्सन ObjectMapper या कुछ का उपयोग कर कुछ करने के लिए नहीं जी आप करते चाहते हैं। आप इसे इस तरह से कर सकते हैं, लेकिन यह उन प्रकारों में सीमित है जो इसे संभाल सकते हैं। यदि आप ऑब्जेक्ट को फ्रेमवर्क द्वारा पहले से ही संभालने के तरीके को क्रमबद्ध करने देते हैं, तो ढांचा सिर्फ JSON की तुलना में कई प्रकारों का समर्थन करने में सक्षम होगा।

    फ्रेमवर्क को क्रमबद्ध करने के लिए, और फिर भी धारावाहिक डेटा प्राप्त करने में सक्षम होने के लिए, हमें WriterInterceptor का उपयोग करने की आवश्यकता है। क्या हम करते हैं एक ByteArrayOutputStream को इकाई उत्पादन धारा सेट किया गया है सकते हैं और फिर ढांचे हमारेByteArrayOutputStream करने के लिए अनुरोध वस्तु को क्रमानुसार, तो समापन उन बाइट्स लॉग ऑन करते हैं। इस प्रकार जर्सी LoggingFilter इसे संभालता है।

  2. प्रतिक्रिया के लिए, हमारे फिल्टर में, हम प्रतिक्रिया स्ट्रीम से डेटा निकालने की जरूरत है, लेकिन भी हम यकीन है कि धारा अभी भी डेटा है, के रूप में यह अभी तक ग्राहक के लिए deserialized नहीं किया गया है बनाने की जरूरत है। यह mark() और reset() स्ट्रीम करने के लिए, मानते हुए कि अंकन समर्थित है। यदि नहीं, तो इसे BufferedOutputStream में लपेटें। फिर, इस प्रकार जर्सी LoggingFilter इसे संभालता है।

नीचे एक पूर्ण सरल कार्यान्वयन है। इसमें से अधिकांश सीधे जर्सी LoggingFilter से लिया जाता है, हालांकि यह केवल आपके उपयोग के मामले के लिए छीन लिया जाता है। जर्सी LoggingFilter केवल इकाई से अलग, कई अन्य जानकारी लॉग करता है। एक चीज जो मैंने छोड़ी वह चार्सेट की जांच है। मैंने जर्सी द्वारा उपयोग की गई MessageUtil कक्षा के रूप में एक कठोर कोडित यूटीएफ -8 का उपयोग किया, जर्सी विशिष्ट है। यदि आप फ़िल्टर को अन्य वर्णों के लिए अधिक सार्वभौमिक बनाना चाहते हैं, तो आप इसे ठीक करने में देखना चाहेंगे।

import java.io.BufferedInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.FilterOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.nio.charset.Charset; 
import java.nio.charset.StandardCharsets; 
import java.util.logging.Logger; 
import javax.annotation.Priority; 
import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.client.ClientRequestContext; 
import javax.ws.rs.client.ClientRequestFilter; 
import javax.ws.rs.client.ClientResponseContext; 
import javax.ws.rs.client.ClientResponseFilter; 
import javax.ws.rs.ext.WriterInterceptor; 
import javax.ws.rs.ext.WriterInterceptorContext; 

@Priority(Integer.MIN_VALUE) 
public class EntityLoggingFilter implements ClientRequestFilter, ClientResponseFilter, WriterInterceptor { 

    private static final Logger logger = Logger.getLogger(EntityLoggingFilter.class.getName()); 
    private static final String ENTITY_STREAM_PROPERTY = "EntityLoggingFilter.entityStream"; 
    private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; 
    private final int maxEntitySize = 1024 * 8; 

    private void log(StringBuilder sb) { 
     logger.info(sb.toString()); 
    } 

    private InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset) throws IOException { 
     if (!stream.markSupported()) { 
      stream = new BufferedInputStream(stream); 
     } 
     stream.mark(maxEntitySize + 1); 
     final byte[] entity = new byte[maxEntitySize + 1]; 
     final int entitySize = stream.read(entity); 
     b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset)); 
     if (entitySize > maxEntitySize) { 
      b.append("...more..."); 
     } 
     b.append('\n'); 
     stream.reset(); 
     return stream; 
    } 

    @Override 
    public void filter(ClientRequestContext requestContext) throws IOException { 
     if (requestContext.hasEntity()) { 
      final OutputStream stream = new LoggingStream(requestContext.getEntityStream()); 
      requestContext.setEntityStream(stream); 
      requestContext.setProperty(ENTITY_STREAM_PROPERTY, stream); 
     } 
    } 

    @Override 
    public void filter(ClientRequestContext requestContext, 
      ClientResponseContext responseContext) throws IOException { 
     final StringBuilder sb = new StringBuilder(); 
     if (responseContext.hasEntity()) { 
      responseContext.setEntityStream(logInboundEntity(sb, responseContext.getEntityStream(), 
        DEFAULT_CHARSET)); 
      log(sb); 
     } 

    } 

    @Override 
    public void aroundWriteTo(WriterInterceptorContext context) 
      throws IOException, WebApplicationException { 
     final LoggingStream stream = (LoggingStream) context.getProperty(ENTITY_STREAM_PROPERTY); 
     context.proceed(); 
     if (stream != null) { 
      log(stream.getStringBuilder(DEFAULT_CHARSET)); 
     } 
    } 

    private class LoggingStream extends FilterOutputStream { 

     private final StringBuilder sb = new StringBuilder(); 
     private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

     LoggingStream(OutputStream out) { 
      super(out); 
     } 

     StringBuilder getStringBuilder(Charset charset) { 
      // write entity to the builder 
      final byte[] entity = baos.toByteArray(); 

      sb.append(new String(entity, 0, entity.length, charset)); 
      if (entity.length > maxEntitySize) { 
       sb.append("...more..."); 
      } 
      sb.append('\n'); 

      return sb; 
     } 

     @Override 
     public void write(final int i) throws IOException { 
      if (baos.size() <= maxEntitySize) { 
       baos.write(i); 
      } 
      out.write(i); 
     } 
    } 
} 

भी देखें:

+0

महान काम करता है। मुझे सिर्फ @Provider के रूप में फ़िल्टर को एनोटेट करने और इसे अपने क्लाइंट पर पंजीकृत करने की आवश्यकता है और यह पोस्टेड इकाई से जेएसओएन लॉग करता है। बीटीडब्ल्यू, मैं इकाइयों को क्रमबद्ध करने के लिए जेएक्स-बी का उपयोग कर रहा हूं। आपके समय के लिए धन्यवाद ठीक है, मेरा अपवित्र और स्वीकृति है। – D00de

+0

डीबगिंग के लिए बढ़िया! –

संबंधित मुद्दे