blog.Ring.idv.tw

Servlet

Apache Tomcat 8 + SQLite

很長一段時間沒有更新該Blog了,由於最近為了做一些side project,所以打算在Mac筆電上架個簡單的開發環境,初步就想說直接利用SQLite來當做資料庫,反正只要中間層的DAO設計好,未來要改個後端也不是什麼太大的負擔,所以更不需要動到HBase之類的儲存方案。所以本文就純粹當作Memo...

必要軟體

.Apache Tomcat 8.5.43

為什麼選擇Tomcat 8的理由是,由於筆電的Java版本為Java 7,加上沒有急著升級的必要,所以就維持著...

至於SQLite的話,直接下載SQLite JDBC Driver即可,目前最新版本為sqlite-jdbc-3.27.2.1.jar

接下來就一步步地做些必要的操作:

修改 /etc/hosts

127.0.0.1    helloworld

這步驟主要是用來方便在筆電端快速地來做測試而已,上述的【helloworld】你可以改成你任意喜歡的,之後要測試時就直接在網頁上輸入http://helloworld:8080即可。

建立必要的目錄及檔案

$TOMCAT_HOME/helloworld/ROOT

$TOMCAT_HOME/helloworld/ROOT/index.jsp

上述index.jsp檔案裡任意寫個Hello JSP之類的文字即可。

修改 $TOMCAT_HOME/conf/server.xml

<Host name="helloworld"  appBase="helloworld"  unpackWARs="true" autoDeploy="true">
	     <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="helloworld_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
</Host>

啟動Tomcat

在啟動之前,如果你也是在Unix-like系統下安裝的話,那你可以考慮刪除掉$TOMCAT_HOME/bin/目錄底下的所有.bat檔案,這樣在透過Tab鍵補字操作下會方便些。

$TOMCAT_HOME/bin/startup.sh

接著在網頁上輸入http://helloworld:8080,應該就可以work了,接下來處理SQLite資料庫的部份。

建立必要的目錄及檔案

$TOMCAT_HOME/helloworld/ROOT/META-INF/context.xml

$TOMCAT_HOME/helloworld/ROOT/WEB-INF/classes

$TOMCAT_HOME/helloworld/ROOT/WEB-INF/lib

P.S. 請將sqlite-jdbc-3.27.2.1.jar直接copy到$TOMCAT_HOME/helloworld/ROOT/WEB-INF/lib/目錄下,至於其它目錄及檔案,待會再說明。

修改 META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/helloworld" auth="Container" type="javax.sql.DataSource" driverClassName="org.sqlite.JDBC"
            url="jdbc:sqlite:/Users/yourname/apache-tomcat-8.5.43/helloworld/ROOT/helloworld.db"
            factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory">
  </Resource>
</Context>

上述的【url】用來設定SQLite的檔案位置,接著會透過下面的Servlet程式來操作該資料庫。

建立一個 Servlet 程式

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.*;
import java.sql.*;

@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html; charset=utf-8");
		
		PrintWriter out = resp.getWriter();
		Connection con = null;
		ResultSet rs = null;
		PreparedStatement ps = null;

		try
		{
			Context ctx = new InitialContext();
			DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/helloworld");
			con =  ds.getConnection();

			Statement stat = con.createStatement();
			stat.executeUpdate("drop table if exists member;");
			stat.executeUpdate("create table member (id, name);");
			ps = con.prepareStatement("insert into member values (?, ?);");

			ps.setInt(1, 1);
			ps.setString(2, "Tony Lee");
			ps.addBatch();
			ps.setInt(1, 2);
			ps.setString(2, "Jack Wang");
			ps.addBatch();
			ps.executeBatch();


			rs = stat.executeQuery("select * from member;");
			while (rs.next()) {
				out.println("ID=" + rs.getInt("id")+"<br/>");
				out.println("Name=" + rs.getString("name")+"<br/>");
			}

		}catch (SQLException e)
		{
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		} finally {
			out.flush();
			out.close();

			try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
			try { ps.close(); } catch (SQLException e) { e.printStackTrace(); }
			try { con.close(); } catch (SQLException e) { e.printStackTrace(); }
		}
	}
}

