forked from apache/thrift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
THRIFT-1608 Allow servlet to be supplied TProcessor and TProtocolFact…
…ory after the init() method has finished Patch: Kiril Raychev git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1351848 13f79535-47bb-0310-9956-ffa450edef68
- Loading branch information
1 parent
f9f841d
commit e64b129
Showing
1 changed file
with
152 additions
and
0 deletions.
There are no files selected for viewing
152 changes: 152 additions & 0 deletions
152
lib/java/src/org/apache/thrift/server/TExtensibleServlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package org.apache.thrift.server; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Map; | ||
|
||
import javax.servlet.ServletConfig; | ||
import javax.servlet.ServletContext; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.apache.thrift.TException; | ||
import org.apache.thrift.TProcessor; | ||
import org.apache.thrift.protocol.TProtocol; | ||
import org.apache.thrift.protocol.TProtocolFactory; | ||
import org.apache.thrift.transport.TIOStreamTransport; | ||
import org.apache.thrift.transport.TTransport; | ||
|
||
/** | ||
* Servlet implementation class ThriftServer, that allows {@link TProcessor} and | ||
* {@link TProtocolFactory} to be supplied after the {@link #init()} method has | ||
* finished. <br> | ||
* Subclasses must implement the abstract methods that return the TProcessor and | ||
* two TProtocolFactory. Those methods are guaranteed to be called exactly once, | ||
* and that {@link ServletContext} is available. | ||
*/ | ||
public abstract class TExtensibleServlet extends HttpServlet { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private TProcessor processor; | ||
|
||
private TProtocolFactory inFactory; | ||
|
||
private TProtocolFactory outFactory; | ||
|
||
private Collection<Map.Entry<String, String>> customHeaders; | ||
|
||
/** | ||
* Returns the appropriate {@link TProcessor}. This will be called <b>once</b> just | ||
* after the {@link #init()} method | ||
* | ||
* @return | ||
*/ | ||
protected abstract TProcessor getProcessor(); | ||
|
||
/** | ||
* Returns the appropriate in {@link TProtocolFactory}. This will be called | ||
* <b>once</b> just after the {@link #init()} method | ||
* | ||
* @return | ||
*/ | ||
protected abstract TProtocolFactory getInProtocolFactory(); | ||
|
||
/** | ||
* Returns the appropriate out {@link TProtocolFactory}. This will be called | ||
* <b>once</b> just after the {@link #init()} method | ||
* | ||
* @return | ||
*/ | ||
protected abstract TProtocolFactory getOutProtocolFactory(); | ||
|
||
@Override | ||
public final void init(ServletConfig config) throws ServletException { | ||
super.init(config); //no-args init() happens here | ||
this.processor = getProcessor(); | ||
this.inFactory = getInProtocolFactory(); | ||
this.outFactory = getOutProtocolFactory(); | ||
this.customHeaders = new ArrayList<Map.Entry<String, String>>(); | ||
|
||
if (processor == null) { | ||
throw new ServletException("processor must be set"); | ||
} | ||
if (inFactory == null) { | ||
throw new ServletException("inFactory must be set"); | ||
} | ||
if (outFactory == null) { | ||
throw new ServletException("outFactory must be set"); | ||
} | ||
} | ||
|
||
/** | ||
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse | ||
* response) | ||
*/ | ||
@Override | ||
protected void doPost(HttpServletRequest request, HttpServletResponse response) | ||
throws ServletException, IOException { | ||
TTransport inTransport = null; | ||
TTransport outTransport = null; | ||
|
||
try { | ||
response.setContentType("application/x-thrift"); | ||
|
||
if (null != this.customHeaders) { | ||
for (Map.Entry<String, String> header : this.customHeaders) { | ||
response.addHeader(header.getKey(), header.getValue()); | ||
} | ||
} | ||
|
||
InputStream in = request.getInputStream(); | ||
OutputStream out = response.getOutputStream(); | ||
|
||
TTransport transport = new TIOStreamTransport(in, out); | ||
inTransport = transport; | ||
outTransport = transport; | ||
|
||
TProtocol inProtocol = inFactory.getProtocol(inTransport); | ||
TProtocol outProtocol = inFactory.getProtocol(outTransport); | ||
|
||
processor.process(inProtocol, outProtocol); | ||
out.flush(); | ||
} catch (TException te) { | ||
throw new ServletException(te); | ||
} | ||
} | ||
|
||
/** | ||
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse | ||
* response) | ||
*/ | ||
@Override | ||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) | ||
throws ServletException, IOException { | ||
doPost(req, resp); | ||
} | ||
|
||
public void addCustomHeader(final String key, final String value) { | ||
this.customHeaders.add(new Map.Entry<String, String>() { | ||
public String getKey() { | ||
return key; | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
public String setValue(String value) { | ||
return null; | ||
} | ||
}); | ||
} | ||
|
||
public void setCustomHeaders(Collection<Map.Entry<String, String>> headers) { | ||
this.customHeaders.clear(); | ||
this.customHeaders.addAll(headers); | ||
} | ||
} |