ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Java質問&情報提供サイトコミュのアプレットでrtf形式のDocumentを作り、サーブレットに転送し保存できますか?

  • mixiチェック
  • このエントリーをはてなブックマークに追加
いつもお世話になっております。しずやと申します。
今回は、アプレットでJTextPaneを利用してrtf形式のDocument
を作成してそれをサーブレット側に送りリッチテキストとして
保存できないかなと試行錯誤しておりましたが、
やっぱりできません。。このような事は可能なのでしょうか?

かなり省略してますがサーブレットとアプレットのソースを
下に貼り付けます。メソッドの宣言、try〜catchも省きました。。

windows xp
jdk 6
tomcat 6


******************アプレット側*********************

JTextPane textPane = new JTextPane();
JScrollPane scroll = new JScrollPane(textPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBounds(10, 60, 300, 100);

StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

textPane.setDocument(doc);
initDocument(doc,sc);//文章の追加しています。
changeStyle(doc);//文章のスタイル変更しています。

URL u = null;
u = new URL(applet.getRtfsavepath());//サーブレットのパスが入ります。

URLConnection connect = null;

connect = u.openConnection();//サーブレットとの回線を開きます。
connect.setDoOutput(true);

RTFEditorKit rtfEditor = new RTFEditorKit();
rtfEditor.write(connect.getOutputStream(),doc, 0, doc.getLength());


********************サーブレット側*********************

ServletContext application = this.getServletContext();
StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

ServletInputStream input = request.getInputStream();
RTFEditorKit rtfEditor = new RTFEditorKit();
FileOutputStream out = new FileOutputStream(application.getRealPath("/WEB-INF/test.rtf"));

rtfEditor.read(input, doc, 0);
rtfEditor.write(out, doc, 0, doc.getLength());

input.close();
out.close();

************************************

こんな感じで独学で作ってみたのですが
エラーは出ないのですが、ファイルも作成されませんorz
不可能でしょうか?^^;
よろしければ、ご教授願います。orz

参考にさせていただいたHPのURLはこちら。
http://www.javadrive.jp/tutorial/appli_word/index.html


コメント(10)

技術的には全く問題ないですが、
どこまでデータが流れているかトレースしましたか?


ソース見て僕が疑った部分です。

1.rtfEditor.write(connect.getOutputStream(),doc, 0, doc.getLength());
これで本当にアウトに書き込まれてますか?

2.サーブレットで受け取れてますか?

3.ファイル作成権限ありますか?(/WEB-INFの下って書き込めたっけ…)
(でも、例外発生しないのか?サーブレットがもみ消し?)

Eclipseなどの統合環境を使ってるなら、ブレークさせてしっかりトレースしましょう。
よく見たら、 URLConnection.connect() 呼んでないからじゃ?
ドキュメントによれば、これ呼ばれるまで、実際に繋がってるわけではないっぽいですよ。
アプレットではないですが、作ってみました。
(アプレットは自身が配備されているホスト以外へのアクセス制限があったような気がするので、、、たぶん、、、)
とりあえず貼り付け。長すぎて怒られましたw

//クライアント
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.rtf.RTFEditorKit;

public class RTFDocumentServerClientTest extends JFrame {

private static final long serialVersionUID = -6337145735082024684L;

public RTFDocumentServerClientTest() {
try {

setTitle("TextPaneTest Test");
setBounds(10, 10, 300, 200);

JTextPane textPane = new JTextPane();
JScrollPane scroll = new JScrollPane(textPane,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBounds(10, 60, 300, 100);

add(scroll);

StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

textPane.setDocument(doc);
initDocument(doc, sc);// 文章の追加しています。
changeStyle(doc);// 文章のスタイル変更しています。

// サーブレットのパス
String path = "http://localhost:8080/misc/servlet/RTFDocumentServer";
URL u = new URL(path);

URLConnection connect = u.openConnection();// サーブレットとの回線を開きます。
connect.setDoOutput(true);

// 出力ストリームを取得
OutputStream out = connect.getOutputStream();
out.write("msg=".getBytes());
RTFEditorKit rtfEditor = new RTFEditorKit();
rtfEditor.write(out, doc, 0, doc.getLength());
out.flush();
out.close();

// 入力ストリームを取得
BufferedReader in = new BufferedReader(new InputStreamReader(
connect.getInputStream()));

// 一行ずつ読み込みます
String line;
while ((line = in.readLine()) != null) {
// 表示します
System.out.println(line);
}
// 入力ストリームを閉じます
in.close();

} catch (Exception e) {
e.printStackTrace();
}
}

private void initDocument(DefaultStyledDocument doc, StyleContext sc) {
StringBuffer sb = new StringBuffer();
sb.append("スタイル付きのテキストサンプルです。\n");
sb.append("スタイルを変えて表示しています。");

try {
/* 文書を挿入する */
doc.insertString(0, new String(sb), sc
.getStyle(StyleContext.DEFAULT_STYLE));
} catch (BadLocationException ble) {
System.err.println("初期文書の読み込みに失敗しました。");
}
}

private void changeStyle(DefaultStyledDocument doc) {
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setBold(attr, true);

/* 4文字目から8文字分だけスタイルを変更する */
doc.setCharacterAttributes(4, 8, attr, false);
}

public static void main(String[] args) {
RTFDocumentServerClientTest test = new RTFDocumentServerClientTest();

test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setVisible(true);
}
}
続き

//サーブレット
package servlet;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.StyleContext;
import javax.swing.text.rtf.RTFEditorKit;

public class RTFDocumentServer extends HttpServlet {

private static final long serialVersionUID = 6436536878215143916L;

@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {

String msg = request.getParameter("msg");

ServletContext application = this.getServletContext();
StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

ByteArrayInputStream input = new ByteArrayInputStream(msg.getBytes());
RTFEditorKit rtfEditor = new RTFEditorKit();
FileOutputStream out = new FileOutputStream(application
.getRealPath("/WEB-INF/test.rtf"));

try {
rtfEditor.read(input, doc, 0);
rtfEditor.write(out, doc, 0, doc.getLength());
} catch (BadLocationException e) {
e.printStackTrace();
}

input.close();
out.close();

}
}


//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>misc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>RTFDocumentServer</servlet-name>
<servlet-class>servlet.RTFDocumentServer</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>RTFDocumentServer</servlet-name>
<url-pattern>/servlet/RTFDocumentServer</url-pattern>
</servlet-mapping>

</web-app>
ええと、しずやさんの方法でうまくいかなかったと考えられる理由は

1.サーブレットにPOST(またはGET。ですが文字数制限があります)でデータを投げていなかった。

2.サーブレットからのレスポンスを受信していなかった。

の二つだと思います。

さて、そちらでもうまく動くといいのですが、、、
Applet試してみましたが、やはりダメなようです。
ローカルホストだからダメなんだという可能性も考えられますが、たぶん他のサーバでも無理でしょう。


java.security.AccessControlException: access denied (java.net.SocketPermission localhost:8080 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at client.RTFDocumentServerClientApplet.init(RTFDocumentServerClientApplet.java:53)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)


あまり良い情報源が見つからなかったのですが、
http://java-house.jp/ml/archive/j-h-b/036104.html
Javaアプレットでは、コードベースの異なるネットワークに
接続することは出来ない。とのことです。
#6

ローカルだからダメなのではなく、
アプレットのダウンロード元と同一のサーバでないと、
セキュリティマネージャがはじきます。
しずやです。
試行錯誤の結果、なんとかアプレットでの保存ができました。
そのほか多くのコメントありがとうございました。
また、しのぶ様にはソースまで公開していただき
非常に参考になりました。ありがとうございました。
アプレット版でソースを公開させていただきます。
このソースはしのぶ様のコメントを参考に完成しました。
本当に深く感謝いたします。

では、アプレットから

********************************************************
import java.awt.Container;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.JApplet;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.rtf.RTFEditorKit;

public class TestRTFApplet extends JApplet{

/**
*
*/
private static final long serialVersionUID = 1L;
public void init(){
String Rtfsavepath = getCodeBase() + "TestRTFServlet";

JTextPane textPane = new JTextPane();
JScrollPane scroll = new JScrollPane(textPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBounds(10, 60, 300, 100);
StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

textPane.setDocument(doc);

initDocument(doc,sc);
changeStyle(doc);
URL u = null;
try {
u = new URL(Rtfsavepath);
} catch (MalformedURLException e1) {
// TODO 自動生成された catch ブロック
e1.printStackTrace();
}

URLConnection connect = null;

try {

connect = u.openConnection();

connect.setDoOutput(true);
connect.setDoInput(true);

OutputStream out = connect.getOutputStream();
RTFEditorKit rtfEditor = new RTFEditorKit();
rtfEditor.write(out,doc, 0, doc.getLength());
out.flush();
out.close();

InputStreamReader inreader = new InputStreamReader(connect.getInputStream());
BufferedReader reader = new BufferedReader(inreader);
String msg = reader.readLine();
System.out.println(msg);

} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (BadLocationException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}

Container contentPane = getContentPane();
contentPane.add(scroll);
}
protected void initDocument(DefaultStyledDocument doc, StyleContext sc){
StringBuffer sb = new StringBuffer();
sb.append("スタイル付きのテキストサンプルです。\n");
sb.append("スタイルを変えて表示しています。");

try{
/* 文書を挿入する */
doc.insertString(0, new String(sb),
sc.getStyle(StyleContext.DEFAULT_STYLE));
}catch (BadLocationException ble){
System.err.println("初期文書の読み込みに失敗しました。");
}
}

protected void changeStyle(DefaultStyledDocument doc){
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setBold(attr, true);

/* 4文字目から8文字分だけスタイルを変更する */
doc.setCharacterAttributes(4, 8, attr, false);
}
}

続き、サーブレットです。


****************************************************************


import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.StyleContext;
import javax.swing.text.rtf.RTFEditorKit;

/**
* Servlet implementation class for Servlet: TestRTFServlet
*
*/
public class TestRTFServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;

/* (non-Java-doc)
* @see javax.servlet.http.HttpServlet#HttpServlet()
*/
public TestRTFServlet() {
super();
}

/* (non-Java-doc)
* @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
// ContentTypeを設定
response.setContentType("text/html; charset=UTF-8");
// 出力用PrintWriterを取得
PrintWriter out = response.getWriter();
// 出力
out.println("<html>");
out.println("<head>");
out.println("<title></title>");
out.println("</head>");
out.println("<body>");
out.println("<APPLET CODE=\"TestRTFApplet.class\" ARCHIVE=\"testRTFApplet.jar\" WIDTH=\"300\" HEIGHT=\"100\" ></APPLET>");
out.println("</body>");
out.println("</html>");

}

/* (non-Java-doc)
* @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
ServletContext application = this.getServletContext();
StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);

LinkedList<Byte> list = new LinkedList<Byte>();
byte b;

ServletInputStream input = request.getInputStream();
while((b = (byte)input.read()) != -1){
list.add(b);
}

System.out.println("size = "+list.size());//デバッグ

byte text[] = new byte[list.size()];
Iterator<Byte> iterator = list.iterator();
int i=0;
while(iterator.hasNext()){
text[i++]=(Byte)iterator.next();
}
ByteArrayInputStream in = new ByteArrayInputStream(text);
RTFEditorKit rtfEditor = new RTFEditorKit();
FileOutputStream out = new FileOutputStream(application.getRealPath("/WEB-INF/test.rtf"));

try {
rtfEditor.read(in, doc, 0);
rtfEditor.write(out, doc, 0, doc.getLength());
} catch (BadLocationException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}

input.close();
out.close();

ServletOutputStream output = response.getOutputStream();
OutputStreamWriter outwriter = new OutputStreamWriter(output);
BufferedWriter writer = new BufferedWriter(outwriter);
writer.write("ok");
writer.flush();
}
}
補足。

サーブレットのパスは
http://localhost:8080/TestRTFServlet/TestRTFServlet

となります。
アプレットは、WebContentの下に(Eclipseではですが・・)
jarファイルで設置しております。

以上。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Java質問&情報提供サイト 更新情報

Java質問&情報提供サイトのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング