Java 使用 FTP

Java 使用 FTP 等用 Apache Commons Net 就可以了:

Apache Commons Net™ library implements the client side of many basic Internet protocols. The purpose of the library is to provide fundamental protocol access, not higher-level abstractions. Therefore, some of the design violates object-oriented design principles. Our philosophy is to make the global functionality of a protocol accessible (e.g., TFTP send file and receive file) when possible, but also provide access to the fundamental protocols where applicable so that the programmer may construct his own custom implementations (e.g, the TFTP packet classes and the TFTP packet send and receive methods are exposed).

微 Web 服务的 REST 框架 Spark Framework

需要点击网页上的一个按钮打开本机上的文件或者修改本地的配置文件,由于安全的限制浏览器不能直接访问本地文件系统。为了实现这个功能,可以本地启动一个 Web 服务,浏览器访问这个 Web 服务(localhost),然后使用 Web 服务中的代码来访问本地文件系统。为了启动一个 Web 服务,一般我们会选择 Tomcat,Jetty,Websphere 等作为 Web 服务器响应 HTTP 请求,对于我们这么小的一个需求,就有些重量级了,如果能像打开一个普通程序一样打开程序就能启动 Web 服务就好了。

jQuery 404 时调用的方法

jQuery 的 ajax 能给不同的响应状态码指定回调函数,例如当连不上服务器(服务器没启动,网络有问题等)时调用 statusCode0 的方法,连上了服务器,但是找不到要访问的 URL 则调用 statusCode404 的方法。

Future

Future 的作用

  • 作为 ExecutorService.submit(Callable|Runnable) 的返回结果
  • 得到了 Future,说明其相关的任务已经提交给线程池去执行了
  • 获取任务的结果(阻塞): Future.get()
  • 取消任务: Future.cancel()
  • 查看任务是否完成: Future.isDone()

如果线程池执行的任务没有返回结果,直接用 Runnable 就好了,不需要用 Callable (代码里加上无意义的返回语句有点奇怪),Callable 更多是任务执行后有结果返回。

jQuery ui 拖拽

jQuery ui 提供了拖拽元素,拖拽排序等功能,例如要让一个元素能够被拖拽,只要给它执行 draggable() 函数即可,要实现 ul li 拖拽排序,只要在 ul 上执行函数 sortable() 就能实现了,具体更多的例子请参考 jQuery UI 实例 - 拖动

Spring 异步调用

Spring 中让一个方法在新线程中运行,只需要给方法加上 @Async 注解就可以(当然也可以自己直接创建一个线程实现异步执行)。

典型的使用如用户注册后需要发送一封邮件进行验证,邮件发送完成的时间取决于很多因素,例如网络快的时候发的快一些,慢的时候需要多一些的时间。如果使用同步的方式发送邮件,有可能需要等很久邮件才发送完成然后用户才能得到注册成功的响应,体验不是很好,如果使用异步的方式发送邮件,在发邮件的同时用户就被告知注册成功,请去收件箱中查看邮件进行注册验证(异步的方式还可以使用 MQ)。

Spring Security Login Util

查看当前登录用户的信息,调用 SecurityUtils.getLoginUser() 即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.xtuer.utils;

import com.xtuer.bean.User;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public final class SecurityUtils {
/**
* 获取登陆用户的信息
*
* @return 返回登陆的用户,如果没有登陆则返回 null
*/
public static User getLoginUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();

// URL 没有经过 Spring Security 登陆验证的 filter 时 auth 为 null
if (auth == null) {
return null;
}

Object p = auth.getPrincipal();

return p instanceof User ? (User) p : null;
}
}

getAuthentication() 返回的是一个 Authentication 对象,未登陆时它的 getPrinciple() 返回的是字符串 anonymousUser,登陆后返回的是 UserDetailsService.loadUserByUsername() 返回的对象,也即是说,我们可以实现一个 User 类,继承自 org.springframework.security.core.userdetails.User,在我们实现的 User 类中保存用户数据,在 loadUserByUsername() 中返回此用户对象。

User 类的实现请参考用户信息数据源一章

SpringMVC 处理 Ajax 映射

SpringMVC 返回 Json 数据给前端是件很简单的事,但是 SpringMVC 的 Controller 接收前端 Ajax传来的 Json 数据却不那么容易,前端和后端都要很小心,有一点不对就会出错,需要分为 2 种情况处理:

  • GET
  • PUT, POST, DELETE

How to change default Java version

1: First run /usr/libexec/java_home -V which will output something like the following:

Matching Java Virtual Machines (2):
    1.8.0_25, x86_64:   "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home
    1.7.0_75, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home

2: Pick the version you want to be the default (1.7.0_75 for arguments sake) then:

export JAVA_HOME=`/usr/libexec/java_home -v 1.7.0_75`

3: Now when you run java -version you will see:

java version "1.7.0_75"
Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode)

4: Just add the above export JAVA_HOME … line to your shell’s init file(/.bash_profile).

Gradle 编码

Gradle 默认使用系统字符编码(Windows 为 GBK,Linux, Mac 为 UTF-8),很多程序员都是使用 Windows,但是 Java 文件以及其他资源文件大多数都会使用 UTF-8(因为要跨平台使用),在 Windows 开发时编译运行容易出现乱码,报错等。

Spring Security 加密密码

明文保存密码是不可取的,可以使用 SHABCrypt 等对密码进行加密。

BCrypt 算法与 MD5/SHA 算法有一个很大的区别,每次生成的 hash 值都是不同的,就可以免除存储 salt,暴力破解起来也更困难。BCrypt 加密后的字符长度比较长,有60位,所以用户表中密码字段的长度,如果打算采用 BCrypt 加密存储,字段长度不得低于 68(需要前缀 {bcrypt})。

下面的代码展示怎么使用 BCrypt 进行加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.junit.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

public class EncryptPassword {
@Test
public void encrypt() {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

for (int i = 0; i < 5; ++i) {
// 每次生成的密码都不一样
String encryptedPassword = passwordEncoder.encode("Passw0rd");
System.out.println(encryptedPassword);
System.out.println(passwordEncoder.matches("Passw0rd", encryptedPassword)); // true
System.out.println(passwordEncoder.matches("Password", encryptedPassword)); // false
}
}
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$2a$10$l7vPVeqwb9GiVjURV5J2QO1CM5qxwk00/Ra5qEog0WgP7O5XV0Ble
true
false
$2a$10$jeyMfHF88mNJb9v.mQ7YiuZ8oTU.pHaiKdT1NLOM38eXj7heHZHg2
true
false
$2a$10$ux43/3JcHUC1hszyoJaH0eQhv7LkIVfL7p1cW80WxfxeTr2dUY6kO
true
false
$2a$10$KdUmhaJOJ30klEcKiYT25.fIRPrMs4xONHOQh4JvmpKSjJ8d9.QKG
true
false
$2a$10$gQKUOoFuevnCkoej3.AvAO9YzHKCKYmKuiSfEGHL22piY2FfNDQYu
true
false

随意取其中任意一个都可以,因为每次生成都是不一样的,所以取第一个就可以了。

Spring Security 用户信息数据源

前面章节中用户名、密码、权限都是写在配置文件里的,不能动态的管理用户的权限,大多数时候显然是不行的。这里介绍从其他数据源读取用户的信息,例如从数据库,LDAP 等。只需要给 authentication-provider 提供接口 UserDetailsService 的实现类即可,使用这个类获取用户的信息,涉及以下内容:

  • 修改 spring-security.xml 中的 authentication-provider
  • 类 UserDetailsService 实现了 Spring Security 的接口 UserDetailsService
  • 类 User
  • 类 UserService

Spring Security 入门

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
├── main
│   ├── java
│   │   └── com
│   │   └── xtuer
│   │   └── controller
│   │   └── HelloController.java
│   ├── resources
│   │   └── config
│   │   ├── spring-mvc.xml
│   │   └── spring-security.xml
│   └── webapp
│   └── WEB-INF
│   ├── view
│   │   └── fm
│   │   ├── admin.htm
│   │   └── hello.htm
│   └── web.xml
└── test
├── java
└── resources

Spring Security 入门

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
├── build.gradle
└── src
├── main
│   ├── java
│   │   └── com
│   │   └── xtuer
│   │   └── controller
│   │   └── HelloController.java
│   ├── resources
│   │   ├── config
│   │   │   ├── application-servlet.xml
│   │   │   └── spring-security.xml
│   │   └── logback.xml
│   └── webapp
│   └── WEB-INF
│   ├── page
│   │   ├── admin.html
│   │   └── hello.html
│   ├── static
│   │   ├── css
│   │   ├── img
│   │   ├── js
│   │   └── lib
│   └── web.xml
└── test
├── java
└── resources

Spotlight 快捷键