最後將上述程式編譯後,將HelloServlet.class檔案copy至$TOMCAT_HOME/helloworld/ROOT/WEB-INF/classes/目錄下。

重新啟動Tomcat,輸入網址http://helloworld:8080/HelloServlet就可以看到下述結果:

ID=1
Name=Tony Lee
ID=2
Name=Jack Wang

2019-07-24 19:49:43 | Add Comment

Jetty - Java HTTP Servlet Server

.2008-12-15 新增Apache Commons DBCP範例

大約六、七年前剛開始初學Web Application的時候~ 那時常聽到的是TomcatResin~ 至於Jetty... 嗯~ 我聞不見其名...XD

Jetty.是一個100%以Java撰寫而成並開放源碼的HTTP Server & Servlet Container~ 從三年前的「Jetty vs. Tomcat vs. Resin: A Performance Comparison」這篇文章來看~ 它的效率似乎表現不錯~ 好了~ 回歸重點~ 為什麼我對它燃起了興趣?... 二個原因,其一,到目前Hadoop 0.19.0版所內建的Servlet Container就是採用Jetty 5.1.4~ 不過根據「(#HADOOP-1650) Upgrade Jetty to 6.x - ASF JIRA」這個issue來看~ 0.20版就會變成Jetty 6.x版了~

另一個原因,由於今年年初有協助老師將一個「English Collocations」的雛型系統改寫成Web版~ 而這樣的系統其實只需要「唯讀」資料庫的內容即可~ 想將整個這樣的系統都做成「DVD-ROM」版本~ 這樣就變成可以帶著跑的Web Application了~ 方便性大大的提高~ 所以Jetty相當適合這樣的應用!!

下面簡單地記錄一下一些常用的設定及步驟:

啟動Jetty Sever

java -jar start.jar etc/jetty.xml

手動增加一個新的Web Application (含VirualHost設定)

請修改「/etc/jetty.xml」。

<New class="org.mortbay.jetty.webapp.WebAppContext">
	<Arg><Ref id="Contexts"/></Arg>
	<Arg><SystemProperty name="jetty.home"/>/webapps/webapp</Arg>
	<Arg>/webapp</Arg>
	<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
	<Set name="VirtualHosts">
	<Array type="java.lang.String">
		<Item>localhost</Item>
	</Array>
	</Set>
</New>

測試Servlet - Hello World

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Test extends HttpServlet
{
	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
	{
		res.setContentType("text/html");
		PrintWriter out = res.getWriter();
		out.println("<html>");
		out.println("<head><title>Hello</title></head>");
		out.println("<body>");
		out.println("HIHI");
		out.println("</body>");
		out.println("</html>");
	}
}

修改「web.xml」

<servlet>
	<servlet-name>Hello</servlet-name>
	<servlet-class>Test</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>Hello</servlet-name>
	<url-pattern>/Hello.do</url-pattern>
</servlet-mapping>

最後開啟「http://localhost:8080/webapp/Hello.do」即可。

PostgreSQL - ConnectionPoolDataSource

請修改「/etc/jetty.xml」。

<New id="DSTest" class="org.mortbay.jetty.plus.naming.Resource">
	<Arg>jdbc/DSTest</Arg>
	<Arg>
	<New class="org.postgresql.ds.PGConnectionPoolDataSource">
		<Set name="User">postgres</Set>
		<Set name="Password">xxx</Set>
		<Set name="DatabaseName">test</Set>
		<Set name="ServerName">localhost</Set>
		<Set name="PortNumber">5432</Set>
	</New>
	</Arg>
</New>

修改「web.xml」。

<resource-ref>
	<description>My DataSource Reference</description>
	<res-ref-name>jdbc/DSTest</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

一個簡單的測試程式如下:

import java.io.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class PostgresDBTest extends HttpServlet
{
	public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
	{
		res.setContentType("text/html");
		PrintWriter out = res.getWriter();
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		try
		{
			ConnectionPoolDataSource source = (ConnectionPoolDataSource)new InitialContext().lookup("jdbc/DSTest");
    			con = source.getPooledConnection().getConnection();  
    			stmt = con.createStatement();
    			rs = stmt.executeQuery("select * from test");
    			while(rs.next())
    			{
    				out.println("Title:"+rs.getString(1)+"<br/>");
    			}
		} catch(Exception e){
    			e.printStackTrace();
		} finally {
    			if(con != null)
    			{
        			try {
       	 				con.close();
        			}catch(SQLException e)
        			{
        				e.printStackTrace();
        			}

    			}
		}		
	}	
}

修改「web.xml」。

<servlet>
	<servlet-name>PostgresDBTest</servlet-name>
	<servlet-class>PostgresDBTest</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>PostgresDBTest</servlet-name>
	<url-pattern>/PostgresDBTest.do</url-pattern>
</servlet-mapping>

最後開啟「http://localhost:8080/webapp/PostgresDBTest.do」即可。

Apache Commons DBCP - PostgreSQL

下載下述這三個Library,並複製到「Jetty_Home/lib」底下。

commons-dbcp.jar

commons-pool.jar

commons-collections.jar

請修改「/etc/jetty.xml」。

<New id="pgsqldbcp" class="org.mortbay.jetty.plus.naming.Resource">
	<Arg>jdbc/Blog</Arg>
	<Arg>
	<New class="org.apache.commons.dbcp.BasicDataSource">
	<Set name="driverClassName">org.postgresql.Driver</Set>
	<Set name="url">jdbc:postgresql://localhost/Blog</Set>
	<Set name="username">postgres</Set>
	<Set name="password">1234</Set>
	<Set name="maxActive">10</Set>
	</New>
	</Arg>
</New>

修改「web.xml」。

<resource-ref>
	<description>My DataSource Reference</description>
	<res-ref-name>jdbc/DSTest</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

測試程式如下:

import java.io.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class PostgresDBTest extends HttpServlet
{
	public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
	{
		res.setContentType("text/html");
		PrintWriter out = res.getWriter();
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		try
		{
			InitialContext ic = new InitialContext();
			DataSource source = (DataSource)ic.lookup("jdbc/Blog");
			con = source.getConnection();  
			stmt = con.createStatement();
			rs = stmt.executeQuery("select * from test");
			while(rs.next())
			{
    				out.println("Title:"+rs.getString(1)+"<br/>");
			}
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			if(con != null)
			{
				try {
					con.close();
				}catch(SQLException e)
				{
					e.printStackTrace();
				}
			}
		}
	}		
}

2008-12-07 21:36:29 | Comments (5)

Flash Webcam 線上拍照存檔!~

.2008/12/10 新增範例下載

今天試著用Flash CS3寫一個Flash Webcam 線上拍照存檔的範例~

大致上分成兩部份來處理~一部份為Flash的前端,用來截取Webcam的畫面並將它存進BitmapData中,以供透過URLRequest來上傳處理~

而這部份比較關鍵的是,我們利用「as3corelib」所提供的「JPGEncoder」來進行壓縮,以增進傳送速度~

想當然而,後端就是直接將它讀出並存進一個影像檔即可。

程式碼如下所示:

ActionScript 3

import com.adobe.images.JPGEncoder;

var camera:Camera = Camera.getCamera("0");
camera.setMode(320,240,30);
var video = new Video(320, 240);
video.attachCamera(camera);
stage.addChild(video);
stage.addEventListener(MouseEvent.MOUSE_DOWN,clickHandler);
function clickHandler(event:MouseEvent)
{
	var bd:BitmapData = new BitmapData(320, 240);
	bd.draw(video);
	var encoder:JPGEncoder = new JPGEncoder(100);
	var bytes:ByteArray = encoder.encode(bd);
	var req:URLRequest = new URLRequest("http://localhost/WebCamHandler.as3");
	req.data = bytes;
	req.method = URLRequestMethod.POST;
	req.contentType = "application/octet-stream";
	var loader:URLLoader = new URLLoader();			
	loader.addEventListener(Event.COMPLETE, completeHandler);
	loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
	loader.load(req);
}
function completeHandler(event:Event):void
{
	trace("上傳成功");
}
function errorHandler(event:IOErrorEvent):void
{
	trace("上傳失敗");
}

Servlet

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

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;

public class WebCamHandler extends HttpServlet
{
    private String base;
    
    public void init(ServletConfig sc) throws ServletException
    {
        ServletContext sco = sc.getServletContext();
        base = sco.getRealPath("/");
    }
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {   
        int readed;
        try
        {
            String filePath = base+new Date().getTime()+".jpg";
            BufferedInputStream bis = new BufferedInputStream(req.getInputStream());
            FileOutputStream fos = new FileOutputStream(new File(filePath));
            byte[] bytes = new byte[2048];
            while((readed=bis.read(bytes)) != -1)
            {
                fos.write(bytes, 0, readed);
            }
            fos.close();
            bis.close();
            
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

範例下載

WebCamHandler(CS4、Webapp)

2007-08-19 15:19:20 | Comments (17)

檔案上傳-「commons fileUpload」

一般我們常見的HTML輸入型態(例如:text、radio、select…)都是使用「application/x-www-form-urlencoded」的編碼方式,但要傳送檔案至伺服端時,編碼方式則是要仰賴「multipart/form-data」,由於兩者的編碼方式不同,所以這裡提供一個「FileUpload」的小範例~

必要的package如下:

commons fileUpload

commons IO

HTML

<%@page language="java" contentType="text/html;charset=utf-8"%>
<html>
<head>
<title>檔案上傳</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<b>檔案上傳</b></font></p>
<form name="UploadForm" enctype="multipart/form-data" method="post" action="fileupload.dan">
    <input type="file" name="File1" size="20" maxlength="20"> <br>
    <input type="text" name="File2" size="20" maxlength="20"> <br>
    <input type="submit"value="上傳">
</form>
</body>
</html>

Servlet

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
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.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class FileUpload extends HttpServlet
{
    private String base;
    
    public void init(ServletConfig sc) throws ServletException
    {
        ServletContext sco = sc.getServletContext();
        base = sco.getRealPath("/");
    }
    
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {   
        boolean isMultipart = ServletFileUpload.isMultipartContent(req);
        try
        {
            if(isMultipart)
            {
                DiskFileItemFactory factory = new DiskFileItemFactory();
                factory.setSizeThreshold(4096);
                factory.setRepository(new File(base+"temp"));
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setSizeMax(10000000);
                List items = upload.parseRequest(req);
                Iterator iter = items.iterator();
                while(iter.hasNext())
                {
                    FileItem item = (FileItem) iter.next();
                    if (item.isFormField())
                    {
                        String name = item.getFieldName();
                        String value = item.getString();
                        System.out.println("name:"+name+" value:"+value);
                    } else {
                        String fieldName = item.getFieldName();
                        String fileName = item.getName();
                        String contentType = item.getContentType();
                        boolean isInMemory = item.isInMemory();
                        long sizeInBytes = item.getSize();
                        System.out.println("fieldName:"+fieldName+" fileName:"+fileName);
                        File to = new File(base+"upload",fileName);
                        item.write(to);
                    }
                }
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

2007-08-10 14:52:00 | Comments (2)

Copyright (C) Ching-Shen Chen. All rights reserved.

::: 搜尋 :::

::: 分類 :::

::: 最新文章 :::

::: 最新回應 :::

::: 訂閱 :::

Atom feed
Atom Comment