@Override protected void writeToResult(Object o, HttpHeaders headers, Result result) throws Exception { Assert.notNull(this.marshaller, "Property 'marshaller' is required"); this.marshaller.marshal(o, result); }
/** * Write the value objects and flush them to the file. * * @param items the value object * * @throws IOException thrown if general error occurs. * @throws XmlMappingException thrown if error occurs during XML Mapping. */ @Override public void write(List<? extends T> items) throws XmlMappingException, IOException { if(!this.initialized) { throw new WriterNotOpenException("Writer must be open before it can be written to"); } currentRecordCount += items.size(); for (Object object : items) { Assert.state(marshaller.supports(object.getClass()), "Marshaller must support the class of the marshalled object"); Result result = createStaxResult(); marshaller.marshal(object, result); } try { eventWriter.flush(); if (forceSync) { channel.force(false); } } catch (XMLStreamException | IOException e) { throw new WriteFailedException("Failed to flush the events", e); } }
@Override protected boolean canConvertTo(Object payload, @Nullable MessageHeaders headers) { return (supportsMimeType(headers) && this.marshaller != null && this.marshaller.supports(payload.getClass())); }
@Override public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) { return (canWrite(mediaType) && this.marshaller != null && this.marshaller.supports(clazz)); }
/** * Marshal the given object to a {@link TextMessage}. * @param object the object to be marshalled * @param session current JMS session * @param marshaller the marshaller to use * @return the resulting message * @throws JMSException if thrown by JMS methods * @throws IOException in case of I/O errors * @throws XmlMappingException in case of OXM mapping errors * @see Session#createTextMessage * @see Marshaller#marshal(Object, Result) */ protected TextMessage marshalToTextMessage(Object object, Session session, Marshaller marshaller) throws JMSException, IOException, XmlMappingException { StringWriter writer = new StringWriter(); Result result = new StreamResult(writer); marshaller.marshal(object, result); return session.createTextMessage(writer.toString()); }
@Test public void renderModelKeyWithJaxbElement() throws Exception { String toBeMarshalled = "value"; String modelKey = "key"; view.setModelKey(modelKey); Map<String, Object> model = new HashMap<>(); model.put(modelKey, new JAXBElement<>(new QName("model"), String.class, toBeMarshalled)); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(String.class)).willReturn(true); marshallerMock.marshal(eq(toBeMarshalled), isA(StreamResult.class)); view.render(model, request, response); assertEquals("Invalid content type", "application/xml", response.getContentType()); assertEquals("Invalid content length", 0, response.getContentLength()); }
/** * Check whether the given value from the current view's model is eligible * for marshalling through the configured {@link Marshaller}. * <p>The default implementation calls {@link Marshaller#supports(Class)}, * unwrapping a given {@link JAXBElement} first if applicable. * @param modelKey the value's key in the model (never {@code null}) * @param value the value to check (never {@code null}) * @return whether the given value is to be considered as eligible * @see Marshaller#supports(Class) */ protected boolean isEligibleForMarshalling(String modelKey, Object value) { Assert.state(this.marshaller != null, "No Marshaller set"); Class<?> classToCheck = value.getClass(); if (value instanceof JAXBElement) { classToCheck = ((JAXBElement<?>) value).getDeclaredType(); } return this.marshaller.supports(classToCheck); }
@Override protected void writeToResult(Object o, HttpHeaders headers, Result result) throws Exception { Assert.notNull(this.marshaller, "Property 'marshaller' is required"); this.marshaller.marshal(o, result); }
@Test public void renderNoModelKeyAndBindingResultFirst() throws Exception { Object toBeMarshalled = new Object(); String modelKey = "key"; Map<String, Object> model = new LinkedHashMap<>(); model.put(BindingResult.MODEL_KEY_PREFIX + modelKey, new BeanPropertyBindingResult(toBeMarshalled, modelKey)); model.put(modelKey, toBeMarshalled); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(BeanPropertyBindingResult.class)).willReturn(true); given(marshallerMock.supports(Object.class)).willReturn(true); view.render(model, request, response); assertEquals("Invalid content type", "application/xml", response.getContentType()); assertEquals("Invalid content length", 0, response.getContentLength()); verify(marshallerMock).marshal(eq(toBeMarshalled), isA(StreamResult.class)); }
@Override public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) { return (canWrite(mediaType) && this.marshaller != null && this.marshaller.supports(clazz)); }
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { Object toBeMarshalled = locateToBeMarshalled(model); if (toBeMarshalled == null) { throw new IllegalStateException("Unable to locate object to be marshalled in model: " + model); } Assert.state(this.marshaller != null, "No Marshaller set"); ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); this.marshaller.marshal(toBeMarshalled, new StreamResult(baos)); setResponseContentType(request, response); response.setContentLength(baos.size()); baos.writeTo(response.getOutputStream()); }
@Test public void renderNoModelKey() throws Exception { Object toBeMarshalled = new Object(); String modelKey = "key"; Map<String, Object> model = new HashMap<>(); model.put(modelKey, toBeMarshalled); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(Object.class)).willReturn(true); view.render(model, request, response); assertEquals("Invalid content type", "application/xml", response.getContentType()); assertEquals("Invalid content length", 0, response.getContentLength()); verify(marshallerMock).marshal(eq(toBeMarshalled), isA(StreamResult.class)); }
/** * Check whether the given value from the current view's model is eligible * for marshalling through the configured {@link Marshaller}. * <p>The default implementation calls {@link Marshaller#supports(Class)}, * unwrapping a given {@link JAXBElement} first if applicable. * @param modelKey the value's key in the model (never {@code null}) * @param value the value to check (never {@code null}) * @return whether the given value is to be considered as eligible * @see Marshaller#supports(Class) */ protected boolean isEligibleForMarshalling(String modelKey, Object value) { Assert.state(this.marshaller != null, "No Marshaller set"); Class<?> classToCheck = value.getClass(); if (value instanceof JAXBElement) { classToCheck = ((JAXBElement<?>) value).getDeclaredType(); } return this.marshaller.supports(classToCheck); }
@Override @Nullable protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) { Assert.notNull(this.marshaller, "Property 'marshaller' is required"); try { if (byte[].class == getSerializedPayloadClass()) { ByteArrayOutputStream out = new ByteArrayOutputStream(); Result result = new StreamResult(out); this.marshaller.marshal(payload, result); payload = out.toByteArray(); } else { Writer writer = new StringWriter(); Result result = new StreamResult(writer); this.marshaller.marshal(payload, result); payload = writer.toString(); } } catch (Throwable ex) { throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex); } return payload; }
@Test public void renderModelKey() throws Exception { Object toBeMarshalled = new Object(); String modelKey = "key"; view.setModelKey(modelKey); Map<String, Object> model = new HashMap<>(); model.put(modelKey, toBeMarshalled); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(Object.class)).willReturn(true); marshallerMock.marshal(eq(toBeMarshalled), isA(StreamResult.class)); view.render(model, request, response); assertEquals("Invalid content type", "application/xml", response.getContentType()); assertEquals("Invalid content length", 0, response.getContentLength()); }
@Test public void testRenderUnsupportedModel() throws Exception { Object toBeMarshalled = new Object(); String modelKey = "key"; Map<String, Object> model = new HashMap<>(); model.put(modelKey, toBeMarshalled); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(Object.class)).willReturn(false); try { view.render(model, request, response); fail("IllegalStateException expected"); } catch (IllegalStateException ex) { // expected } }
/** * Marshal the given object to a {@link BytesMessage}. * @param object the object to be marshalled * @param session current JMS session * @param marshaller the marshaller to use * @return the resulting message * @throws JMSException if thrown by JMS methods * @throws IOException in case of I/O errors * @throws XmlMappingException in case of OXM mapping errors * @see Session#createBytesMessage * @see Marshaller#marshal(Object, Result) */ protected BytesMessage marshalToBytesMessage(Object object, Session session, Marshaller marshaller) throws JMSException, IOException, XmlMappingException { ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); StreamResult streamResult = new StreamResult(bos); marshaller.marshal(object, streamResult); BytesMessage message = session.createBytesMessage(); message.writeBytes(bos.toByteArray()); return message; }
@Test public void renderModelKeyUnsupported() throws Exception { Object toBeMarshalled = new Object(); String modelKey = "key"; view.setModelKey(modelKey); Map<String, Object> model = new HashMap<>(); model.put(modelKey, toBeMarshalled); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); given(marshallerMock.supports(Object.class)).willReturn(false); try { view.render(model, request, response); fail("IllegalStateException expected"); } catch (IllegalStateException ex) { // expected } }
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { Object toBeMarshalled = locateToBeMarshalled(model); if (toBeMarshalled == null) { throw new IllegalStateException("Unable to locate object to be marshalled in model: " + model); } Assert.state(this.marshaller != null, "No Marshaller set"); ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); this.marshaller.marshal(toBeMarshalled, new StreamResult(baos)); setResponseContentType(request, response); response.setContentLength(baos.size()); baos.writeTo(response.getOutputStream()); }
@Test public void canWrite() { Marshaller marshaller = mock(Marshaller.class); given(marshaller.supports(Integer.class)).willReturn(false); given(marshaller.supports(String.class)).willReturn(true); MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(); converter.setMarshaller(marshaller); assertFalse(converter.canWrite(Boolean.class, MediaType.TEXT_PLAIN)); assertFalse(converter.canWrite(Integer.class, MediaType.TEXT_XML)); assertTrue(converter.canWrite(String.class, MediaType.TEXT_XML)); }