“Java”的版本间的差异
(→一个很诡异的bug,原来是由int精度引起的) |
(→java中List的初始化问题) |
||
第87行: | 第87行: | ||
就可以了,然后添加元素就不会出现空指针了。 | 就可以了,然后添加元素就不会出现空指针了。 | ||
+ | |||
+ | ===一个很诡异的bug,原来是由int精度引起的=== | ||
+ | |||
+ | <source lang="java"> | ||
+ | import java.util.*; | ||
+ | import java.text.SimpleDateFormat; | ||
+ | |||
+ | public class hello { | ||
+ | |||
+ | |||
+ | public static void main(String[] args) { | ||
+ | |||
+ | int[] ebbing = {1, 2, 4, 7, 15, 30, 50, 70, 100, 150, 200, 150, 200, 300, 400}; | ||
+ | |||
+ | getToday((long)ebbing[0] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[1] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[2] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[3] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[4] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[5] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[6] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[7] * 3600 * 24 * 1000); | ||
+ | getToday((long)ebbing[8] * 3600 * 24 * 1000); | ||
+ | } | ||
+ | |||
+ | // int为整数类型,在存储的时候,用4个字节存储,范围为-2,147,483,648到2,147,483,647。 | ||
+ | // 原用的是getToday(int offset_ms),这样在第6个日期,就超出范围了。 | ||
+ | public static String getToday(long offset_ms) { | ||
+ | |||
+ | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | ||
+ | Date date = new Date(System.currentTimeMillis() + offset_ms); | ||
+ | String today = dateFormat.format(date); | ||
+ | |||
+ | System.out.println(offset_ms + " " + today); | ||
+ | |||
+ | return today; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | <source lang="bash"> | ||
+ | # java hello | ||
+ | 86400000 2014-05-14 | ||
+ | 172800000 2014-05-15 | ||
+ | 345600000 2014-05-17 | ||
+ | 604800000 2014-05-20 | ||
+ | 1296000000 2014-05-28 | ||
+ | 2592000000 2014-06-12 | ||
+ | 4320000000 2014-07-02 | ||
+ | 6048000000 2014-07-22 | ||
+ | 8640000000 2014-08-21 | ||
+ | </source> | ||
==Tomcat== | ==Tomcat== |
2019年12月17日 (二) 05:34的版本
基础入门
hello world
public class HelloWorld{ public static void main(String[] args) { System.out.println("Hello World!"); } }
java打印数组
将数组转化为有序的List打印出来
import java.util.Arrays; public class Hello { public static void main(String[] args) { String pool[] = {"dog", "cat", "pig", "main", "fish"}; System.out.println(Arrays.asList(pool)); } }
JAVA中int转String类型有三种方法
int i = 123; String s = String.valueOf(i); String s = Integer.toString(i); String s = i + ""; //字符转数字 String str = "123456"; i = Integer.parseInt(str);
compareto, equals, == 在java中相对于值和引用
1.compareto是判断一个对象的值是否包含包含另一个对象的值;
例如"abcds".compareto("ab")就是判断abcds中是否含有ab
2.equals 是比较两个对象的值
3.==是比较两个对象内存地址
String A = "abcd"; String B = "abcd"; A == B; //ture A.equals(B); //true String A = new String("abcd"); String B = new String("abcd"); A == B; //false A.equals(B); //true
java中List的初始化问题
我声明了一个
List<String[]> users = null;
然后 使用 add()方法想这个List中加入元素的时候为啥会出现空指针啊。
List当然不能初始化为null,
List<String[]> users = new LinkedList<String[]>();
就可以了,然后添加元素就不会出现空指针了。
一个很诡异的bug,原来是由int精度引起的
import java.util.*; import java.text.SimpleDateFormat; public class hello { public static void main(String[] args) { int[] ebbing = {1, 2, 4, 7, 15, 30, 50, 70, 100, 150, 200, 150, 200, 300, 400}; getToday((long)ebbing[0] * 3600 * 24 * 1000); getToday((long)ebbing[1] * 3600 * 24 * 1000); getToday((long)ebbing[2] * 3600 * 24 * 1000); getToday((long)ebbing[3] * 3600 * 24 * 1000); getToday((long)ebbing[4] * 3600 * 24 * 1000); getToday((long)ebbing[5] * 3600 * 24 * 1000); getToday((long)ebbing[6] * 3600 * 24 * 1000); getToday((long)ebbing[7] * 3600 * 24 * 1000); getToday((long)ebbing[8] * 3600 * 24 * 1000); } // int为整数类型,在存储的时候,用4个字节存储,范围为-2,147,483,648到2,147,483,647。 // 原用的是getToday(int offset_ms),这样在第6个日期,就超出范围了。 public static String getToday(long offset_ms) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = new Date(System.currentTimeMillis() + offset_ms); String today = dateFormat.format(date); System.out.println(offset_ms + " " + today); return today; } }
# java hello 86400000 2014-05-14 172800000 2014-05-15 345600000 2014-05-17 604800000 2014-05-20 1296000000 2014-05-28 2592000000 2014-06-12 4320000000 2014-07-02 6048000000 2014-07-22 8640000000 2014-08-21
Tomcat
java开发环境
- 安装JDK
- 设置环境变量
JAVA_HOME = C:\Program Files\Java\jdk1.8.0_66 PATH = C:\ProgramData\Oracle\Java\javapath;%JAVA_HOME%\bin; CLASSPATH = %JAVA_HOME%\lib; %JAVA_HOME%\lib\dt.jar; %JAVA_HOME%\lib\tools.jar;
- 安装tomcat
- 安装IntellJ idea
- 新建项目,关联tomcat
- 部署项目:把IntelliJ项目的web目录上传到外网虚拟站点根目录就可以了。
jar xf tomcat.war chown -R www.www ./* service tomcat restart
数据库连接不上,把mysql-connector-java-5.1.18-bin.jar放到tomcat/lib目录下,重启。
Spring
谈谈对ssh三大框架的理解?
SSH框架一般指的是Struts、Spring、Hibernate,后来Struts2代替了Struts。最近5年,Struts2已经被Spring MVC代替,而Hibernate基本也被iBatis/MyBatis代替。
所以你真正需要了解的是Spring,Spring你需要了解两个概念AOP和IOC,更进一步就是Spring的核心技术“动态代理”。
持久层框架看看Hibernate/iBatis/MyBatis,研究一下Spring的数据库事务管理,各个持久层框架式如何实现ORM的,了解至少一种缓存框架,知道什么是数据库连接池。和数据库的交互最核心的不是ORM,而是掌握和数据库相关的能力,比如数据库编程、SQL优化、对范式的理解。
MVC框架Struts2和Spring MVC,你需要知道他们在web.xml文件里配置了一些什么,Struts2/Spring MVC接到前台请求之后经过哪些步骤之后转到Action/Controller,return之后Struts2/Spring MVC又作了些什么。还有就是Filter、Listener和Struts2/Spring MVC的拦截器各有什么特点,适合处理什么样的问题。
Spring Security取username
前台
<%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %> <security:authentication property="principal.username"></security:authentication>
后台
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); String username = ""; if (principal instanceof UserDetails) { username = ((UserDetails) principal).getUsername(); } else { username = principal.toString(); } System.out.println(username);
favicon.ico引起的spring security登录后跳转错误
在使用spring security登录的时候,用户在某些情况下登录成功的时候莫名被重定向到favicon.ico。
之前一直没发现这个问题是因为在项目中存在favicon.ico文件,这个请求被nginx处理了而未转发给tomcat。
这次因为偷懒还没来得及配置nginx,结果就出现了上面的问题。
出现上述问题的原因是:基本大多数浏览器都会请求favicon.ico这个图标文件用来展示在浏览器的URL地址前面,而这个文件被spring security保护了,所以…有下面的流程:
the user requests URL "/". This URL is cached.
the browser makes a requests to "/favicon.ico". This URL becomes the new URL where to redirect to upon authentication.
the user posts the login form and is redirected to "/favicon.ico"
而解决办法是将favicon.ico加入允许匿名访问.
<http pattern="/favicon.ico" security="none"/>
SPRING MVC 的请求参数获取的几种方法
<form method="post" action="hao.do"> a: <input id="a" type="text" name="a"/> b: <input id="b" type="text" name="b"/> <input type="submit" value="Submit" /> </form>
方法1:
public class Pojo{ private String a; private int b; } @RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pojo") Pojo pojo) { return "helloWorld"; }
方法2:
@RequestMapping(method = RequestMethod.GET) public String get(HttpServletRequest request, HttpServletResponse response) { System.out.println(request.getParameter("a")); return "helloWorld"; }
spring mvc 静态资源 404问题
修改web.xml文件,增加对静态资源的url映射。
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping>
在web.xml中添加好配置后,在jsp页面就可以引用这些静态资源了。
这里还需要说明的是:这种方法不能访问WEB-INF目录下的静态资源,也就是js目录必须是web根(可能是webapp,webContent等)目录下,否则是不能引用的。
常用代码
随机取读取数据库的一道题
Random random = new Random(System.currentTimeMillis()); int index_random = random.nextInt(listItem.size());
guid()
private String guid() { UUID uuid = UUID.randomUUID(); String str = uuid.toString(); // 去掉"-"符号 String temp = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24); return temp; }
Java数字格式化
double pi = 3.1415927;//pi // 取一位整数 System.out.println(new DecimalFormat("0").format(pi));// 3 // 取一位整数和两位小数 System.out.println(new DecimalFormat("0.00").format(pi));// 3.14 // 取两位整数和三位小数,整数不足部分以0填补。 System.out.println(new DecimalFormat("00.000").format(pi));// 03.142 // 取所有整数部分 System.out.println(new DecimalFormat("#").format(pi));// 3 // 以百分比方式计数,并取两位小数 System.out.println(new DecimalFormat("#.##%").format(pi));// 314.16% long c = 299792458; // 显示为科学计数法,并取五位小数 System.out.println(new DecimalFormat("#.#####E0").format(c));// 2.99792E8 // 显示为两位整数的科学计数法,并取四位小数 System.out.println(new DecimalFormat("00.####E0").format(c));// 29.9792E7 // 每三位以逗号进行分隔。 System.out.println(new DecimalFormat(",###").format(c));// 299,792,458 // 将格式嵌入文本 System.out.println(new DecimalFormat("光速大小为每秒,###米。").format(c));
生成随机字符
private String RandomString(int length, String type) { String number = "0123456789"; String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { if (type.equals("number")) { int num = random.nextInt(number.length()); sb.append(number.charAt(num)); } else { int num = random.nextInt(str.length()); sb.append(str.charAt(num)); } } return sb.toString(); }
应用
AES加密
java代码
// 密钥 private final static String secretKey = "key123"; private final static String salt = "0123456789abcdef" ;//KeyGenerators.string().generateKey(); /** * 加密 * * @param plainString 明文 * @return */ private static String encrypt(String plainString) { // 明文 byte[] byteArray = plainString.getBytes(); // 加密,设置密钥和随机数 byte[] cipherArrayTemp = Encryptors.standard(secretKey, salt).encrypt(byteArray); byte[] cipherArray = Base64.encode(cipherArrayTemp); return new String(cipherArray); } /** * 解密 * * @param cipherString 密文 * @return */ private static String decrypt(String cipherString) { // 密文 byte[] byteArray = cipherString.getBytes(); byte[] plainArrayTemp = Base64.decode(byteArray); // 解密 byte[] plainArray = Encryptors.standard(secretKey, salt).decrypt(plainArrayTemp); return new String(plainArray); }
javascript代码
https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.js
// 可在第三方网站解密 let word = 'hello world!'; let key = 'key123'; var iv = '0123456789abcdef'; var attr = { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }; console.log(CryptoJS.AES.encrypt(word, key, attr).toString()); console.log(CryptoJS.AES.decrypt(CryptoJS.AES.encrypt(word, key), key).toString(CryptoJS.enc.Utf8));
Base64,Base32,Base16进制的区别
刚刚接触Base时,没有太注重区分Base64,Base32,Base16的区别,后面每一次遇到就要去一个一个试,这次花了点时间记下了一下Base的区别,顺便写一下。
在看了大佬们的分析后http://blog.51cto.com/xiaoqin00/1718416,我截取了几个关键的记住这些就能区分Base之间的区别了:
Base64:
包含大写字母(A-Z),小写字母(a-z),数字(0-9)以及+/;
Base32:
而Base32中只有大写字母(A-Z)和数字234567;
Base16:
而Base16就是16进制,他的范围是数字(0-9),字母(ABCDEF);
顺便说一句,当ASCll用Base加密达不到所对应的位数的时候用=号补齐;
在这里附带由三种Base加密的:I love you!
Base64:SSBsb3ZlIHlvde+8gQ==
Base32:JEQGY33WMUQHS33V566IC===
Base16:49206c6f766520796f75efbc81
poi导出excel文件、下载
@RequestMapping(value = "batchCardNoExport", method = RequestMethod.GET) public void batchCardNoExport(HttpServletRequest request, HttpServletResponse response) throws Exception { // 创建Excel的工作书册 Workbook,对应到一个excel文档 HSSFWorkbook wb = new HSSFWorkbook(); // 创建Excel的工作sheet,对应到一个excel文档的tab HSSFSheet sheet = wb.createSheet("sheet1"); HSSFRow row; HSSFCell cell; for (int i = 0; i < 60; i++) { row = sheet.createRow(i); // 创建Excel的sheet的一行 for (int j = 0; j < 30; j++) { cell = row.createCell(j); // 创建一个Excel的单元格 cell.setCellValue("hello world " + i + " " + j); } } response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment; filename=filename.xls"); wb.write(response.getOutputStream()); // Write workbook to response. wb.close(); }
如何在mac上安装gradle
首先,先download最新版本的gradle,网址如下:
http://www.gradle.org/get-started
然后将下载下来的zip包放在你要安装的路径上,我安装在
/usr/local/bin;
然后打开电脑上的.bash_profile文件,输入以下命令:
GRADLE_HOME=/usr/local/bin/gradle-1.8; export GRADLE_HOME export PATH=$PATH:$GRADLE_HOME/bin
然后再在console上输入以下命令:
source ~/.bash_profile
这样就安装成功啦,可以通过以下命令来查看是否安装成功。
gradle -version