  • ⌘+D: 快速查字典
  • ⌘+L: 直接在 Spotlight 浏览名词解释
  • ⌘+B: 打开浏览器,在网页上搜索
  • ⌘+R: 打开档案所在的文件夹
  • ⌘+i: 查看档案详细信息

Mac 开发者软件推荐

下面列举一些 Mac 下开发者可能常用到的软件,大多数都是免费的,或者使用免费版也能够满足常用需求。

Homebrew

Homebrew 简称 brew,是 Mac OSX 上的软件包管理工具,能在 Mac 中方便的安装软件或者卸载软件,可以说 Homebrew 就是 Mac 下的 apt-get、yum 神器,安装软件只需要一个命令。

Homebrew 主页为 https://brew.sh/index_zh-cn.html,安装 Homebrew 只需要在终端执行下面的 Ruby 代码即可:

1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

常用命令可参考 http://qtdebug.com/mac-homebrew

Mac Homebrew

Homebrew 可以很方便的通过终端安装许多软件,例如 Tomcat,Redis,Gradle,Tree 等,和 Ubuntu 下的 apt-get 很像,下面列出一些 Homebrew 常用命令,以安装 tomcat 为例。

CentOS 7 简单使用

下载 CentOS

访问 https://www.centos.org/download/ 下载 Minimal ISO 即可,其他的虽然功能齐全,但是太大了。

必要工具

  • yum install zip unzip -y:

    1
    2
    3
    4
    5
    # 把文件夹 H5 和文件 x.html 压缩成 result.zip
    zip -r result.zip H5 x.html

    # 解压 filename.zip, 如无 -d 则解压到当前目录,有则解压到目录 dest-directory
    unzip filename.zip [-d dest-directory]
  • yum install bzip2 (解压 .bz2 文件)

  • yum install net-tools (安装后才能使用 ifconfig 等)

  • tar 解压 tar.gz: tar xf filename.tar.gz

  • 安装 tree: yum install tree

  • 安装 7z: yum install -y p7zip,如果不能用 yum 安装,可以自己编译

    1
    2
    3
    4
    5
    wget http://nchc.dl.sourceforge.net/project/p7zip/p7zip/9.20.1/p7zip_9.20.1_src_all.tar.bz2
    tar -jxvf p7zip_9.20.1_src_all.tar.bz2
    cd p7zip_9.20.1
    make
    make install
  • 安装 VIM (默认只安装了 VI,不能高亮搜索,不能语法高亮等)

    • 查看本机是否已经安装 VIM: rpm -qa | grep vim

      1
      2
      3
      vim-minimal-7.4.629-5.el6.x86_64
      vim-enhanced-7.4.629-5.el6_8.1.x86_64
      vim-common-7.4.629-5.el6_8.1.x86_64

      如果安装了则会显示上面 3 个包,缺少了的需要进行安装:

      • 缺少 vim-common: yum -y install vim-common
      • 缺少 vim-minimal: yum -y install vim-minimal
      • 缺少 vim-enhanced: yum -y install vim-enhanced

Java 解压 zip 文件

使用 Apache commons-compress 解压 zip 文件是件很幸福的事,可以解决 zip 包中文件名有中文时跨平台的乱码问题,不管文件是在 Windows 压缩的还是在 Mac,Linux 压缩的,解压后都没有再出现乱码问题了。

Java 访问 Redis

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API,和 Memcached 类似,它支持存储的 value 类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set – 有序集合)和 hash(哈希类型)。

Hexo 环境搭建

使用 Hexo 来搭建自己的个人静态博客:

  1. Markdown 写博客
  2. Hexo 生成 HTML
  3. Hexo 发布 HTML 到 Github Pages

既然是静态博客,那么就没有后台了,留言功能可以使用第三方的服务,例如畅言。

All Documents

Ajax

Cas

DB

FE

Gradle

Hexo

Index

Java

Mac

Misc

PHP

Qt

QtBook

Redis

SemanticUi

Spring

SpringBoot

SpringCore

SpringMVC

SpringSecurity

SpringWeb

Util

Vue

zTree

Spring Core

Spring IoC

Spring AOP

Scheduler