INT-1245, INT-1256 shifting balance between sub-classes and base

This commit is contained in:
Mark Fisher
2010-07-26 22:38:24 +00:00
parent ef25896a9a
commit 19b1ab5fd6
3 changed files with 122 additions and 40 deletions

View File

@@ -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 <code>false</code>).
* 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;
}
}

View File

@@ -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<HttpHeaders> 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<String, ?> 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;
}
/**

View File

@@ -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 + "]");
}
}