问题
I've developed a Java application (a dictionary) with an Access database to store the words of the dictionary and I'm getting ready to distribute it. I want to encrypt my database with a password to prevent people to access my words. When I set a passwords the Java code shows this Exception
net.ucanaccess.jdbc.UcanaccessSQLException: Decoding not supported. Please choose a CodecProvider which supports reading the current database encoding.
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:247)
Here is my connection code before encryption of my database with password ....
String s1="jdbc:ucanaccess://";
String user="";
String pass="";
String s4="words.accdb";
public void connectToDB(){
//database connection
try {
conn = DriverManager.getConnection(s1+s4,user,pass);
} catch (SQLException e) {
e.printStackTrace();
}
//end of database connection
}
Here is the code after the encryption with password for example 12345...
String s1="jdbc:ucanaccess://";
String user="";
String pass="12345";
String s4="words.accdb";
public void connectToDB(){
//database connection
try {
conn = DriverManager.getConnection(s1+s4,user,pass);
} catch (SQLException e) {
e.printStackTrace();
}
//end of database connection
}
回答1:
Steps of How to connect UCanAccess to an Access database encrypted with a database password
Step 1:
Add these two packages to your project (jackcess-encrypt.jar, bcprov-ext-jdk15on-152)
You can download the two packages from the following links:
Jackcess Encrypt
Bouncy Castle
Step 2:
You have to add this class to your project folder
import java.io.File;
import java.io.IOException;
import net.ucanaccess.jdbc.JackcessOpenerInterface;
import com.healthmarketscience.jackcess.CryptCodecProvider;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
public class CryptCodecOpener implements JackcessOpenerInterface {
@Override
public Database open(File fl,String pwd) throws IOException {
DatabaseBuilder dbd =new DatabaseBuilder(fl);
dbd.setAutoSync(false);
dbd.setCodecProvider(new CryptCodecProvider(pwd));
dbd.setReadOnly(false);
return dbd.open();
}
//Notice that the parameter setting autosync =true is recommended with UCanAccess for performance reasons.
//UCanAccess flushes the updates to disk at transaction end.
//For more details about autosync parameter (and related tradeoff), see the Jackcess documentation.
}
like this
step 3:
use the following connection code
public void connectToDB(){
try {
conn = DriverManager.getConnection("jdbc:ucanaccess://words.accdb;jackcessOpener=CryptCodecOpener", "user", "pass");
} catch (SQLException ex) {
ex.printStackTrace();
}
}
You can also watch this video...https://www.youtube.com/watch?v=TT6MgBBkRSE
回答2:
UCanaccess supports encryption through the dependencies injection pattern.
-You have to add jackcess-encrypt and all related dependencies to your project
-You have to code a class implementing the net.ucanaccess.jdbc.JackcessOpenerInterface
as suggested in the ucanaccess web site
-You have to pass the name of the above class in the jdbc url:
if you named the implementation class com.pippo.Bingo
then you have to build the jdbc url in this way:
DriverManager.getConnection("jdbc:ucanaccess://c:/db/your_db_name.mdb;jackcessOpener=com.pippo.Bingo", "sa", pwd);
回答3:
Your Link to the jdbc driver (s1) seems to be invalid.
Look at the pattern i found while googleing it from this Site
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\IJTS EXAMPLES\\Database11.accdb;PWD=1234";
Here is a sample from a Site
private void initializeConnection()
{
Connection con ;
try
{
// Load Class Definition for Database Driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// set this to a MS Access DB you have on your machine
String curDir = System.getProperty("user.dir");
String filename = curDir +"/test.mdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\\test.mdb;READONLY=true";
// Get connection from the DriverManager
con = DriverManager.getConnection( database,"Admin","test" );
} catch (Exception e) {
System.out.println("Database Connection Problem");
}
}
Please not that you have to change the string by replacing parts with your credentials
回答4:
I assume you have set the database password from within MSAccess, encrypting it.
To connect to this type of database, you need the correct connection string and connect via odbc.
Here is a link to get the connection strings for MSAccess https://www.connectionstrings.com/access/
A good post on the subject can be found here How can I add a password to this JDBC:ODBC connection string that is trying to connect to an MS Access database
I would suggest you use a different type of embedded database to do all of this for java. Use h2, which is far better pure java solution
http://www.h2database.com/html/main.html
code example
public class HelloWorld {
/**
* Called when ran from command line.
*
* @param args ignored
*/
public static void main(String... args) throws Exception {
// delete the database named 'test' in the user home directory
DeleteDbFiles.execute("~", "test", true);
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:~/test");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar(255))");
stat.execute("insert into test values(1, 'Hello')");
ResultSet rs;
rs = stat.executeQuery("select * from test");
while (rs.next()) {
System.out.println(rs.getString("name"));
}
stat.close();
conn.close();
}
}
Where are the Database Files Stored?
When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\ or C:\Users\.
If the base directory is not set (as in jdbc:h2:test), the database files are stored in the directory where the application is started (the current working directory).
When using the H2 Console application from the start menu, this is /bin. The base directory can be set in the database URL. A fixed or relative path can be used.
When using the URL jdbc:h2:file:data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist.
It is also possible to use the fully qualified directory name (and for Windows, drive name). Example: jdbc:h2:file:C:/data/test
Passing the User Name and/or Password in the URL
Instead of passing the user name as a separate parameter as in
Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", "123");
The user name (and/or password) can be supplied in the URL itself: Connection conn = DriverManager. getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123");
来源:https://stackoverflow.com/questions/31429939/how-to-connect-ucanaccess-to-an-access-database-encrypted-with-a-database-passwo