You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/03/04 14:53:46 UTC

svn commit: r750010 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/ systests/src/test/java/org/apache/cxf/systest/jaxrs/

Author: sergeyb
Date: Wed Mar  4 13:53:46 2009
New Revision: 750010

URL: http://svn.apache.org/viewvc?rev=750010&view=rev
Log:
JAXRS: handling early exceptions which might be thrown by MessageBodyWriters

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=750010&r1=750009&r2=750010&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java Wed Mar  4 13:53:46 2009
@@ -73,7 +73,6 @@
 
     }
     
-    @SuppressWarnings("unchecked")
     private void processResponse(Message message, String baseAddress) {
         
         MessageContentsList objs = MessageContentsList.getContentsList(message);
@@ -91,90 +90,120 @@
             }
             
             Exchange exchange = message.getExchange();
-            OperationResourceInfo operation = (OperationResourceInfo)exchange.get(OperationResourceInfo.class
+            OperationResourceInfo ori = (OperationResourceInfo)exchange.get(OperationResourceInfo.class
                 .getName());
 
             List<ProviderInfo<ResponseHandler>> handlers = 
                 ProviderFactory.getInstance(baseAddress).getResponseHandlers();
             for (ProviderInfo<ResponseHandler> rh : handlers) {
-                Response r = rh.getProvider().handleResponse(message, operation, response);
+                Response r = rh.getProvider().handleResponse(message, ori, response);
                 if (r != null) {
                     response = r;
                 }
             }
             
-            message.put(Message.RESPONSE_CODE, response.getStatus());
-            message.put(Message.PROTOCOL_HEADERS, response.getMetadata());
-                            
-            responseObj = response.getEntity();
-            if (responseObj == null) {
-                return;
-            }
+            serializeMessage(message, response, ori, baseAddress, true);        
             
-            Class targetType = responseObj.getClass();
-            List<MediaType> availableContentTypes = 
-                computeAvailableContentTypes(message, response);  
-            
-            Method invoked = operation == null ? null : operation.getMethodToInvoke();
-            
-            MessageBodyWriter writer = null;
-            MediaType responseType = null;
-            for (MediaType type : availableContentTypes) { 
-                writer = ProviderFactory.getInstance(baseAddress)
-                    .createMessageBodyWriter(targetType, 
-                          invoked != null ? invoked.getGenericReturnType() : null, 
-                          invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
-                          type,
-                          exchange.getInMessage());
-                
-                if (writer != null) {
-                    responseType = type;
-                    break;
-                }
-            }
+        } else {
+            message.put(Message.RESPONSE_CODE, 204);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void serializeMessage(Message message, 
+                                  Response response, 
+                                  OperationResourceInfo ori,
+                                  String baseAddress,
+                                  boolean firstTry) {
+        message.put(Message.RESPONSE_CODE, response.getStatus());
+        message.put(Message.PROTOCOL_HEADERS, response.getMetadata());
+                        
+        Object responseObj = response.getEntity();
+        if (responseObj == null) {
+            return;
+        }
+        
+        Class targetType = responseObj.getClass();
+        List<MediaType> availableContentTypes = 
+            computeAvailableContentTypes(message, response);  
+        
+        Method invoked = ori == null ? null : ori.getMethodToInvoke();
         
-            OutputStream out = message.getContent(OutputStream.class);
-            if (writer == null) {
-                message.put(Message.RESPONSE_CODE, 500);
-                writeResponseErrorMessage(out, 
-                      "NO_MSG_WRITER",
-                      invoked != null ? invoked.getReturnType().getSimpleName() : "");
-                return;
+        MessageBodyWriter writer = null;
+        MediaType responseType = null;
+        for (MediaType type : availableContentTypes) { 
+            writer = ProviderFactory.getInstance(baseAddress)
+                .createMessageBodyWriter(targetType, 
+                      invoked != null ? invoked.getGenericReturnType() : null, 
+                      invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
+                      type,
+                      message.getExchange().getInMessage());
+            
+            if (writer != null) {
+                responseType = type;
+                break;
             }
+        }
+    
+        OutputStream out = message.getContent(OutputStream.class);
+        if (writer == null) {
+            message.put(Message.RESPONSE_CODE, 500);
+            writeResponseErrorMessage(out, 
+                  "NO_MSG_WRITER",
+                  invoked != null ? invoked.getReturnType().getSimpleName() : "");
+            return;
+        }
+        
+        try {
             
-            try {
-                
-                responseType = checkFinalContentType(responseType);
-                LOG.fine("Response content type is: " + responseType.toString());
-                message.put(Message.CONTENT_TYPE, responseType.toString());
-                
-                LOG.fine("Response EntityProvider is: " + writer.getClass().getName());
-                writer.writeTo(responseObj, targetType, invoked.getGenericReturnType(), 
-                               invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
-                               responseType, 
-                               response.getMetadata(), 
-                               out);
-                
-            } catch (IOException e) {
-                e.printStackTrace();
-                message.put(Message.RESPONSE_CODE, 500);
-                writeResponseErrorMessage(out, "SERIALIZE_ERROR", 
-                                          responseObj.getClass().getSimpleName());
-            }        
-            
-        } else {
-            message.put(Message.RESPONSE_CODE, 204);
+            responseType = checkFinalContentType(responseType);
+            LOG.fine("Response content type is: " + responseType.toString());
+            message.put(Message.CONTENT_TYPE, responseType.toString());
+            
+            LOG.fine("Response EntityProvider is: " + writer.getClass().getName());
+            writer.writeTo(responseObj, targetType, invoked.getGenericReturnType(), 
+                           invoked != null ? invoked.getAnnotations() : new Annotation[]{}, 
+                           responseType, 
+                           response.getMetadata(), 
+                           out);
+            
+        } catch (IOException ex) {
+            handleWriteException(message, response, ori, baseAddress, ex, responseObj, firstTry);
+        } catch (Exception ex) {
+            handleWriteException(message, response, ori, baseAddress, ex, responseObj, firstTry);
         }
     }
     
+    private void handleWriteException(Message message, 
+                                         Response response, 
+                                         OperationResourceInfo ori,
+                                         String baseAddress,
+                                         Exception ex,
+                                         Object responseObj,
+                                         boolean firstTry) {
+        OutputStream out = message.getContent(OutputStream.class);
+        if (firstTry) {
+            Response excResponse = JAXRSUtils.convertFaultToResponse(ex, baseAddress, message);
+            if (excResponse != null) {
+                serializeMessage(message, excResponse, ori, baseAddress, false);
+            }
+        } else {
+            message.put(Message.RESPONSE_CODE, 500);
+            writeResponseErrorMessage(out, "SERIALIZE_ERROR", 
+                                      responseObj.getClass().getSimpleName()); 
+        }    
+    }
+    
     
     private void writeResponseErrorMessage(OutputStream out, String errorString, 
                                            String parameter) {
         try {
-            out.write(new org.apache.cxf.common.i18n.Message(errorString,
-                                                             BUNDLE,
-                                                             parameter
-                                                             ).toString().getBytes("UTF-8"));
+            org.apache.cxf.common.i18n.Message message = 
+                new org.apache.cxf.common.i18n.Message(errorString,
+                                                   BUNDLE,
+                                                   parameter);
+            LOG.warning(message.toString());
+            out.write(message.toString().getBytes("UTF-8"));
         } catch (IOException another) {
             // ignore
         }

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=750010&r1=750009&r2=750010&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Wed Mar  4 13:53:46 2009
@@ -20,6 +20,8 @@
 package org.apache.cxf.systest.jaxrs;
 
 
+import java.io.IOException;
+import java.io.OutputStream;
 import java.net.URL;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -48,6 +50,7 @@
 import javax.ws.rs.core.PathSegment;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.StreamingOutput;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -262,8 +265,14 @@
         return doGetBook(currentBookId);
     }
     
+    @GET
+    @Path("/books/stream")
+    @Produces("application/xml")
+    public StreamingOutput writeToStreamAndFail() {
+        return new StreamingOutputImpl();
+    }
+    
     private Book doGetBook(String id) throws BookNotFoundFault {
-        //System.out.println("----invoking getBook with id: " + id);
         Book book = books.get(Long.parseLong(id));
         if (book != null) {
             return book;
@@ -511,6 +520,17 @@
             throw new RuntimeException("The bad book");
         }
     }
+    
+    private static class StreamingOutputImpl implements StreamingOutput {
+
+        public void write(OutputStream output) throws IOException, WebApplicationException {
+            //output.write("This is not supposed to go on the wire".getBytes());
+            throw new WebApplicationException(
+                 Response.status(410).type("text/plain")
+                 .entity("This is supposed to go on the wire").build());
+        } 
+        
+    }
 }
 
 

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=750010&r1=750009&r2=750010&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Wed Mar  4 13:53:46 2009
@@ -84,6 +84,13 @@
                       "application/xml", 404);
     }
     
+    @Test
+    public void testWriteAndFailEarly() throws Exception {
+        getAndCompare("http://localhost:9080/bookstore/books/stream",
+                      "This is supposed to go on the wire",
+                      "application/xml, text/plain", 410);
+    }
+    
     
     @Test
     public void testAcceptTypeMismatch() throws Exception {