1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.servlet;
12
13 import org.mule.RequestContext;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.config.MuleProperties;
17 import org.mule.api.lifecycle.InitialisationException;
18 import org.mule.api.transport.OutputHandler;
19 import org.mule.config.ExceptionHelper;
20 import org.mule.transport.http.HttpConstants;
21 import org.mule.transport.http.HttpResponse;
22 import org.mule.transport.http.transformers.MuleMessageToHttpResponse;
23
24 import java.io.IOException;
25
26 import javax.servlet.ServletException;
27 import javax.servlet.http.HttpServlet;
28 import javax.servlet.http.HttpServletResponse;
29
30 import org.apache.commons.httpclient.Header;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39 public abstract class AbstractReceiverServlet extends HttpServlet
40 {
41
42
43
44
45 protected transient Log logger = LogFactory.getLog(getClass());
46
47 public static final String REQUEST_TIMEOUT_PROPERTY = "org.mule.servlet.timeout";
48 public static final String FEEDBACK_PROPERTY = "org.mule.servlet.feedback";
49 public static final String DEFAULT_CONTENT_TYPE_PROPERTY = "org.mule.servlet.default.content.type";
50
51
52
53
54
55 @Deprecated
56 public static final String SERVLET_CONNECTOR_NAME_PROPERTY = "org.mule.servlet.connector.name";
57
58 public static final String PAYLOAD_PARAMETER_NAME = "org.mule.servlet.payload.param";
59 public static final String DEFAULT_PAYLOAD_PARAMETER_NAME = "payload";
60
61 public static final long DEFAULT_GET_TIMEOUT = 10000L;
62
63 protected String payloadParameterName;
64 protected long timeout = DEFAULT_GET_TIMEOUT;
65 protected boolean feedback = true;
66 protected String defaultContentType = HttpConstants.DEFAULT_CONTENT_TYPE;
67 protected MuleContext muleContext;
68
69 private MuleMessageToHttpResponse responseTransformer = new MuleMessageToHttpResponse();
70
71 @Override
72 public final void init() throws ServletException
73 {
74 String timeoutString = getServletConfig().getInitParameter(REQUEST_TIMEOUT_PROPERTY);
75 if (timeoutString != null)
76 {
77 timeout = Long.parseLong(timeoutString);
78 }
79 if (logger.isInfoEnabled())
80 {
81 logger.info("Default request timeout for GET methods is: " + timeout);
82 }
83
84 String feedbackString = getServletConfig().getInitParameter(FEEDBACK_PROPERTY);
85 if (feedbackString != null)
86 {
87 feedback = Boolean.valueOf(feedbackString);
88 }
89 if (logger.isInfoEnabled())
90 {
91 logger.info("feedback is set to: " + feedback);
92 }
93
94 String ct = getServletConfig().getInitParameter(DEFAULT_CONTENT_TYPE_PROPERTY);
95 if (ct != null)
96 {
97 if (logger.isDebugEnabled())
98 {
99 logger.debug("Using default content type configured on the servlet (" + DEFAULT_CONTENT_TYPE_PROPERTY + ") = " + ct);
100 }
101 defaultContentType = ct;
102 }
103 if (logger.isInfoEnabled())
104 {
105 logger.info("Default content type is: " + defaultContentType);
106 }
107
108 payloadParameterName = getServletConfig().getInitParameter(PAYLOAD_PARAMETER_NAME);
109 if (payloadParameterName == null)
110 {
111 payloadParameterName = DEFAULT_PAYLOAD_PARAMETER_NAME;
112 }
113 if (logger.isInfoEnabled())
114 {
115 logger.info("Using payload param name: " + payloadParameterName);
116 }
117
118 muleContext = setupMuleContext();
119 responseTransformer.setMuleContext(muleContext);
120 try
121 {
122 responseTransformer.initialise();
123 }
124 catch (InitialisationException e)
125 {
126 throw new ServletException(e);
127 }
128 doInit();
129 }
130
131 protected MuleContext setupMuleContext() throws ServletException
132 {
133 MuleContext muleContext = (MuleContext) getServletContext().getAttribute(MuleProperties.MULE_CONTEXT_PROPERTY);
134 if (muleContext == null)
135 {
136 throw new ServletException("Property " + MuleProperties.MULE_CONTEXT_PROPERTY + " not set on ServletContext");
137 }
138 return muleContext;
139 }
140
141 protected void doInit() throws ServletException
142 {
143
144 }
145
146 protected void writeResponse(HttpServletResponse servletResponse, MuleMessage message) throws Exception
147 {
148 if (message == null)
149 {
150 servletResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
151 if (feedback)
152 {
153 servletResponse.setStatus(HttpServletResponse.SC_OK);
154 servletResponse.getWriter().write("Action was processed successfully. There was no result");
155 }
156 }
157 else
158 {
159 HttpResponse httpResponse;
160
161 if (message.getPayload() instanceof HttpResponse)
162 {
163 httpResponse = (HttpResponse) message.getPayload();
164
165 }
166 else
167 {
168 httpResponse = (HttpResponse) responseTransformer.transform(message);
169 }
170
171
172 Header contentTypeHeader = httpResponse.getFirstHeader(HttpConstants.HEADER_CONTENT_TYPE);
173 String contentType = defaultContentType;
174 if (contentTypeHeader != null && contentTypeHeader.getValue() != null)
175 {
176 if (logger.isDebugEnabled())
177 {
178 logger.debug("Using Content-Type from message header = " + contentTypeHeader.getValue());
179 }
180 contentType = contentTypeHeader.getValue();
181 }
182
183 servletResponse.setContentType(contentType);
184
185 servletResponse = setHttpHeadersOnServletResponse(httpResponse, servletResponse);
186
187 if (!servletResponse.isCommitted())
188 {
189 servletResponse.setStatus(httpResponse.getStatusCode());
190 }
191
192 if (httpResponse.hasBody())
193 {
194 OutputHandler outputHandler = httpResponse.getBody();
195 outputHandler.write(RequestContext.getEvent(), servletResponse.getOutputStream());
196 }
197 }
198 servletResponse.flushBuffer();
199 }
200
201 protected HttpServletResponse setHttpHeadersOnServletResponse(HttpResponse httpResponse, HttpServletResponse servletResponse)
202 {
203
204
205
206
207
208 httpResponse.removeHeaders(HttpConstants.HEADER_TRANSFER_ENCODING);
209
210 Header[] headers = httpResponse.getHeaders();
211 for (Header header : headers)
212 {
213 servletResponse.setHeader(header.getName(), header.getValue());
214 }
215 return servletResponse;
216 }
217
218 protected void handleException(Throwable exception, String message, HttpServletResponse response)
219 {
220 logger.error("message: " + exception.getMessage(), exception);
221 int code = Integer.valueOf(ExceptionHelper.getErrorMapping("http", exception.getClass()));
222 response.setStatus(code);
223 try
224 {
225 response.sendError(code, message + ": " + exception.getMessage());
226 }
227 catch (IOException e)
228 {
229 logger.error("Failed to sendError on response: " + e.getMessage(), e);
230 }
231 }
232 }