INT-1245, INT-1256 removed old HttpInboundEndpoint

This commit is contained in:
Mark Fisher
2010-07-27 04:31:07 +00:00
parent 56f6453a8e
commit bc56173725
2 changed files with 0 additions and 707 deletions

View File

@@ -1,301 +0,0 @@
/*
* 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 java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.integration.core.Message;
import org.springframework.integration.gateway.SimpleMessagingGateway;
import org.springframework.integration.message.MessageTimeoutException;
import org.springframework.util.Assert;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.View;
/**
* An inbound endpoint for handling an HTTP request and generating a response.
* <p/>
* By default GET and POST requests are accepted, but the 'supportedMethods'
* property may be set to include others or limit the options (e.g. POST only).
* By default the request will be converted to a Message payload according to
* the rules of the {@link DefaultInboundRequestMapper}.
* <p/>
* To customize the mapping of the request to the Message payload, provide
* a reference to an {@link InboundRequestMapper} implementation to the
* {@link #setRequestMapper(InboundRequestMapper)} method.
* <p/>
* The value for {@link #expectReply} is <code>false</code> by default.
* This means that as soon as the Message is created and passed to the
* {@link #setRequestChannel(org.springframework.integration.core.MessageChannel) request channel},
* a response will be generated. If a {@link #setView(View) view} has been
* provided, it will be invoked to render the response, and it will have
* access to the request message in the model map. The corresponding key
* in that map is determined by the {@link #requestKey} property (with a
* default of "requestMessage"). If no view is provided, and the 'expectReply'
* value is <code>false</code> then a simple OK status response will be issued.
* <p/>
* To handle request-reply scenarios, set the 'expectReply' flag to
* <code>true</code>. By default, the reply Message's payload will be
* extracted prior to generating a response. The payload must be either
* a String, a byte array, or a Serializable object. To have the entire
* serialized Message written as the response body, switch the
* {@link #extractReplyPayload} value to <code>false</code>.
* <p/>
* In the request-reply case, if a 'view' is provided, the response will
* not be generated directly from the reply Message or its extracted payload.
* Instead, the model map will be passed to that view, and it will contain
* either the reply Message or payload depending on the value of
* {@link #extractReplyPayload}. The corresponding key in the map will be
* determined by the {@link #replyKey} property (with a default of "reply").
* The map will also contain the original request Message as described above.
*
* @author Mark Fisher
* @since 1.0.2
*/
public class HttpInboundEndpoint extends SimpleMessagingGateway implements HttpRequestHandler {
private static final String DEFAULT_REQUEST_KEY = "requestMessage";
private static final String DEFAULT_REPLY_KEY = "reply";
private volatile List<String> supportedMethods = Arrays.asList("GET", "POST");
private volatile boolean expectReply;
private volatile InboundRequestMapper requestMapper;
private volatile boolean extractReplyPayload = true;
private volatile View view;
private volatile String requestKey = DEFAULT_REQUEST_KEY;
private volatile String replyKey = DEFAULT_REPLY_KEY;
/**
* Specify the supported request methods for this endpoint.
* By default, only GET and POST are supported.
*/
public void setSupportedMethods(String... supportedMethods) {
Assert.notEmpty(supportedMethods, "at least one supported method is required");
for (int i = 0; i < supportedMethods.length; i++) {
supportedMethods[i] = supportedMethods[i].trim().toUpperCase();
}
this.supportedMethods = Arrays.asList(supportedMethods);
}
/**
* Specify whether this endpoint should perform a request/reply
* operation. Otherwise, it will only send the message and
* immediately generate a response. The default is 'false'.
*/
public void setExpectReply(boolean expectReply) {
this.expectReply = expectReply;
}
/**
* Specify an {@link InboundRequestMapper} implementation to map from the
* inbound {@link HttpServletRequest} instances to Messages at runtime.
* The default implementation is {@link DefaultInboundRequestMapper}.
*/
public void setRequestMapper(InboundRequestMapper requestMapper) {
Assert.notNull(requestMapper, "requestMapper must not be null");
this.requestMapper = requestMapper;
}
/**
* Specify whether the reply Message's payload should be passed in
* the response. If this is set to 'false', the entire Message will
* be sent as bytes. Otherwise, the reply Message payload must be
* a String or byte array. If a 'view' has been provided,
* the reply value will be sent in the model Map to that View.
* If the 'view' is <code>null</code>, the String or byte array
* will be written directly to the HTTP response.
* <p>The default value is 'true'.
* @see #setView(View)
*/
public void setExtractReplyPayload(boolean extractReplyPayload) {
this.extractReplyPayload = extractReplyPayload;
}
/**
* Specify a {@link View} to be used for rendering the
* response. If no View is provided, the reply Message or its
* payload will be written directly to the response.
* @see #setExtractReplyPayload(boolean)
*/
public void setView(View view) {
this.view = view;
}
/**
* Specify the key to be used when storing the request Message in the model
* map. This is only necessary when a {@link #setView(View) view} has been
* provided for rendering the response. The default key is "requestMessage".
*/
public void setRequestKey(String requestKey) {
this.requestKey = (requestKey != null) ? requestKey : DEFAULT_REQUEST_KEY;
}
/**
* Specify the key to be used when storing the reply Message or payload in
* the model map. This is only necessary when a {@link #setView(View) view}
* has been provided for rendering the response. The default key is "reply".
*/
public void setReplyKey(String replyKey) {
this.replyKey = (replyKey != null) ? replyKey : DEFAULT_REPLY_KEY;
}
@Override
protected void onInit() throws Exception {
if (this.requestMapper == null) {
this.configureDefaultRequestMapper();
}
super.onInit();
}
private void configureDefaultRequestMapper() {
DefaultInboundRequestMapper defaultMapper = new DefaultInboundRequestMapper();
if (this.getBeanFactory() != null) {
try {
MultipartResolver multipartResolver =
this.getBeanFactory().getBean(DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using MultipartResolver [" + multipartResolver + "]");
}
defaultMapper.setMultipartResolver(multipartResolver);
}
catch (NoSuchBeanDefinitionException e) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MultipartResolver with name '" + DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME +
"': no multipart request handling will be supported.");
}
}
}
this.requestMapper = defaultMapper;
}
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Assert.notNull(this.requestMapper, "HttpInboundEndpoint has not been initialized.");
if (!this.supportedMethods.contains(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
try {
Message<?> requestMessage = this.requestMapper.toMessage(request);
Object reply = this.handleRequestMessage(requestMessage);
this.generateResponse(requestMessage, reply, request, response);
}
catch (ResponseStatusCodeException e) {
response.setStatus(e.getStatusCode());
}
catch (ServletException e) {
throw e;
}
catch (IOException e) {
throw e;
}
catch (Exception e) {
throw new ServletException(e);
}
}
private Object handleRequestMessage(Message<?> requestMessage) {
Object reply = null;
if (this.expectReply) {
if (this.extractReplyPayload) {
reply = this.sendAndReceive(requestMessage);
}
else {
reply = this.sendAndReceiveMessage(requestMessage);
}
if (reply == null) {
throw new MessageTimeoutException(requestMessage,
"failed to handle Message within specified timeout value");
}
}
else {
this.send(requestMessage);
}
return reply;
}
private void generateResponse(Message<?> requestMessage, Object reply,
HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException {
if (this.view != null) {
Map<String, Object> model = new HashMap<String, Object>();
model.put(this.requestKey, requestMessage);
if (reply != null) {
model.put(this.replyKey, reply);
}
try {
this.view.render(model, httpRequest, httpResponse);
}
catch (Exception e) {
throw new ServletException("failed to render view", e);
}
}
else if (reply == null) {
httpResponse.setStatus(HttpServletResponse.SC_OK);
}
else if (reply instanceof String) {
httpResponse.setContentType("text/plain");
httpResponse.setContentLength(((String) reply).length());
httpResponse.getWriter().print((String) reply);
httpResponse.flushBuffer();
}
else if (reply instanceof byte[]) {
byte[] bytes = (byte[]) reply;
httpResponse.setContentType("application/octet-stream");
httpResponse.setContentLength(bytes.length);
httpResponse.getOutputStream().write(bytes);
httpResponse.flushBuffer();
}
else if (reply instanceof Serializable) {
// either a Serializable payload or the Message itself
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(reply);
objectStream.flush();
objectStream.close();
byte[] bytes = byteStream.toByteArray();
httpResponse.getOutputStream().write(bytes);
httpResponse.setContentType("application/x-java-serialized-object");
httpResponse.setContentLength(bytes.length);
httpResponse.flushBuffer();
}
else {
throw new ServletException("failed to generate HTTP response from reply Message");
}
}
}