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 {