Java

来自tomtalk
跳转至: 导航搜索



目录

基础入门

hello world

public class HelloWorld{ 
    public static void main(String[] args) {  
        System.out.println("Hello World!"); 
    }
}
#运行java程序
$ javac HelloWorld.java
$ java HelloWorld  #文件名后面不要带.class后缀,否则会报错“错误:找不到或无法加载主类”。
Hello World!
 
#打包可运行的jar文件
$ jar -cvfe HelloWorld.jar HelloWorld HelloWorld.class
$ java -jar HelloWorld.jar
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

<T>(尖括号)是什么意思?

它与java中的泛型有关。如果我提到ArrayList<String>这意味着我只能将String类型对象添加到该ArrayList。

Java中泛型的两个主要好处是:

  • 减少程序中的强制转换数量,从而减少程序中潜在错误的数量。
  • 提高代码清晰度。

Java map 详解 - 用法、遍历、排序、常用API等

https://baike.xsoftlab.net/view/250.html

  • HashMap:最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。
  • TreeMap:能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。
  • Hashtable:与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
  • LinkedHashMap:保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。

@validated和@valid不同点

https://www.jianshu.com/p/89a800eda155 https://segmentfault.com/a/1190000011712893

  • @Valid可以注解在成员属性(字段)上,但是@Validated不行。
  • @valid只能用在controller。@Validated可以用在其他被spring管理的类上。

Java bean 是个什么概念?

Java语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库。

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等)目录下,否则是不能引用的。

使用spring ResponseEntity处理http响应

https://blog.csdn.net/neweastsun/article/details/81142870

使用spring时,达到同一目的通常有很多方法,对处理http响应也是一样。本文我们学习如何通过ResponseEntity设置http相应内容、状态以及头信息。

ResponseEntity标识整个http相应:状态码、头部信息以及相应体内容。因此我们可以使用其对http响应实现完整配置。

如果需要使用ResponseEntity,必须在请求点返回,通常在spring rest中实现。ResponseEntity是通用类型,因此可以使用任意类型作为响应体。

@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "foo");
 
    return new ResponseEntity<>("Custom header set", headers, HttpStatus.OK);
}

Controller中返回数据总结(ResponseEntity,@ResponseBody,@ResponseStatus)

https://www.cnblogs.com/Jason-Xiang/p/10244075.html

在传统的开发过程中,我们的控制CONTROLLER层通常需要转向一个JSP视图;但随着WEB2.0相关技术的崛起,我们很多时候只需要返回数据即可,而不是一个JSP页面。

  • ResponseEntity:表示整个HTTP响应:状态代码,标题和正文。因此,我们可以使用它来完全配置HTTP响应,它是一个对象。
  • @ResponseBody:返回json格式的结果
  • @ResponseStatus:返回状态
@GetMapping("/hello")
public ResponseEntity<String> hello() {
    return new ResponseEntity<>(new User(‘jdon’), HttpStatus.OK);
}
//返回的是JSON字符串:[ { ‘name’: 'jdon'}]

在类级别使用@Controller标注情况下, @ResponseBody注解告诉返回的对象将自动序列化为JSON,并通过回控制器的HttpResponse对象。

@Controller
public class XXXController{
    @ResponseBody
    public User postResponseController(@RequestBody LoginForm loginForm) {
        return new User("Thanks For Posting!!!");
    }
}
//将返回客户端JSON字符串:[ { ‘name’: Thanks For Posting!!!"}]

在@RestController注解了类的情况下,我们就不需要再使用@ResponseBody了。

@ResponseStatus

ResponseStatus虽然只是规定了返回的状态,但是只需要标注在方法上,简单,而且状态码与返回类型分离,比较清晰。我们将上面返回对象列表的代码使用ResponseStatus改写如下,注意类级别@RestController:

@RestController
public class XXXController{
    @ResponseStatus(HttpStatus.FOUND)
    public User postResponseController() {
        return new User("Thanks For Posting!!!");
    }
}
//这也会返回客户端JSON字符串:[ { ‘name’: Thanks For Posting!!!"}]

这样的代码更加专注于业务。

Spring还允许我们直接访问javax.servlet.http.HttpServletResponse对象; 我们只需要将它声明为方法参数:

@GetMapping("/manual")
public void manual(HttpServletResponse response) throws IOException {
    response.setHeader("Custom-Header", "foo");
    response.setStatus(200);
    response.getWriter().println("Hello World!");
}

由于Spring在底层实现之上提供了抽象和附加功能,因此如果以这种方式直接操纵响应,会失去很多Spring提供方便功能。

注解@RequestParam与@RequestBody的使用场景

https://cloud.tencent.com/developer/article/1414464

注解@RequestParam接收的参数是来自requestHeader中,即请求头。通常用于GET请求,比如常见的url:

http://localhost:8081/spring-boot-study/novel/findByAuthorAndType?author=唐家三少&type=已完结

注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。

RestTemplate

https://blog.csdn.net/itguangit/article/details/78825505

REST与RPC几乎没有任何关系。RPC是面向服务的,并关注于行为和动作;而REST是面向资源的,强调描述应用程序的事物和名词。

RestTemplate定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。 其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。

  1. put() PUT 资源到特定的URL
  2. getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
  3. getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
  4. postForEntity()POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的
  5. postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
  6. postForLocation() POST 数据到一个URL,返回新创建资源的URL
  7. delete() 在特定的URL上对资源执行HTTP DELETE操作
  8. headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
  9. optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
  10. exchange()在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
  11. execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象

Spring Boot

入门--Hello World

https://blog.csdn.net/duchao123duchao/article/details/73011717

