問題の声明
comポートへの情報の読み取りと書き込みが可能なサイトからブラウザーによってロードされたJavaアプレットを作成する必要があります。 この場合の主な要件は、ユーザーにとっての使いやすさ、複雑な設定がないこと、そして可能であればユーザーのシステムに追加のライブラリまたはプログラムをインストールする必要があることです。
ユーザーコンピューターの要件:
1. Microsoft Windows XP、Vista、7
2. Javaアプレットをサポートする最新のブラウザ。IE、Firefoxが主な重点
3. JRE1.6をインストールしました。
JavaアプレットからCOMポートにアクセスするための利用可能なメソッドの概要
ご存知のように、標準JREにはCOMポートへのアクセスを許可するクラスやメソッドは含まれていません。 最も人気のある2つの外部ライブラリであるjavax.commとRXTXを見つけました 。 それらに関する情報を見た後、RXTXを使用することにしました。 javax.commは現在開発されていません。さらに、RXTXにはサポートされているオペレーティングシステムの範囲が広いため、将来役立つかもしれません。
両方のライブラリは、ネイティブライブラリを使用してCOMポートにアクセスします。 RXTXの場合、これはrxtxSerial.dllライブラリです。
COMポートを操作するための機能に関しては、両方のライブラリに同じクラスのセットがあります。
COMポートを操作するためのテストアプレット
アプレットのコードを提供します。これを「配布」します。 このアプレットは、当然私のプロジェクトで使用したものではなく、この記事専用に作成しました。 だから:
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
このコードは、システムで見つかったすべてのCOMポートのリストを表示するだけです(これにより、アプレットが再描画されるたびにこの操作が実行されます)。
RXTXライブラリーの追加
問題の声明に基づいて、ユーザーにとってアプレットをできるだけ単純にする必要があります。 また、アプレットとRXTXライブラリの両方を含む単一のjarファイルよりも簡単なものはありません。 ライブラリをjarに統合するには、まずソースコードをダウンロードします 。
srcフォルダーからダウンロードしたアーカイブで、すべての.javaファイルを取得してプロジェクトに追加します。 私のように、NetBeansを使用している場合は、プロジェクトのsrc-folderにgnu / ioディレクトリ構造を作成するだけで、そこに上記のファイルを配置します。
1つのアプレットでコンパイルした後、コードとRXTXライブラリはすぐにマージされます。
rxtxSerial.dllネイティブライブラリの追加
上記のように、RXTXはネイティブライブラリrxtxSerial.dllを使用して、WindowsのCOMポートにアクセスします。 このライブラリーは、 System.loadLibrary()メソッドを介してRXTXクラスとともにロードされます。
したがって、アプレットを機能させるには、rxtxSerial.dllライブラリをユーザーのコンピューター上、およびRXTXがロードできるディレクターの1つに配置する必要があります。 java.library.pathに登録されているディレクトリ内。 そのようなディレクトリの1つは、JREインストールフォルダ内のbinディレクトリです。
最も明白な方法は、指定されたディレクトリにrxtxSerial.dllライブラリを事前インストールすることですが、これにはユーザーからの追加のアクションが必要であるため(常に修飾されていない)、別のソリューションが適用されました。
dllライブラリを含む任意のファイルを、リソースとしてjarファイルに含めることができます。 NetBeansでこれを行うには、アプレットの.javaファイルがあるディレクトリにリソースフォルダを作成し、そこにrxtxSerial.dllを配置します。 しかし、今それを接続する方法は? ここで説明されている方法が助けになります。
説明されているメソッドを考えると、アプレットのソースコードは次のようになります。
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
static {
try {
System. out .println( "CardReader {}" );
/* Get DLL from JAR file */
URL res = CardReader. class .getResource( "resources/rxtxSerial.dll" );
InputStream is = res.openStream();
/* Define the destination file */
File dll = File.createTempFile( "rxtxSerial" , ".dll" );
/* Open the destination file */
FileOutputStream fos = new FileOutputStream(dll);
/* Copy the DLL fro the JAR to the filesystem */
byte [] array = new byte [1024];
for ( int i= is .read(array);
i!=-1;
i= is .read(array)
) {
fos.write(array,0,i);
}
/* Close all streams */
fos.close();
is .close();
/* Load the DLL from the filesystem */
System.load(dll.getAbsolutePath());
System. out .println( "CardReader loaded" );
}
catch (Throwable e)
{
e.printStackTrace();
}
}
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
static {
try {
System. out .println( "CardReader {}" );
/* Get DLL from JAR file */
URL res = CardReader. class .getResource( "resources/rxtxSerial.dll" );
InputStream is = res.openStream();
/* Define the destination file */
File dll = File.createTempFile( "rxtxSerial" , ".dll" );
/* Open the destination file */
FileOutputStream fos = new FileOutputStream(dll);
/* Copy the DLL fro the JAR to the filesystem */
byte [] array = new byte [1024];
for ( int i= is .read(array);
i!=-1;
i= is .read(array)
) {
fos.write(array,0,i);
}
/* Close all streams */
fos.close();
is .close();
/* Load the DLL from the filesystem */
System.load(dll.getAbsolutePath());
System. out .println( "CardReader loaded" );
}
catch (Throwable e)
{
e.printStackTrace();
}
}
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
package cardreaders;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.URL;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class CardReader extends Applet {
Graphics gg;
int pos;
static {
try {
System. out .println( "CardReader {}" );
/* Get DLL from JAR file */
URL res = CardReader. class .getResource( "resources/rxtxSerial.dll" );
InputStream is = res.openStream();
/* Define the destination file */
File dll = File.createTempFile( "rxtxSerial" , ".dll" );
/* Open the destination file */
FileOutputStream fos = new FileOutputStream(dll);
/* Copy the DLL fro the JAR to the filesystem */
byte [] array = new byte [1024];
for ( int i= is .read(array);
i!=-1;
i= is .read(array)
) {
fos.write(array,0,i);
}
/* Close all streams */
fos.close();
is .close();
/* Load the DLL from the filesystem */
System.load(dll.getAbsolutePath());
System. out .println( "CardReader loaded" );
}
catch (Throwable e)
{
e.printStackTrace();
}
}
public void init() {
// TODO start asynchronous download of heavy resources
}
public void paint(Graphics g)
{
gg = g;
pos = 14;
text( "INITIALIZATION..." );
java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
CommPortIdentifier portIdentifier = portEnum.nextElement();
if ( portIdentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
text( "FOUND PORT " + portIdentifier.getName());
}
}
public void text(String t)
{
gg.drawString(t, 10, pos);
pos += 14;
}
}
* This source code was highlighted with Source Code Highlighter .
しかし、それだけではありません。 RXTXライブラリーは、 System.loadLibrary()を使用してrxtxSerial.dllをロードしようとしていますが、もちろん失敗します。 この問題を解決するために、java.library.pathディレクトリの1つにdllを保存することは可能ですが、ソースコードでは、RXTXはライブラリのロード行をコメントアウトしました(まだCardReaderクラスでロードされています)。
アプレット署名
アプレットはユーザーのコンピューターでファイル操作を実行しようとしているため、デジタル署名が必要です。 インターネットでこれを行う方法については多くの指示があります 。たとえば、 ここに記載されているとおりに行うことができます 。
まとめ
私たちから配布されたアプレットは、COMポートを操作する機会を得たと同時に、必要なものはすべて単一のjarファイルに含まれています。 ユーザーのコンピューターにライブラリーは必要ありません。 ユーザーはアプレットのあるページに移動するだけです(この場合、表示されるウィンドウでアプレットを起動する許可を確認します)。
PS記事を適切なブログに転送するのに十分なカルマがありません。