【CDMI-PROJECT】DAILY SUMMURY

1. Java中单元测试中:@BeforeClass,@Before,@Test,@After,@AfterClass中的问题详解

  1. 其中:@BeforeClass,@AfterClass是Junit4中新添加进去的
  2. 如果Run as —>Junit Test,运行含有@Test注释的方法是,那么所有注解方法都将被执行,所含的执行顺序是:
    @BeforeClass ,@Before,@Test,@After,@AfterClass
  3. 在JUnit4中,如果测试类继承了TestCase类,那么所有的Annotation都不会起作用。

2. import static和import的区别

import static静态导入是JDK1.5中的新特性。一般我们导入一个类都用 import com…..ClassName;而静态导入是这样:import static com…..ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。

这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。
但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便

3. transient 关键字

我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。

然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中不会写到磁盘里持久化

总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

4. volatie 关键字

JAVA中保证多线程的线程安全有两种方式:

  1. 同步语法块(synchronized)
  2. volatile关键字

下面主要讲一下volatile关键字,被该关键字修饰的变量,当在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

了解更多,深入理解Java内存模型(volatile关键字)

5. Annotation

Java基础之理解Annotation

6. AES加密

  • pc java默认的jar包不支持256加密,即32位密钥。要到官网下载jar包替换java_home/jre/lib/security下的jar包才可以。android 默认支持256位加密。
  • 下面给出的是128位也就是16字节的AES加密
package aes_encryption;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 *
 * @author Kevin Guo
 */
public class AES_Encryption {

    /**
     * 
     */
    public static void main(String[] args) {
        // TODO code application logic here
        String content = "test";  
        String password = "12345678";  
        //加密  
        System.out.println("加密前:" + content);  
        byte[] encryptResult = encrypt(content, password);  
        System.out.println("加密后:" + encryptResult);
        //解密  
        byte[] decryptResult = decrypt(encryptResult,password);  
        System.out.println("解密后:" + new String(decryptResult)); 
    }

    public static byte[] encrypt(String content, String password) {  
        try {             
                KeyGenerator kgen = KeyGenerator.getInstance("AES");  
                kgen.init(128, new SecureRandom(password.getBytes()));  
                SecretKey secretKey = kgen.generateKey();  
                byte[] enCodeFormat = secretKey.getEncoded();  
                SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");  
                Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
                byte[] byteContent = content.getBytes("utf-8");  
                cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化  
                byte[] result = cipher.doFinal(byteContent);  
                return result; // 加密  
        } catch (NoSuchAlgorithmException e) {  
                e.printStackTrace();  
        } catch (NoSuchPaddingException e) {  
                e.printStackTrace();  
        } catch (InvalidKeyException e) {  
                e.printStackTrace();  
        } catch (UnsupportedEncodingException e) {  
                e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
                e.printStackTrace();  
        } catch (BadPaddingException e) {  
                e.printStackTrace();  
        }  
        return null;  
    }  

    public static byte[] decrypt(byte[] content, String password) {  
        try {  
                KeyGenerator kgen = KeyGenerator.getInstance("AES");  
                kgen.init(128, new SecureRandom(password.getBytes()));  
                SecretKey secretKey = kgen.generateKey();  
                byte[] enCodeFormat = secretKey.getEncoded();  
                SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");              
                Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
                cipher.init(Cipher.DECRYPT_MODE, key);// 初始化  
                byte[] result = cipher.doFinal(content);  
                return result; // 加密  
        } catch (NoSuchAlgorithmException e) {  
                e.printStackTrace();  
        } catch (NoSuchPaddingException e) {  
                e.printStackTrace();  
        } catch (InvalidKeyException e) {  
                e.printStackTrace();  
        } catch (IllegalBlockSizeException e) {  
                e.printStackTrace();  
        } catch (BadPaddingException e) {  
                e.printStackTrace();  
        }  
        return null;  
    }  
}

**注意:**JAVA 原生 API 中的 AES 加密只支持128位加密,如果想要用192或者256位加密,要去官网下载JCE扩展包,替换 JAVA_HOME/jdk/jre/lib/security 里面的 local_policy 和 US_export_policy,一定要注意下载包和自己的java版本的配套,我的是1.7 就要下载这个链接里面的 JCE 7 匹配 1.7版本java

7. JAVA 文件的读写


import java.io.*;


public class FileIO {
    private static String path = "C:/data/test.txt";

    public static void main(String[] args) throws Exception {
        // Read data from file located in C:/data/test.txt 
        try {
            File f = new File(path);
            InputStreamReader isr = new InputStreamReader(new FileInputStream(f));
            BufferedReader br = new BufferedReader(isr);
            String line = br.readLine();
            while(line != null) {
                System.out.println(line);
                line = br.readLine();
            }
        } catch (Exception e) {
        }

        // Write data to file C:/data/test.txt 
        try {
            File f = new File("C:/data/test.txt");
        if(!f.exists())
            f.createNewFile();
        //Attention: the boolean parm in FileWriter(f, true) decesides if it overwrite the contents in the txt file.
        BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
        bw.write("This is line 1\r\n");
        bw.write("This is line 2\r\n");
        bw.write("This is line 3\r\n");
        bw.write("This is line 4\r\n");
        bw.write("This is line 5\r\n");
        bw.write("This is line 6\r\n");
        bw.flush();
        bw.close();
        } catch (Exception e) {
        }
    }

}

8. JSON-SMART

json-smart 是 java 方便操作 JSONObject 的 API 。可以方便地把自定义的 class 与 JSONObject 之间进行转化,并将转化后的 JSONObject 转换为字符串。同时该包还提供了 JSON 的解析器。

官方文档
具体使用参考这篇文档:json-smart 使用示例

9. forward和redirect的区别

可以从以下几个方面来看:

1.从地址栏显示来说

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.

redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.所以redirect等于客户端向服务器端发出两次request,同时也接受两次response。

2.从数据共享来说

forward:转发页面和转发到的页面可以共享request里面的数据. redirect:不能共享数据.

redirect不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源.

forward 方法只能在同一个Web应用程序内的资源之间转发请求。forward 是服务器内部的一种操作. redirect是服务器通知客户端,让客户端重新发起请求.

所以,你可以说 redirect 是一种间接的请求, 但是你不能说”一个请求是属于forward还是redirect “

3.从运用地方来说

forward:一般用于用户登陆的时候,根据角色转发到相应的模块.

redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

4.从效率来说 forward:高. redirect:低.

你可能感兴趣的:(Java)