Spring Boot是一种简化原有Spring应用繁杂配置的微框架。使开发者从繁杂的各种配置文件中解脱出来,通过Spring Boot能够很简单、很快速构建一个优秀的、产品级的Spring基础应用。运行Spring Boot和运行普通的Java类一样简单,仅仅run一下Spring Boot的入口main()方法即可开启应用;你也可以把Spring Boot应用打成jar,在命令行执行java -jar xxx.jar命令来运行;或者打成war包部署到服务器下运行服务器来开启应用。Spring Boot微框架考虑到了Spring平台和第三方库的情况,所以你需要做的则是最少的操作或配置。

Spring Boot特点:

  1. 创建优秀的Spring Web应用;
  2. 直接嵌入了Tomcat、Jetty和Undertow等三个Web服务器,很方便的部署应用;
  3. 提供一系列不同类型的starter POMs简化原有Spring应用繁杂的Maven配置;
  4. 充分利用JavaConfig的配置模式以及“约定优于配置”的理念,自动化配置、装配Spring,简化了人为的配置;
  5. 提供生产就绪型功能,如指标,健康检查和外部配置(?不理解这点,求指教);
  6. 没有代码产生、没有XML文件要求配置。
@RestController //里面的方法都以 json 格式输出,表示这个入口类也是控制类,=@Controller+@ResponseBody 
@SpringBootApplication
public class DemoApplication {
    @RequestMapping("/")   //请求的映射路由
    public String home(){
        return "hello world";
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

spring boot 指定启动端口

src/main/resources/application.properties
server.port=8081

如何禁用 Spring Boot DEBUG 和 Spring Boot INFO 日志?

logging.level.org.springframework=OFF
logging.level.root=OFF
spring.main.banner-mode=off

SpringApplication启动原理

http://www.majunwei.com/view/201708231840127244.html

  1. SpringApplication.run(args)
  2. 初始化监听器
  3. 发布ApplicationStarterEvent事件
  4. 装配环境
  5. 发布ApplicatinEnvironmentPreparedEvent事件
  6. 打印Banner
  7. 创建ApplicationContext
  8. 装配Context
  9. 发布ApplicationPreparedEvent事件(注意源码中是空的,没有真正发布)
  10. 注册、加载等等…
  11. 发布ApplicationPreparedEvent事件(注意这里才是真正发布了Prepared事件)
  12. refreshContent
  13. afterContent
  14. 发布ApplicationReadyEvent事件

springboot中 @Autowired @Resource @Bean

https://www.jianshu.com/p/70e7e7bc652e

Spring Data JPA 与 MyBatis简单对比

https://www.jianshu.com/p/3927c2b6acc0

JPA是Java Persistence API的简称,是一套Sun官方提出的Java持久化规范。

Spring Data JPA是Spring Data的子模块。使用Spring Data,使得基于“repositories”概念的JPA实现更简单和容易。Spring Data JPA的目标是大大简化数据访问层代码的编码。作为使用者,我们只需要编写自己的repository接口,接口中包含一些个性化的查询方法,Spring Data JPA将自动实现查询方法。

JPA默认使用hibernate作为ORM实现,所以,一般使用Spring Data JPA即会使用hibernate。我们再看看hibernate的官方概念,Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

这样看,Spring Data JPA与MyBatis对比,起始也就是hibernate与MyBatis对比。所以,我们直接来比较后两者。

hibernate是一个自动化更强、更高级的框架,毕竟在java代码层面上,省去了绝大部分sql编写,取而代之的是用面向对象的方式操作关系型数据库的数据。而MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。

这样看来MyBatis更适合于面向关系(或面向数据、或面向过程)的系统设计方法,这样的系统一般称为“事务脚步”系统(事务脚步(Transaction Script) 出自Martin Fowler 2004年所著的企业应用架构模式(Patterns of Enterprise Application Architecture))。而hibernate(也可以说Spring Data JPA)更适合于构建领域模型类的系统。当然,我们也不能说MyBatis无法构建领域模型驱动的系统,而hibernate无法构建事务脚步系统。只是用MyBatis构建领域模型要做更多、更脏、更累的工作;而用hibernate构建一个事务脚本系统有些大材小用,数据的查询反而没那么灵活。

Spring Data Jpa的使用

https://www.jianshu.com/p/c23c82a8fcfc

相关配置

server:
  port: 8080
  servlet:
  context-path: /
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: mysql123
  jpa:
    database: MySQL
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    hibernate:
    ddl-auto: update

ddl-auto

  • create:每次运行程序时,都会重新创建表,故而数据会丢失
  • create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
  • upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
  • validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
  • none: 禁用DDL处理

简单的REST CRUD示例

写一个类继承JpaRepository<T, ID>,需要写两个泛型,第一个代表要存储的实体类型,第二个代表主键类型,例如写一个User类的仓储如下:

public interface UserRepository extends JpaRepository<User, Long> {
}

常用代码

随机取读取数据库的一道题

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

IntelliJ IDEA 配置

https://www.cnblogs.com/knowledgesea/p/11158412.html

IDEA 清除类中无用的import包:Ctrl + Alt + O

自动导入缺失的包:Alt + Enter

格式化代码:Ctrl + Alt + L

swagger常用注解说明

https://www.jianshu.com/p/12f4394462d5

@Api:用在类上,说明该类的作用。
@ApiOperation:用在方法上,说明方法的作用。
@ApiParam:请求属性。
@ApiResponse:响应配置。
@ApiResponses:响应集配置。
@ResponseHeader:响应头设置。
 
@ApiModel:描述一个Model的信息,(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)。
@ApiModelProperty:描述一个model的属性。