Annotation
package com.liguoliang.lang; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) /** * http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html * @author Guoliang * */ public @interface Note { String title() default "Note"; String details(); }
Usage
package com.test.meta; import static org.junit.Assert.*; import org.junit.Test; import com.liguoliang.lang.Note; @Note(details="This test is for Annotation") public class TestMeta { @Test public void test() { Classklass = TestMeta.class; assertTrue(klass.isAnnotationPresent(Note.class)); Note note = klass.getAnnotation(Note.class); System.out.println("Class: " + klass.getCanonicalName() + "Note: " + note.title() + ": " + note.details()); } }
Output:
Class: com.test.meta.TestMetaNote: Note: This test is for Annotation
* PECS stands for producer-extends, consumer-super
* Do not use wildcard types as return
types. Rather than providing additional flexibility for your users, it would force them to use wildcard types in client code.
.
@Test /** * PECS stands for producer-extends, consumer-super. */ public void testAccountListUtils() { ListcorporationAccounts = new ArrayList (); corporationAccounts.add(new CorporationAccount(1, "Google")); corporationAccounts.add(new CorporationAccount(2, "Yahoo")); List allAccounts = new ArrayList<>(); AccountListUtils. mergeUserList(corporationAccounts, allAccounts); assertEquals(corporationAccounts.size(), allAccounts.size()); }
package com.liguoliang.lang.collection; import java.util.List; import com.jpm.model.IAccount; public class AccountListUtils < T extends IAccount >{ public staticvoid mergeUserList(List tobeMerged, List allAccounts) { allAccounts.addAll(tobeMerged); } }
@Test public void wildCard() { ListcorporationAccounts = new ArrayList<>(); corporationAccounts.add(new CorporationAccount(1, "GE")); corporationAccounts.add(new CorporationAccount(2, "IBM")); IAccount account = getUserById(corporationAccounts, 2); System.out.println(account.getAccountName()); } /** * List and List are treated as two different types. * If we use List as the parameter type, and call the method by getUserId(List , * will got this compile Error: * The method getUserById_iAccount(List , int) in the type LearnGeneric * is not applicable for the arguments (List , int); * @param accountList * @param id * @return */ public IAccount getUserById(List< ? extends IAccount> accountList, int id) { for (IAccount iAccount : accountList) { if(iAccount.getAccountId().equals(id)) { return iAccount; } } return null; } /** * Note: getUserById(List and getaUserById(List ) are not reloading methods: * Erasure of method getUserById(List , int) is the same as another method in type LearnGeneric * @param accountList * @param id * @return */ public IAccount getUserById_withoutWildCard(List accountList, int id) { for (IAccount iAccount : accountList) { if(iAccount.getAccountId().equals(id)) { return iAccount; } } return null; }
ArrayList in JDK is the best example. however, this one is created by myself:
Set up Maven dependences
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.10.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.10.2.0</version>
</dependency>
Connect to the DB using JDBC
This method will print out all Tables; // before you do anything with the Database, there should be some System tables already.
package com.liguoliang; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JDBCTest { private static final String DB_URL = "jdbc:derby:tempDBForTest;create=true"; public static void main(String[] args) { Connection conn = null ; try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver") ; conn = DriverManager.getConnection(DB_URL); String sql = "SELECT TABLENAME FROM SYS.SYSTABLES"; PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while (rs.next()) { System.out.println("Rs: " + rs.getString(1)); } } catch (SQLException se) { se.printStackTrace(); } catch(ClassNotFoundException e){ System.out.println("JDBC Driver not found in CLASSPATH") ; }finally { if(conn != null){ try{ conn.close() ; } catch(SQLException se){ se.printStackTrace(); } } } } }
Use Eclipse to manage your Derby
Switch to ‘Database Development’ perspective, you may create/manage Derby DB/table.
Here is an example to inject dirty SQL using JDBC Statement:
package com.liguoliang.j2ee; import static org.junit.Assert.*; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Date; import org.junit.Before; import org.junit.Test; public class TestJDBC { private static final String DB_URL = "jdbc:derby:C:\\Users\\Guoliang\\MyDB;create=true"; Connection conn = null ; @Before public void before() throws ClassNotFoundException, SQLException { Class.forName("org.apache.derby.jdbc.EmbeddedDriver") ; conn = DriverManager.getConnection(DB_URL); } @Test public void testSQLInjection() throws SQLException { String userName = "guoliang' OR 'a' = 'a"; String password = "wrong-password" + new Date().toString(); Statement statement = conn.createStatement(); String sql = "SELECT * FROM USERS WHERE USER_NAME = '" + userName + "' AND PASSWORD = '" + password + "'"; System.out.println(sql); ResultSet rs = statement.executeQuery(sql); int userId = -1; while (rs.next()) { userId= rs.getInt(1); System.out.println(" > User Id: " + userId); // Will print all user id; } assertTrue(userId != -1); } @Test public void testPreparedStatement() throws SQLException { String userName = "guoliang' OR 'a' = 'a"; String password = "wrong-password"; PreparedStatement ps = conn.prepareStatement("SELECT * FROM USERS WHERE USER_NAME = ? AND PASSWORD = ?"); ps.setString(1, userName); ps.setString(2, password); ResultSet rs = ps.executeQuery(); int userId = -1; while (rs.next()) { userId= rs.getInt(1); fail("User Id: " + userId); } System.out.println("userId: " + userId); } }
I set one of the paramters to : [guoliang ‘a’ = ‘a], the I got the SQL:
SELECT * FROM USERS WHERE USER_NAME = 'guoliang' OR 'a' = 'a' AND PASSWORD = 'wrong-passwordWed May 07 23:47:11 CST 2014'
This means, the SQL will return all records in this table.
However we can use prepared statement to solve this issue.
SQLs used by this example:
CREATE TABLE USERS (ID INT, USER_NAME VARCHAR(20), PASSWORD VARCHAR(20)); INSERT INTO USERS (ID, USER_NAME, PASSWORD) VALUES (1, 'guoliang', 'password_abc');
// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.