diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingController.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingController.java new file mode 100644 index 0000000000..06b22ea237 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingController.java @@ -0,0 +1,82 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.http; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.Controller; + +/** + * @author Mark Fisher + * @since 2.0 + */ +public class HttpRequestHandlingController extends HttpRequestHandlingEndpointSupport implements Controller { + + private static final String DEFAULT_REPLY_KEY = "reply"; + + + private volatile String viewName; + + private volatile String replyKey = DEFAULT_REPLY_KEY; + + + public HttpRequestHandlingController() { + this(true); + } + + public HttpRequestHandlingController(boolean expectReply) { + super(expectReply); + } + + + /** + * Specify the view name. + */ + public void setViewName(String viewName) { + this.viewName = viewName; + } + + /** + * Specify the key to be used when adding the reply Message or payload + * to the model map (will be payload only unless the value of + * {@link #setExtractReplyPayload(boolean) extractReplyPayload} is false). + * The default key is "reply". + */ + public void setReplyKey(String replyKey) { + this.replyKey = (replyKey != null) ? replyKey : DEFAULT_REPLY_KEY; + } + + /** + * Handles the HTTP request by generating a Message and sending it to the request channel. + * If this gateway's 'expectReply' property is true, it will also generate a response from + * the reply Message once received. + */ + public final ModelAndView handleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception { + ModelAndView modelAndView = new ModelAndView(); + if (this.viewName != null) { + modelAndView.setViewName(this.viewName); + } + Object reply = super.doHandleRequest(servletRequest, servletResponse); + if (reply != null) { + modelAndView.addObject(this.replyKey, reply); + } + return modelAndView; + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingEndpointSupport.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingEndpointSupport.java index 647da3385e..c5540666fb 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingEndpointSupport.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingEndpointSupport.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -37,6 +38,7 @@ import org.springframework.http.converter.json.MappingJacksonHttpMessageConverte import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter; import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessagingException; import org.springframework.integration.gateway.AbstractMessagingGateway; @@ -79,6 +81,8 @@ abstract class HttpRequestHandlingEndpointSupport extends AbstractMessagingGatew private final boolean expectReply; + private volatile boolean extractReplyPayload = true; + private volatile MultipartResolver multipartResolver; @@ -130,10 +134,6 @@ abstract class HttpRequestHandlingEndpointSupport extends AbstractMessagingGatew this.headerMapper = headerMapper; } - protected HeaderMapper getHeaderMapper() { - return this.headerMapper; - } - /** * Specify the supported request methods for this gateway. * By default, only GET and POST are supported. @@ -152,10 +152,20 @@ abstract class HttpRequestHandlingEndpointSupport extends AbstractMessagingGatew this.conversionTargetType = conversionTargetType; } + /** + * Specify whether only the reply Message's payload should be passed + * in the response. If this is set to 'false', the entire Message will + * be used to generate the response. The default is 'true'. + */ + public void setExtractReplyPayload(boolean extractReplyPayload) { + this.extractReplyPayload = extractReplyPayload; + } + /** * Specify the {@link MultipartResolver} to use when checking requests. - * If no resolver is provided, this mapper will not support multipart - * requests. + * If no resolver is provided, the "multipartResolver" bean in the context + * will be used as a fallback. If that is not available either, this endpoint + * will not support multipart requests. */ public void setMultipartResolver(MultipartResolver multipartResolver) { this.multipartResolver = multipartResolver; @@ -197,10 +207,13 @@ abstract class HttpRequestHandlingEndpointSupport extends AbstractMessagingGatew * If this gateway's 'expectReply' property is true, it will also generate a response from * the reply Message once received. */ - protected final Object handleRequest(HttpServletRequest servletRequest) throws IOException { + protected final Object doHandleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException { ServletServerHttpRequest request = this.prepareRequest(servletRequest); - Assert.isTrue(this.supportedMethods.contains(request.getMethod()), - "unsupported request method [" + request.getMethod() + "]"); + if (!this.supportedMethods.contains(request.getMethod())) { + servletResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); + this.postProcessRequest(servletRequest); + return null; + } Object payload = null; if (this.isReadable(request)) { payload = this.generatePayloadFromRequestBody(request); @@ -211,19 +224,26 @@ abstract class HttpRequestHandlingEndpointSupport extends AbstractMessagingGatew Map headers = this.headerMapper.toHeaders(request.getHeaders()); Message message = MessageBuilder.withPayload(payload) .copyHeaders(headers) - //.setHeader(HttpHeaders.REQUEST_URL, request.getURI().toString()) - //.setHeader(HttpHeaders.REQUEST_METHOD, request.getMethod().toString()) - //.setHeader(HttpHeaders.USER_PRINCIPAL, servletRequest.getUserPrincipal()) + .setHeader(org.springframework.integration.http.HttpHeaders.REQUEST_URL, request.getURI().toString()) + .setHeader(org.springframework.integration.http.HttpHeaders.REQUEST_METHOD, request.getMethod().toString()) + .setHeader(org.springframework.integration.http.HttpHeaders.USER_PRINCIPAL, servletRequest.getUserPrincipal()) .build(); - Object result = null; + Object reply = null; if (this.expectReply) { - result = this.sendAndReceiveMessage(message); + reply = this.sendAndReceiveMessage(message); + if (reply != null) { + ServletServerHttpResponse response = new ServletServerHttpResponse(servletResponse); + this.headerMapper.fromHeaders(((Message) reply).getHeaders(), response.getHeaders()); + if (this.extractReplyPayload) { + reply = ((Message) reply).getPayload(); + } + } } else { this.send(message); } this.postProcessRequest(servletRequest); - return result; + return reply; } /** diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingMessagingGateway.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingMessagingGateway.java index 15f74bb853..9a45efeb63 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingMessagingGateway.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestHandlingMessagingGateway.java @@ -27,7 +27,6 @@ import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; -import org.springframework.integration.core.Message; import org.springframework.integration.core.MessagingException; import org.springframework.util.MultiValueMap; import org.springframework.web.HttpRequestHandler; @@ -59,9 +58,6 @@ import org.springframework.web.HttpRequestHandler; */ public class HttpRequestHandlingMessagingGateway extends HttpRequestHandlingEndpointSupport implements HttpRequestHandler { - private volatile boolean extractReplyPayload = true; - - public HttpRequestHandlingMessagingGateway() { this(true); } @@ -71,32 +67,16 @@ public class HttpRequestHandlingMessagingGateway extends HttpRequestHandlingEndp } - /** - * Specify whether the reply Message's payload should be passed in - * the response. If this is set to 'false', the entire Message will - * be processed by the {@link HttpMessageConverter}s. Otherwise, the - * reply Message payload will be processed. The default is 'true'. - */ - public void setExtractReplyPayload(boolean extractReplyPayload) { - this.extractReplyPayload = extractReplyPayload; - } - /** * Handles the HTTP request by generating a Message and sending it to the request channel. * If this gateway's 'expectReply' property is true, it will also generate a response from - * the reply Message once received. + * the reply Message once received. That response will be written by the {@link HttpMessageConverter}s. */ public final void handleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException { - Object responseContent = super.handleRequest(servletRequest); - ServletServerHttpResponse response = new ServletServerHttpResponse(servletResponse); - if (responseContent instanceof Message) { - this.getHeaderMapper().fromHeaders(((Message) responseContent).getHeaders(), response.getHeaders()); - if (this.extractReplyPayload) { - responseContent = ((Message) responseContent).getPayload(); - } - } + Object responseContent = super.doHandleRequest(servletRequest, servletResponse); if (responseContent != null) { ServletServerHttpRequest request = new ServletServerHttpRequest(servletRequest); + ServletServerHttpResponse response = new ServletServerHttpResponse(servletResponse); this.writeResponse(responseContent, response, request.getHeaders().getAccept()); } } @@ -111,8 +91,8 @@ public class HttpRequestHandlingMessagingGateway extends HttpRequestHandlingEndp } } } - throw new MessagingException("Could not convert reply: no suitable HttpMessageConverter found for result type [" + - content.getClass().getName() + "] and content types [" + acceptTypes + "]"); + throw new MessagingException("Could not convert reply: no suitable HttpMessageConverter found for type [" + + content.getClass().getName() + "] and accept types [" + acceptTypes + "]"); } }