WEBフレームワークの中心的クラスのhtmlSrvを拡張しています。
主な拡張点は、
- Cookieによるセッション管理機能
- 認証機能
- ページ割り込み機能
リダイレクションとフォワードによって、別ページを割り込ませます。
この機能によって、ログイン画面や、成人ですかという画面を割り込ませることができます。
設定は、TOMCATのWEB.XMLによって設定情報を定義するので、
この定義情報を取り出すためのコードがかなりのボリュームを持っています。
それと、HTMLパーサの呼び出しに引数を1つ追加し、PrintWriterを渡しています。
従来のコードでは、いったん1ページ分のデータをStringに格納してから
Outputしていましたが、読み込み次第、出力することができます。
大きなページでは反応がよくなります。
まだ、拡張し続けているの参考まで。
package ews.servlet import org.apache.log4j.Logger import java.io._ import java.net.{URLDecoder,URLEncoder} import javax.servlet._ import javax.servlet.http._ import ews.servlet.sp._ import ews.servlet.session._ /** * The dynamic page is made by HttpServlet. */ class htmlSrv extends HttpServlet { lazy val logger = Logger.getLogger(classOf[ewsSrv]) var context : ServletContext = null var DocumentRoot : String = null // DocumentRoot var loginUrl : String = null // Login画面のURL var checkUrl : String = null // Cookie設定画面のURL var registrationUrl : String = null // 登録画面のURL var registrationPath : String = null // 登録が必要なコンテンツが格納されるディレクトリ (このバージョンでは1つしか指定できない) var authPath : String = null // 認証が必要なコンテンツが格納されるディレクトリ (このバージョンでは1つしか指定できない) var checkCookie : String = null // チェック画面を表示させる場合にセットされるCookieの名称 var registrationCookie : String = null // 登録画面を表示させる場合にセットされるCookieの名称 var message = "Not Found :The requested URL was not found on this server." // Not Found var characode = "utf-8" override def init(config : ServletConfig) : Unit = { super.init(config) context = config.getServletContext DocumentRoot = config.getInitParameter("html") // WEB-INF/web.xml loginUrl = config.getInitParameter("login") // WEB-INF/web.xml if(loginUrl == null) loginUrl = "/toro/login" checkUrl = config.getInitParameter("check") // WEB-INF/web.xml if(checkUrl != null && checkUrl.length == 0) checkUrl = null registrationUrl = config.getInitParameter("registration") // WEB-INF/web.xml if(registrationUrl != null && registrationUrl.length == 0) registrationUrl = null registrationPath = config.getInitParameter("registrationpath") // WEB-INF/web.xml if(registrationPath != null && registrationPath.length == 0) registrationPath = null authPath = config.getInitParameter("authpath") // WEB-INF/web.xml if(authPath != null && authPath.length == 0) authPath = null checkCookie = config.getInitParameter("checkcookie") // WEB-INF/web.xml if(checkCookie != null && checkCookie.length == 0) checkCookie = null registrationCookie = config.getInitParameter("registrationcookie") // WEB-INF/web.xml if(registrationCookie != null && registrationCookie.length == 0) registrationCookie = null } override def doGet(request : HttpServletRequest, response : HttpServletResponse) : Unit = { gen(request, response) } override def doPost(request : HttpServletRequest, response : HttpServletResponse) : Unit = { gen(request, response) } // generate HTML def gen(request : HttpServletRequest, response : HttpServletResponse) : Unit = { logger.debug("htmlSrv ################# start") var htmlFile = "" var parsersw = if(request.getParameter("parsersw") !=null){request.getParameter("parsersw").toInt}else{0} // 強制的にHTMLパーサを切り替える request.setCharacterEncoding(characode) val url = request.getRequestURL val uri = request.getRequestURI var spth:String = request.getServletPath // URLからパラメータ情報を取り出す spth = spth.replace("/","") val ur = uri.split("/") var fg = false ur.foreach({v => if(fg){ htmlFile += "/" + v } if(v.equals(spth)) fg = true }) val contentFilePath = DocumentRoot + htmlFile // コンテンツのファイルフルパス var ct = ContentTypeDef.changeFromFileNameToContentType(htmlFile) val sw = ContentTypeDef.getCtype(ct) match { case "text" => { if(htmlFile.lastIndexOf(".html") > 0 || htmlFile.lastIndexOf(".htm") > 0){ val session = new Session(request,response) // Cookie if(checkUrl != null // URLが定義されているか? && checkCookie != null // クッキーが定義されているか? && checkUrl.lastIndexOf(htmlFile) == -1 // チェック用のURLの場合はフォワードさせない && session.getAttribute(checkCookie) == null){// 特定のクッキーが値の有無によって制御したい場合 println("Cookie oc none checkUrl="+checkUrl + " htmlFile=" + htmlFile + " " + checkUrl.lastIndexOf(htmlFile)) // for test session.cookie.setCookie(checkCookie,java.lang.Math.random.toString ,-1) val rd = context.getRequestDispatcher(checkUrl) rd.forward(request, response) return } else { println("checkUrl is null & Cookie oc="+session.getAttribute(checkCookie)) } if(registrationCookie != null // クッキーが定義されているか? && registrationUrl != null // URLが定義されているか? && registrationUrl.lastIndexOf(htmlFile) == -1 // 登録用のURLの場合はフォワードさせない && session.getAttribute(registrationCookie) == null // 特定のクッキーが値の有無によって制御したい場合 && registrationPath != null && registrationPath.equals(getPath(htmlFile))){ // 指定されたパスが登録が必要なディレクトリか? println("registrationCookie & htmlFile="+htmlFile) val rd = context.getRequestDispatcher(registrationUrl) rd.forward(request, response) return } if((authPath != null && authPath.equals(getPath(htmlFile))) || htaccess(htmlFile)){ // 指定されたパスが認証が必要なディレクトリか? if(!session.isLogin){ // 認証がされているか? println("htmlSrv ############ Longin画面を表示 -> loginUrl=" + loginUrl+"?url=" + URLEncoder.encode(uri.toString)) logger.debug("htmlSrv ############ Longin画面を表示 -> loginUrl=" + loginUrl+"?url=" + URLEncoder.encode(uri.toString)) response.sendRedirect(loginUrl+"?uri=" + URLEncoder.encode(uri.toString)) val out = response.getWriter out.close return } } } if(ct.equals("text/html")){parsersw}else{11} } case "image" => 10 case "application" => if(ct.equals("application/xml")){2}else{10} case "audio" => 10 case "video" => 10 case _ => 10 } logger.debug("htmlSrv ############ "+ct+" ##### htmlFile="+htmlFile) println("htmlSrv ############ "+ct+" ##### htmlFile="+htmlFile) if(sw == 0){ ct += "; charset=" + characode response.setContentType(ct) val sp = new Htmlparse6Sp(request, response, contentFilePath)// Dynamic page. use the org.htmlparser.sax._ val r = sp.io println("htmlSrv sw=0 Htmlparse6Sp r="+r+ " " + contentFilePath) if(!r){ System.err.println("Not Found the "+htmlFile) error(404,"Not Found "+htmlFile,response) } } else if(sw == 11){ ct += "; charset=" + characode response.setContentType(ct) val sp = new TextSp(request, response, contentFilePath) sp.characode = characode val r = sp.io if(!r){ System.err.println("Not Found the "+htmlFile) error(404,"Not Found "+htmlFile,response) } } else if(sw < 10){ // HTMLパーサ評価用 val ssp = sw match { // It reads a file, and the content is output as it is. case 1 => new StraightSp(request, response, contentFilePath) // The HTML file is read by the Scala XML loader. The character string is converted and XML is output. case 2 => new XmlSp(request, response, contentFilePath) // The analytical result of HTML parser is converted in the character string and it outputs it. case 3 => new Htmlparse2Sp(request, response, contentFilePath)// javax.swing.text.html.parser._ case 4 => new HtmlparseSp(request, response, contentFilePath) // nu.validator.htmlparser._ for TEST case 5 => new ValidatorHtmlparserSp(request, response, contentFilePath) // nu.validator.htmlparser for TEST case 6 => new Htmlparse3Sp(request, response, contentFilePath)// org.cyberneko.html.parsers._ for TEST case 7 => new Htmlparse4Sp(request, response, contentFilePath)// org.htmlparser.sax._ for TEST case 8 => new Ssp(request, response, contentFilePath) // Dynamic page. use the nu.validator.htmlparser case 9 => new Htmlparse5Sp(request, response, contentFilePath)// Dynamic page. use the org.htmlparser.sax._ } val re = if(ssp.html != null){ response.setStatus(200) ssp.toString } else { error(404,"Not Found "+htmlFile,response) return } ct += "; charset=" + characode response.setContentType(ct) val out = response.getWriter out.println(re) // output html data out.flush out.close } else { var stream:FileInputStream = null try { val binaryFile = new java.io.File(contentFilePath) if(binaryFile.exists){ response.setContentType(ct) response.setStatus(200) stream = new FileInputStream(binaryFile) val buf:Array[Byte] = new Array(1024) var out = response.getOutputStream while(stream.available != 0){ val i = stream.read(buf,0,1024) out.write(buf,0,i) } } else { System.err.println("Not Found the "+htmlFile) error(404,"Not Found "+htmlFile,response) } } catch { case e:IOException => { System.err.println("IOException "+e.getMessage) error(500,"Internal Server Error",response) } case e:Exception => { System.err.println("Exception "+e.getMessage) error(500,"Internal Server Error",response) } } finally { if(stream != null) stream.close } } // logger.debug(" #### End") } // for error def error(status:Int,message:String, response : HttpServletResponse) :Unit = { response.setContentType("text/html") response.setStatus(status,message) var out = response.getOutputStream out.close } // htaccessファイルがHTMLファイルが置かれているディレクトにあるかを調べる // このファイルがあればそのディレクトにあるコンテンツへのアクセスは認証が必要となる。 var htaccess = "htaccess.txt" def htaccess(fileName:String) : Boolean = { val point = fileName.lastIndexOf("/") if (point == -1) { return false } val htaccessPath = fileName.substring(0,point+1) val path = DocumentRoot + htaccessPath + htaccess try { val htmlFile = new java.io.File(path) return htmlFile.exists } catch { case e:IOException => { System.err.println("IOException "+e.getMessage) } } return false } // ファイル名からパスを取り出す def getPath(fileName:String) : String = { val point = fileName.lastIndexOf("/") if (point == -1) { return null } val htaccessPath = fileName.substring(0,point+1) return DocumentRoot + htaccessPath } }
コメントを残す
コメントを投稿するにはログインしてください。