jspを返すrestlet
2014/02/03
java
jsp
restlet
jspを返すrestlet です。
とはいいつつ、これは正確な言い回しではないかもです。
GAE上で、Restletを使っていろいろ試しているところなのですが、restletで返すページ(この言い回しが正しいか微妙ですが)で、jspを指定して返したいなと。
で、いろいろ調べていて
jspってコンテナ上で、コンパイルされて処理されるものなので、どうもRestlet経由で、おこなうものっていうものでないらしく、僕が想像しているような感じのものがみつかりませんでした。
ただ、方法として、とりあえず、それっぽいものがあったので、忘れないように記事にしておきます。
- JSP/Servlet Representation
- Configure Restlet to Return JSPs on Google App Engine? - java, google-app-engine, jsp, restlet - TechQues.com
いまいち、決めてに欠ける理由に、こういう処理をしたいというニーズがないのかなと不安になりますが、海外で上記のやりとりがあるところから、JSPを処理して返したいという人々もいるのでしょう。
ルーターとして処理をしてくれるなら、なんでもそこを通して処理をしたいというの人の性(さが)というもので、いちいとweb.xmlとルーターで処理を分けるのもかったるいというか。。。
と、Restletをさわりはじめて数日なので、的外れな意見かもしれませんが。
とにもかくにも忘れないうちにコードを残しておきます。
使い方は、そのものずばり
router.attach("/mng/kind/{name}/dummy", new JspRestlet(getContext(), "/ok.jsp"));
それで、JspRestletの本体は、こんな感じ。
package jp.deiji.application;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.MediaType;
import org.restlet.engine.adapter.HttpRequest;
import org.restlet.ext.servlet.internal.ServletCall;
import org.restlet.representation.InputRepresentation;
import org.restlet.representation.Representation;
public class JspRestlet extends Restlet {
String path;
public JspRestlet(Context context, String path) {
super(context);
this.path = path;
}
@Override
public void handle(Request request, Response response) {
ServletCall httpCall = (ServletCall) ((HttpRequest) request)
.getHttpCall();
RequestDispatcher dispatcher = httpCall.getRequest()
.getRequestDispatcher(this.path);
HttpServletRequest proxyReq = new HttpServletRequestWrapper(
httpCall.getRequest());
BufferedServletResponseWrapper proxyResp = new BufferedServletResponseWrapper(
httpCall.getResponse());
try {
dispatcher.include(proxyReq, proxyResp);
} catch (ServletException | IOException e) {
e.printStackTrace();
}
Representation rep = new InputRepresentation(proxyResp.toInputStream(),
MediaType.TEXT_PLAIN);
response.setEntity(rep);
}
/**
* http://permalink.gmane.org/gmane.comp.java.restlet/8441
*
*
*/
public class BufferedServletResponseWrapper extends
HttpServletResponseWrapper {
private StringWriter writer;
private PrintWriter printWriter;
private ByteArrayOutputStream outBuffer;
private ServletOutputStream out;
public BufferedServletResponseWrapper(
HttpServletResponse httpServletResponse) {
super(httpServletResponse);
}
public ServletOutputStream getOutputStream() throws IOException {
if (printWriter != null) {
throw new UnsupportedOperationException(
"Outputstream cannot beobtained - getWriter already called");
}
if (out == null) {
outBuffer = new ByteArrayOutputStream();
out = new ServletOutputStream() {
public void write(int b) throws IOException {
outBuffer.write(b);
}
};
}
return out;
}
public PrintWriter getWriter() throws IOException {
if (out != null) {
throw new UnsupportedOperationException(
"Writer cannot beobtained - getOutputStream already called");
}
if (printWriter == null) {
writer = new StringWriter();
printWriter = new PrintWriter(writer);
}
return printWriter;
}
/**
* This method is not supported, as it makes no sense to send a redirect
* on a ServletResponse that is not connected.
*
* <at> param s <at> throws UnsupportedOperationException always
*/
public void sendRedirect(String s) throws IOException {
throw new UnsupportedOperationException(
"sendRedirect no supportedin restlet proxy");
}
/**
* Returns the content of the buffer as a string
*
* <at> return the content of the buffer
*/
public InputStream toInputStream() {
if (printWriter != null) {
printWriter.flush();
return new ByteArrayInputStream(writer.getBuffer().toString()
.getBytes());
} else if (out != null) {
return new ByteArrayInputStream(outBuffer.toByteArray());
} else {
return new ByteArrayInputStream(new byte[] {});
}
}
}
}
: