GeoPicPlugin

Abstract#

以下にGeoPicPlugin開発時のお恥ずかしい苦労話などを記録します。

Topic#

やりたいこと:#

  • フォームに入っているテキストをもとにページを作成し、ファイルを添付する。
  • JSPWikiのライブラリを最大限活用
  • web.xmlはいじりたくない。つまりできるだけJSPWikiから独立に開発を進めたい。
  • Tomcat8.5でも動かしたい。(コンテンツ分けるか)

記録#

  • JSP or Servlet
やりたいことをやるには、JSPかServletか
HttpServletRequestでフォームの情報は引き出せそう。JSPからは使える?サーブレットから渡してやる感じか。つまり少なくともサーブレットは作らないとか。
Pluginの中にサーブレットクラスって入れられる?JSPWIKIでの例はなさそうなので、やってみるしかないか。→[1]の方法でできた!割と簡単。WEB.XML編集しなくてもできるんだ。Servlet3.0, Tomcat8から対応とのこと。
  • つぎは、Formの使い方か
[2]を参照して実施。
FormタグでAction属性に、動かしたいURLを指定
Formタグで囲われた中にInput type="Submit"を。
Buttonは、TypeもButtonとしておかないと、Type=submitと同じ動きをする。
Formにenctype="multipart/form-data" を設定する必要がある。
  • GetとPostの違いを確認
Getは主にサーバからクライアントが情報を取るとき。
Postは、サーバに情報をアップデートするとき。
  • ServletのなかでWikiEngine呼び出せるかな。
AttacheServletが参考になる。最初に必ず
org.apache.wiki.InternalWikiException: No wiki engine, check logs.
	org.apache.wiki.WikiEngine.getInstance(WikiEngine.java:377)
	org.apache.wiki.WikiEngine.getInstance(WikiEngine.java:316)
	org.braincopy.jspwiki.plugin.TestServlet.init(TestServlet.java:28)
これは、WikiEngine.getInstance()をやるときにWeb.xmlを見に行こうとするから一回目は出るらしい。

JSPWikiのUpload.jspをみると、JSP側でもWikiEngine.getInstance()を呼び出している。このあたりの違いか。要確認。
JSP側の処理で上記以外もある。PluginからcontextをServletに渡すことは可能か?
Access権関係なんかあるのかな。
どうも新しいページを作れない。
WikiEngineオブジェクトがおかしいのか。saveTextが使われるはず。→ん?呼ばれない?Contextがページと結びついているはず。SaveTextが呼ばれた瞬間にPageは作られているか?
AttacheServletにディスパッチしてForwardしよう!
もうJSPからつくるつもりにならないとだめか。。。
まずは、WikiEngineがちゃんと作られていないというエラーを対処する方向で。
org.apache.wiki.WikiEngine@1d6c9a6
./temp/personal: org.apache.wiki.WikiEngine@1d6c9a6
org.apache.wiki.WikiEngine@1bf1ec2
org.apache.wiki.WikiEngine@1bf1ec2
新しいWikiEngineが作られている。自然ではない。
ServletContextの中にWikiEngineが保存されていない?
AttacheServletのInitから呼ばれているgetInstanceでは、そこは保存されているようで、
        WikiEngine engine = (WikiEngine) context.getAttribute( ATTR_WIKIENGINE );
でえられていた。
でもgetInstance()の中で、setAttributeもやっている。どういうことだ。
参照しているServletContextが違うオブジェクト?
org.apache.catalina.core.ApplicationContextFacade@12bc773
org.apache.catalina.core.ApplicationContextFacade@1c81301
うーん、違う。このContextの中だと保存されていない。。。gpuploadがPersonalの配下にいない。。。
form でactionを指定するときに"/gpupload"だとhostname/gpuploadになってしまう。actionを"gpupload"にすると狙い通りhostname/appname/gpuploadになる。これでWikiEngineは、ちゃんと作れるようになった。
  • さて、あとは新しいページをどう作るかだ。
WikiPageオブジェクトをnewで作ればいいだけだった。。。
  • さて、フォワードしよう。どうするかな。
フォワードしたさきの
upload.parseRequest( req );
でうまくITEMが取れていない。一回とっちゃうとダメなんじゃ。うん、2回parseRequestはできないっぽい。
選択肢は、AttacheServletの内容をコピーする。でもあまりやりたくない。AttacheServletを継承できるかな。→AttacheServletを継承し、privateで見えないメンバ変数とメソッドを再度定義しつつ、uploadメソッドをオーバーライド。

記録2(Tomcat8.5対応)#

  • まずは何が動いていないか確認したい。
  • /gpuploadが呼び出されたら何が動くのか?init()かupload()だろうね。
やばい。自分で緯度経度を指定する場合、普通に動いた。EXIFを使う場合だけ、へんなエラーが出るのかもしれない。
executeUpload(context, in, filename, nextPage, wikipage, changeNote, fileSize);で何か起きてる。
実はUseEXIF関係ない。ファイルサイズ制限のエラー処理ができていない。たぶん今設定で4Mまでにしているところ8Mをアップしようとしたから落ちたのだろう。エラーメッセージがおかしいのも問題だが、やはり適切なサイズでアップするようなプログラムにしたい。
executeUpload()のオーバライドに挑戦。もはやAttachmentServletを継承している意味がなくなりつつあるが。その中でAttacheManager.validateFileName()がis not visibleとでる。AttachmentManagerはpublicクラスだし、validateFileName()はstaticメソッドだし、見れないはずないのだが。コンパイルも通るし。なんでだろう。staticメソッドはpublic指定されていないと使えない。何も書かないとprotectedよりきつい[3]。ということで権限のないメソッドはコピーしてくる。
相変わらず、ファイルサイズ制御のエラーは、ちゃんとエラー処理できていない。org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededExceptionをちゃんと受け止め切れていない。まあ、その前にファイルサイズを落とすことを考えよう

Reference#

  1. [#1]http://www.javaroad.jp/servletjsp/sj_servlet14.htm
  2. [#2]http://www.tagindex.com/html_tag/form/input_submit.html
  3. [#3]https://www.sejuku.net/blog/22679