Java JDK 8 中的新特性

Java Platform, Standard Edition 8 是一个拥有丰富特性的主要版本。本文档总结了 Java SE 8、JDK 8 以及 Oracle 的 Java SE 8 实现中的特性和增强。单击组件名称可获取该组件增强功能更详细的描述。

  • Java 编程语言
    • Lambda 表达式是一个新的语言特性,已经在此版本中引入。该特性让您可以将功能视为方法参数,或者将代码视为数据。使用 Lambda 表达式,您可以更简洁地表示单方法接口(称为功能接口)的实例。
    • 方法引用为已经具有名称的方法提供了易于理解的 lambda 表达式。
    • 默认方法允许将新功能添加到库的接口中,并确保与为这些接口的旧版本编写的代码的二进制兼容性。
    • 重复批注支持对同一个声明或类型的使用多次应用相同的批注类型。
    • 类型批注支持在使用类型的任何地方应用批注,而不仅限于声明。与可插拔类型系统结合使用时,此特性可改进代码的类型检查。
    • 改进类型推断。
    • 方法参数反射。
  • 集合
    • 新的 java.util.stream 包中的类提供了一个 Stream API,支持对元素流进行函数式操作。Stream API 集成在 Collections API 中,可以对集合进行批量操作,例如顺序或并行的 map-reduce 转换。
    • 针对存在键冲突的 HashMap 的性能改进
  • 紧凑 profile包含 Java SE 平台的预定义子集,并且支持不需要在小型设备上部署和运行整个平台的应用。
  • 安全性
    • 默认启用客户端 TLS 1.2
    • AccessController.doPrivileged 的新变体支持代码断言其权限的子集,而不会阻止完全遍历堆栈来检查其他权限
    • 更强大的基于密码的加密算法
    • JSSE 服务器端支持 SSL/TLS 服务器名称指示 (SNI) 扩展
    • 支持 AEAD 算法:SunJCE 提供程序得到了增强,支持 AES/GCM/NoPadding 密码实现以及 GCM 算法参数。而且 SunJSSE 提供程序也得到了增强,支持基于 AEAD 模式的密码套件。请参阅 Oracle 提供程序文档,JEP 115。
    • 密钥库增强,包括新的域密钥库类型 java.security.DomainLoadStoreParameter 和为 keytool 实用程序新增的命令选项 -importpassword
    • SHA-224 消息摘要
    • 增强了对 NSA Suite B 加密的支持
    • 更好地支持高熵随机数生成
    • 新增了 java.security.cert.PKIXRevocationChecker 类,用于配置 X.509 证书的撤销检查
    • 适用于 Windows 的 64 位 PKCS11
    • Kerberos 5 重放缓存中新增了 rcache 类型
    • 支持 Kerberos 5 协议转换和受限委派
    • 默认禁用 Kerberos 5 弱加密类型
    • 适用于 GSS-API/Kerberos 5 机制的未绑定 SASL
    • 针对多个主机名称的 SASL 服务
    • JNI 桥接至 Mac OS X 上的原生 JGSS
    • SunJSSE 提供程序中支持更强大的临时 DH 密钥
    • JSSE 中支持服务器端加密套件首选项自定义
  • JavaFX
    • 本版本中实施了新的 Modena 主题。
    • 新的 SwingNode 类允许开发人员将 Swing 内容嵌入到 JavaFX 应用中。请参阅 SwingNode javadoc 和将 Swing 内容嵌入 JavaFX 应用中。
    • 新的 UI 控件包括 DatePickerTreeTableView 控件。
    • javafx.print 程序包为 JavaFX Printing API 提供了公共类。
    • 3D 图形特性现在包括 3D 形状、摄像头、灯光、子场景、材料、挑选和抗锯齿。JavaFX 3D 图形库中新增了 Shape3DBoxCylinderMeshViewSphere 子类)、SubSceneMaterialPickResultLightBaseAmbientLightPointLight子类)和 SceneAntialiasing API 类。此版本中的 Camera API 类也已更新。请参阅 javafx.scene.shape.Shape3Djavafx.scene.SubScenejavafx.scene.paint.Materialjavafx.scene.input.PickResultjavafx.scene.SceneAntialiasing 类的相关 javadoc 以及 JavaFX 3D 图形入门文档。
    • WebView 类包含新特性和改进。有关其他 HTML5 特性(包括 Web 套接字、Web 辅助进程和 Web 字体)
    • 增强了文本支持,包括双向文本、复杂文本脚本(如泰语和印地语控件)以及文本节点中的多行多样式文本。
    • 此版本添加了对 Hi-DPI 显示的支持。
    • CSS Styleable* 类已成为公共 API。有关更多信息,请参阅 Javafx.css javadoc。
    • 新的 ScheduledService 类允许自动重新启动服务。
    • JavaFX 现在可用于 ARM 平台。适用于 ARM 的 JDK 包含 JavaFX 的基础组件、图形组件和控制组件。
  • 工具
    • javadoc 工具支持新的 DocTree API,让您可以将 Javadoc 注释作为抽象语法树来进行遍历。
    • javadoc 工具支持新的 Javadoc Access API,让您可以直接从 Java 应用中调用 Javadoc 工具,而无需执行新的进程。
    • javadoc 工具现在支持检查 javadoc 注释的内容,从而避免在运行 javadoc 时生成的文件中产生各种问题,例如无效的 HTML 或可访问性问题。此特性默认为启用状态,可以通过新的 -Xdoclint 选项加以控制。有关更多详细信息,请参阅运行“javadoc -X”时的输出。javac 工具也支持此特性,但默认情况下并未启用它。
    • javac 命令的 -parameters 选项可用于存储正式参数名称,并启用反射 API 来检索正式参数名称。
    • javac 命令现已正确实施了 Java 语言规范 (JLS) 第 15.21 节中的相等运算符的类型规则。
    • javac 工具现在支持检查 javadoc 注释的内容,从而避免在运行 javadoc 时生成的文件中产生各种问题,例如无效的 HTML 或可访问性问题。可通过新的 Xdoclint 选项来启用此特性。有关更多详细信息,请参阅运行“javac-X”时的输出。此特性也可以在 javadoc 工具中使用,并且默认启用。
    • javac 工具现在支持根据需要生成原生标头。这样便无需在构建管道中单独运行 javah 工具。可以使用新的 -h 选项在 javac 中启用此特性,该选项用于指定写入头文件的目录。将为任何具有原生方法或者使用 java.lang.annotation.Native 类型的新批注的类进行批注的常量字段生成头文件。
    • 可通过 jjs 命令来调用 Nashorn 引擎。
    • java 命令用于启动 JavaFX 应用。
    • 重新编写了 java 手册页。
    • 可通过 jdeps 命令行工具来分析类文件。
    • Java Management Extensions (JMX) 支持远程访问诊断命令。
    • jarsigner 工具提供了一个选项用于请求获取时间戳机构 (TSA) 的签名时间戳。
    • Javac 工具
    • Javadoc 工具
  • 国际化
    • Unicode 增强,包括对 Unicode 6.2.0 的支持
    • 采用 Unicode CLDR 数据和 java.locale.providers 系统属性
    • 新增日历和区域设置 API
    • 支持将自定义资源包作为扩展进行安装
  • 部署
    • 现在可以使用 URLPermission 允许沙盒小程序和 Java Web Start 应用连接回启动它们的服务器。不再授予 SocketPermission
    • 在所有安全级别,主 JAR 文件的 JAR 文件清单中都需要 Permissions 属性。
  • Date-Time 程序包 — 一组新程序包,提供全面的日期-时间模型。
  • 脚本编写
    • Rhino Javascript 引擎已被替换为 Nashorn JavaScript 引擎
  • Pack200
    • Pack200 支持 JSR 292 引入的常量池条目和新字节码
    • JDK8 支持 JSR-292、JSR-308 和 JSR-335 指定的类文件更改
  • IO 和 NIO
    • 全新的基于 Solaris 事件端口机制的面向 Solaris 的 SelectorProvider 实现。要使用它,请将系统属性 java.nio.channels.spi.Selector 的值设置为 sun.nio.ch.EventPortSelectorProvider
    • 减小 <JDK_HOME>/jre/lib/charsets.jar 文件的大小
    • 提高了 java.lang.String(byte[], *) 构造函数和 java.lang.String.getBytes() 方法的性能。
  • java.lang 和 java.util 程序包
    • 并行数组排序
    • 标准编码和解码 Base64
    • 无符号算术支持
  • JDBC
    • 删除了 JDBC-ODBC Bridge。
    • JDBC 4.2 引入了新特性。
  • Java DB
    • JDK 8 包含 Java DB 10.10。
  • 网络
    • 已添加 java.net.URLPermission 类。
    • java.net.HttpURLConnection 类中,如果安装了安全管理器,那么请求打开连接的调用需要权限。
  • 并发性
    • java.util.concurrent 程序包中新增了一些类和接口。
    • java.util.concurrent.ConcurrentHashMap 类中新增了一些方法,支持基于新增流工具和 lambda 表达式的聚合操作。
    • java.util.concurrent.atomic 程序包中新增了一些类来支持可扩展、可更新的变量。
    • java.util.concurrent.ForkJoinPool 类中新增了一些方法来支持通用池。
    • 新增的 java.util.concurrent.locks.StampedLock 类提供了一个基于能力的锁,可通过三种模式来控制读/写访问。
  • Java XML – JAXP
  • HotSpot
    • 新增的硬件内部函数以便使用高级加密标准 (AES)。UseAESUseAESIntrinsics 标志用于为 Intel 硬件启用基于硬件的 AES 内部函数。硬件必须是 2010 年或更新的 Westmere 硬件。例如,要启用硬件 AES,请使用以下标志: -XX:+UseAES -XX:+UseAESIntrinsics 要禁用硬件 AES,请使用以下标志: -XX:-UseAES -XX:-UseAESIntrinsics
    • 删除了 PermGen。
    • 方法调用的字节码指令支持 Java 编程语言中的默认方法。
  • Java Mission Control 5.3 版本说明
    • JDK 8 包含 Java Mission Control 5.3。

java日期时间工具类

工具类继承了OutPut类,这个类只是提供了一个out()的静态方法,用于测试。

package system.utils;

import system.lib.OutPut;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.*;
import java.util.Date;
import java.util.Locale;

/**
 * Created by alan on 2019/4/19.
 *
 * ********************************
 * getTime():1555776871585
 * getTimeInt():1555776871
 * getLocalDate():2019-04-21
 * parseLocalDate("2019-04-20",1):2019-04-20
 * parseLocalDate(2019,04,20):2019-04-20
 * plus(getLocalDate(),2,ChronoUnit.DAYS):2019-04-23
 * --------------------------------
 * getLocalTime():00:14:31.585
 * parseLocalTime("23:56:00"):23:56
 * parseLocalTime(23,56,12):23:56:12
 * plus(getLocalTime(),-3,ChronoUnit.HOURS):21:14:31.585
 * --------------------------------
 * getLocalDateTime():2019-04-21T00:14:31.585
 * parseLocalDateTime("2019-04-20 21:05:56",1):2019-04-20T21:05:56
 * parseLocalDateTime(2019,4,20,21,05,56):2019-04-20T21:05:56
 * plus(getLocalDateTime(),-1,ChronoUnit.MONTHS):2019-03-21T00:14:31.585
 * --------------------------------
 * format(int t):2019-04-21T00:14:31
 * format(long t):2019-04-21T00:14:31.585
 * format(int t,1):2019-4-21 0:14:31
 * format(long t,1):2019-4-21 0:14:31
 * format(LocalDate d,1):2019-4-21
 * format(LocalTime t):0:14:31
 * format(LocalDateTime t,1):2019-4-21 0:14:31
 * format(ZonedDateTime.now(),1):2019-4-21 0:14:31
 * format(LocalDate d,DateTimeFormatter.ISO_DATE):2019-04-21
 * format(LocalTime t,DateTimeFormatter.ISO_TIME):00:14:31.585
 * format(LocalDateTime t,DateTimeFormatter.ISO_DATE_TIME):2019-04-21T00:14:31.585
 * format(ZonedDateTime t,DateTimeFormatter.ISO_DATE_TIME):2019-04-21T00:14:31.585+08:00[Asia/Shanghai]
 * format(LocalDateTime t,DATE_TIME_FULL):2019-04-21 00:14:31
 * format(int i,DATE_TIME_FULL):2019-04-21 00:14:31
 * format(long l,DATE_TIME_FULL):2019-04-21 00:14:31
 * --------------------------------
 * getYear():2019
 * getMonthI():4
 * getMonth():APRIL
 * getMonthS():四月
 * getDayOfMonth():21
 * getDayOfYear():111
 * getDayOfMonthMax():30
 * getWeek():星期日
 * getWeekI():7
 * getDate():Sun Apr 21 00:14:31 CST 2019
 * getTimestamp():2019-04-21 00:14:31.587
 * getTimestampL():2019-04-21 00:14:31.587
 * getHour():0
 * getMinute():14
 * getSecond():31
 */
public class DateTimeUtils extends OutPut {

    public static final String YEAR = "yyyy";
    public static final String MONTH = "MM";
    public static final String DAY = "dd";
    public static final String DATE_FULL = "yyyy-MM-dd";
    public static final String DATE_FULL2 = "yyyyMMdd";
    public static final String DATE_TIME_FULL = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_TIME_FULL2 = "yyyyMMddHHmmss";
    public static final String WEEK = "EEEE";

    private static final int ZONE_HOUR = 8;

    public DateTimeUtils() {

    }

    /**
     * 取时间戳
     *
     * @return long
     */
    public static long getTime() {
        return System.currentTimeMillis();
    }

    /**
     * 取时间戳
     *
     * @return int
     */
    public static int getTimeInt() {
        return (int) (getTime() / 1000);
    }

    /**
     * 取本地日期对象
     *
     * @return LocalDate
     */
    public static LocalDate getLocalDate() {
        return LocalDate.now();
    }

    /**
     * 字符串日期转本地日期对象
     *
     * @param str    2012/01/01|2012-01-01
     * @param format 1|2
     * @return LocalDate
     */
    public static LocalDate parseLocalDate(String str, int format) {
        /**
         * format:1=-,2=/
         */
        String regx = "/";
        if (1 == format) {
            regx = "-";
        }
        String[] s = str.split(regx);
        return parseLocalDate(Integer.valueOf(s[0]), Integer.valueOf(s[1]), Integer.valueOf(s[2]));
    }

    /**
     * 整数日期转本地日期对象
     *
     * @param y 年
     * @param m 月
     * @param d 日
     * @return LocalDate
     */
    public static LocalDate parseLocalDate(int y, int m, int d) {
        return LocalDate.of(y, m, d);
    }

    /**
     * 本地日期增减
     *
     * @param date 本地日期
     * @param n    +正数则增加;-负数则减去
     * @param unit ChronoUnit.DAYS|ChronoUnit.YEARS|ChronoUnit.MONTHS
     * @return LocalDate
     */
    public static LocalDate plus(LocalDate date, int n, ChronoUnit unit) {
        return date.plus(n, unit);
    }

    /**
     * 取本地时间对象
     *
     * @return LocalTime
     */
    public static LocalTime getLocalTime() {
        return LocalTime.now();
    }

    /**
     * 本地时间增减
     *
     * @param time 本地时间
     * @param n    +正数则增加;-负数则减去
     * @param unit ChronoUnit.HOURS|ChronoUnit.MINUTES|ChronoUnit.SECONDS
     * @return LocalTime
     */
    public static LocalTime plus(LocalTime time, int n, ChronoUnit unit) {
        return time.plus(n, unit);
    }

    /**
     * 字符串时间转本地时间对象
     *
     * @param time 00:00:00
     * @return LocalTime
     */
    public static LocalTime parseLocalTime(String time) {
        String[] s = time.split(":");
        return parseLocalTime(Integer.valueOf(s[0]), Integer.valueOf(s[1]), Integer.valueOf(s[2]));
    }

    /**
     * 整数时间转本地时间对象
     *
     * @param h 小时
     * @param m 分钟
     * @param s 秒
     * @return LocalTime
     */
    public static LocalTime parseLocalTime(int h, int m, int s) {
        return LocalTime.of(h, m, s);
    }

    /**
     * 获取本地日期时间对象
     *
     * @return
     */
    public static LocalDateTime getLocalDateTime() {
        return LocalDateTime.now();
    }

    /**
     * 本地日期时间增减
     *
     * @param time 本地日期时间
     * @param n    +正数则增加;-负数则减去
     * @param unit ChronoUnit.DAYS|ChronoUnit.YEARS|ChronoUnit.MONTHS|ChronoUnit.HOURS|ChronoUnit.MINUTES|ChronoUnit.SECONDS
     * @return LocalDateTime
     */
    public static LocalDateTime plus(LocalDateTime time, int n, ChronoUnit unit) {
        return time.plus(n, unit);
    }

    /**
     * 本地日期增减
     *
     * @param time 本地时间
     * @param n    +正数则增加;-负数则减去
     * @param unit ChronoUnit.DAYS|ChronoUnit.YEARS|ChronoUnit.MONTHS
     * @return LocalDate
     */
    public static LocalDate plusDate(LocalDate time, int n, ChronoUnit unit) {
        return time.plus(n, unit);
    }

    /**
     * 本地时间增减
     *
     * @param time 本地时间
     * @param n    +正数则增加;-负数则减去
     * @param unit ChronoUnit.HOURS|ChronoUnit.MINUTES|ChronoUnit.SECONDS
     * @return LocalTime
     */
    public static LocalTime plusTime(LocalTime time, int n, ChronoUnit unit) {
        return time.plus(n, unit);
    }

    /**
     * 字符串日期时间转本地日期时间对象
     *
     * @param datetime string like it:2019-01-01 00:00:00 other is 2019/01/01 00:00:00
     * @param format   if == 1 then 2019-01-01 00:00:00 other is 2019/01/01 00:00:00
     * @return null|LocalDateTime
     */
    public static LocalDateTime parseLocalDateTime(String datetime, int format) {
        String[] x = datetime.split(" ");
        if (x.length != 2) {
            return null;
        }
        String regx = "/";
        if (1 == format) {
            regx = "-";
        }
        String[] d = x[0].split(regx);
        String[] s = x[1].split(":");
        return parseLocalDateTime(Integer.valueOf(d[0]), Integer.valueOf(d[1]), Integer.valueOf(d[2]),
                Integer.valueOf(s[0]), Integer.valueOf(s[1]), Integer.valueOf(s[2]));
    }

    /**
     * 整数日期时间转本地日期时间对象
     *
     * @param y 年
     * @param m 月
     * @param d 日
     * @param h 小时
     * @param i 分钟
     * @param s 秒
     * @return LocalDateTime
     */
    public static LocalDateTime parseLocalDateTime(int y, int m, int d, int h, int i, int s) {
        return LocalDateTime.of(y, m, d, h, i, s);
    }

    /**
     * 格式化当前时间
     * @return
     */
    public static String format() {
        return format(getTime(),1);
    }

    /**
     * 秒时间戳转本地日期时间对象
     *
     * @param datetime 秒时间戳
     * @return LocalDateTime
     */
    public static LocalDateTime format(int datetime) {
        return format((long) datetime * 1000L);
    }

    /**
     * 微秒时间戳转本地日期时间对象
     *
     * @param datetime 微秒时间戳
     * @return LocalDateTime
     */
    public static LocalDateTime format(long datetime) {
        LocalDateTime localDateTime = Instant.ofEpochMilli(datetime).atZone(ZoneOffset.systemDefault()).toLocalDateTime();
        return localDateTime;
    }

    /**
     * 秒时间戳格式化字符串文本
     *
     * @param datetime 秒时间戳
     * @param format   格式化字符串
     * @return String
     */
    public static String format(int datetime, int format) {
        return format((long) datetime * 1000L, format);
    }

    /**
     * 微秒时间戳格式化字符串文本
     *
     * @param datetime 微秒时间戳
     * @param format   格式化字符串
     * @return String
     */
    public static String format(long datetime, int format) {
        return format(format(datetime), format);
    }

    /**
     * 本地日期对象格式化文本
     *
     * @param date   本地日期对象
     * @param format 1~2
     * @return String
     */
    public static String format(LocalDate date, int format) {
        String regx = "/";
        if (1 == format) {
            regx = "-";
        }
        StringBuffer st = new StringBuffer();
        st.append(date.getYear()).append(regx)
                .append(date.getMonthValue()).append(regx)
                .append(date.getDayOfMonth());
        return st.toString();
    }


    /**
     * 本地时间对象格式化文本
     *
     * @param time 本地时间对象
     * @return String
     */
    public static String format(LocalTime time) {
        StringBuffer st = new StringBuffer();
        st.append(time.getHour()).append(":")
                .append(time.getMinute()).append(":")
                .append(time.getSecond());
        return st.toString();
    }

    /**
     * 本地日期时间对象格式化文本
     *
     * @param dateTime 本地日期时间对象
     * @param format   1~2
     * @return String
     */
    public static String format(LocalDateTime dateTime, int format) {
        String regx = "/";
        if (1 == format) {
            regx = "-";
        }
        StringBuffer st = new StringBuffer();
        st.append(dateTime.getYear()).append(regx)
                .append(dateTime.getMonthValue()).append(regx)
                .append(dateTime.getDayOfMonth()).append(" ")
                .append(dateTime.getHour()).append(":")
                .append(dateTime.getMinute()).append(":")
                .append(dateTime.getSecond());
        return st.toString();
    }

    /**
     * 时区时间格式化文本
     *
     * @param dateTime 时区时间对象
     * @param format 1~2
     * @return String
     */
    public static String format(ZonedDateTime dateTime, int format) {
        String regx = "/";
        if (1 == format) {
            regx = "-";
        }
        StringBuffer st = new StringBuffer();
        st.append(dateTime.getYear()).append(regx)
                .append(dateTime.getMonthValue()).append(regx)
                .append(dateTime.getDayOfMonth()).append(" ")
                .append(dateTime.getHour()).append(":")
                .append(dateTime.getMinute()).append(":")
                .append(dateTime.getSecond());
        return st.toString();
    }

    /**
     * 格式化本地日期
     * @param date 本地日期对象
     * @param format 日期时间格式化对象:DateTimeFormatter.ISO_DATE
     * @return String
     */
    public static String format(LocalDate date, DateTimeFormatter format) {
        return format.format(date);
    }

    /**
     * 格式化本地时间
     * @param time 本地时间对象
     * @param format 日期时间格式化对象:DateTimeFormatter.ISO_TIME
     * @return String
     */
    public static String format(LocalTime time, DateTimeFormatter format) {
        return format.format(time);
    }

    /**
     * 格式化本地日期时间
     * @param dateTime 本地日期时间对象
     * @param format 日期时间格式化对象:DateTimeFormatter.ISO_LOCAL_DATE_TIME|ISO_DATE_TIME
     * @return String
     */
    public static String format(LocalDateTime dateTime, DateTimeFormatter format) {
        return format.format(dateTime);
    }

    /**
     * 格式化时区日期时间
     * @param dateTime 时区日期时间对象
     * @param format 日期格式化对象:DateTimeFormatter.ISO_ZONED_DATE_TIME|ISO_DATE_TIME
     * @return String
     */
    public static String format(ZonedDateTime dateTime, DateTimeFormatter format) {
        return format.format(dateTime);
    }

    /**
     * 取Date对象
     * @return Date
     */
    public static Date getDate() {
        return Date.from(Instant.now());
    }

    /**
     * 取Timestamp对象
     * @return Timestamp
     */
    public static Timestamp getTimestamp() {
        return Timestamp.from(Instant.now());
    }

    /**
     * 取Timestamp对象
     * @return Timestamp
     */
    public static Timestamp getTimestampL() {
        return Timestamp.valueOf(getLocalDateTime());
    }

    /**
     * 获取星期
     *
     * @return like 星期六|?
     */
    public static String getWeek() {
        return getLocalDate().getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.getDefault());
    }

    /**
     * 获取星期
     *
     * @return like 1~7
     */
    public static int getWeekI() {
        return getLocalDate().getDayOfWeek().getValue();
    }

    /**
     * 获取当天日(按月)
     * @return int
     */
    public static int getDayOfMonth() {
        return getLocalDate().getDayOfMonth();
    }

    /**
     * 获取当天日(按年)
     * @return int
     */
    public static int getDayOfYear() {
        return getLocalDate().getDayOfYear();
    }

    /**
     * 获取当月最后一天
     * @return int
     */
    public static int getDayOfMonthMax() {
        return getMonth().maxLength();
    }

    /**
     * 获取Month对象
     * @return Month
     */
    public static Month getMonth() {
        return getLocalDate().getMonth();
    }

    /**
     * 获取月份(当地格式)
     * @return String|六月
     */
    public static String getMonthS() {
        return getMonth().getDisplayName(TextStyle.FULL, Locale.getDefault());
    }

    /**
     * 获取月份
     * @return int
     */
    public static int getMonthI() {
        return getMonth().getValue();
    }

    /**
     * 取年份
     * @return int|2019
     */
    public static int getYear() {
        return getLocalDate().getYear();
    }

    /**
     * 取小时
     * @return int|0~23
     */
    public static int getHour() {
        return getLocalTime().getHour();
    }

    /**
     * 取分钟
     * @return int|0~59
     */
    public static int getMinute() {
        return getLocalTime().getMinute();
    }

    /**
     * 取秒
     * @return int|0~59
     */
    public static int getSecond() {
        return getLocalTime().getSecond();
    }

    /**
     * 格式化本地日期时间对象
     * @param dateTime 本地日期时间对象
     * @param pattern  public static final String YEAR = "yyyy";
     *                 public static final String MONTH = "MM";
     *                 public static final String DAY = "dd";
     *                 public static final String FULL_DATE = "yyyy-MM-dd";
     *                 public static final String FULL_DATE_Q = "yyyyMMdd";
     *                 public static final String FULL_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
     *                 public static final String FULL_DATE_TIME_Q = "yyyyMMddHHmmss";
     *                 public static final String WEEK = "EEEE";
     * @return String
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(Date.from(dateTime.atZone(ZoneOffset.systemDefault()).toInstant()));
    }

    /**
     * 格式化日期时间(整数)
     * @param dateTime 时间戳
     * @param pattern 格式化文本
     * @return String
     */
    public static String format(int dateTime, String pattern) {
        return format((long) dateTime * 1000L, pattern);
    }

    /**
     * 格式化日期时间(长整数)
     * @param dateTime 微秒时间戳
     * @param pattern 格式化文本
     * @return String
     */
    public static String format(long dateTime, String pattern) {
        return format(format(dateTime), pattern);
    }

    public static void main(String[] args) {
        out("********************************");
        out("getTime():"+getTime());
        out("getTimeInt():"+getTimeInt());
        out("getLocalDate():"+getLocalDate());
        out("parseLocalDate(\"2019-04-20\",1):"+parseLocalDate("2019-04-20",1));
        out("parseLocalDate(2019,04,20):"+parseLocalDate(2019,04,20));
        out("plus(getLocalDate(),2,ChronoUnit.DAYS):"+plus(getLocalDate(),2,ChronoUnit.DAYS));
        out("--------------------------------");
        out("getLocalTime():"+getLocalTime());
        out("parseLocalTime(\"23:56:00\"):"+parseLocalTime("23:56:00"));
        out("parseLocalTime(23,56,12):"+parseLocalTime(23,56,12));
        out("plus(getLocalTime(),-3,ChronoUnit.HOURS):"+plus(getLocalTime(),-3,ChronoUnit.HOURS));
        out("--------------------------------");
        out("getLocalDateTime():"+getLocalDateTime());
        out("parseLocalDateTime(\"2019-04-20 21:05:56\",1):"+parseLocalDateTime("2019-04-20 21:05:56",1));
        out("parseLocalDateTime(2019,4,20,21,05,56):"+parseLocalDateTime(2019,4,20,21,05,56));
        out("plus(getLocalDateTime(),-1,ChronoUnit.MONTHS):"+plus(getLocalDateTime(),-1,ChronoUnit.MONTHS));
        out("--------------------------------");
        out("format(int t):"+format(getTimeInt()));
        out("format(long t):"+format(getTime()));
        out("format(int t,1):"+format(getTimeInt(),1));
        out("format(long t,1):"+format(getTime(),1));
        out("format(LocalDate d,1):"+format(getLocalDate(),1));
        out("format(LocalTime t):"+format(getLocalTime()));
        out("format(LocalDateTime t,1):"+format(getLocalDateTime(),1));
        out("format(ZonedDateTime.now(),1):"+format(ZonedDateTime.now(),1));
        out("format(LocalDate d,DateTimeFormatter.ISO_DATE):"+format(getLocalDate(),DateTimeFormatter.ISO_DATE));
        out("format(LocalTime t,DateTimeFormatter.ISO_TIME):"+format(getLocalTime(),DateTimeFormatter.ISO_TIME));
        out("format(LocalDateTime t,DateTimeFormatter.ISO_DATE_TIME):"+format(getLocalDateTime(),DateTimeFormatter.ISO_DATE_TIME));
        out("format(ZonedDateTime t,DateTimeFormatter.ISO_DATE_TIME):"+format(ZonedDateTime.now(),DateTimeFormatter.ISO_DATE_TIME));
        out("format(LocalDateTime t,DATE_TIME_FULL):"+format(getLocalDateTime(),DATE_TIME_FULL));
        out("format(int i,DATE_TIME_FULL):"+format(getTimeInt(),DATE_TIME_FULL));
        out("format(long l,DATE_TIME_FULL):"+format(getTime(),DATE_TIME_FULL));
        out("--------------------------------");
        out("getYear():"+getYear());
        out("getMonthI():"+getMonthI());
        out("getMonth():"+getMonth());
        out("getMonthS():"+getMonthS());
        out("getDayOfMonth():"+getDayOfMonth());
        out("getDayOfYear():"+getDayOfYear());
        out("getDayOfMonthMax():"+getDayOfMonthMax());
        out("getWeek():"+getWeek());
        out("getWeekI():"+getWeekI());
        out("getDate():"+getDate());
        out("getTimestamp():"+getTimestamp());
        out("getTimestampL():"+getTimestampL());
        out("getHour():"+getHour());
        out("getMinute():"+getMinute());
        out("getSecond():"+getSecond());


    }
}

CSS样式形状

PS:代码来源于网络。

CSS能够生成各种形状。正方形和矩形很容易,因为它们是 web 的自然形状。添加宽度和高度,就得到了所需的精确大小的矩形。添加边框半径,你就可以把这个形状变成圆形,足够多的边框半径,你就可以把这些矩形变成圆形和椭圆形。

我们还可以使用 CSS 伪元素中的 ::before::after,这为我们提供了向原始元素添加另外两个形状的可能性。通过巧妙地使用定位、转换和许多其他技巧,我们可以只用一个 HTML 元素在 CSS 中创建许多形状。

1.正方形

1555920540-9852-o88wosemav
#square {
  width: 100px;
  height: 100px;
  background: red;
}

2.长方形

1555920541-6008-rj4xn4mycs
#rectangle {
  width: 200px;
  height: 100px;
  background: red;
}

3.圆形

1555920540-5020-52z7b78uym
#circle {
  width: 100px;
  height: 100px;
  background: red;
  border-radius: 50%
}

4.椭圆形

1555920540-6489-u5866htngx
#oval {
  width: 200px;
  height: 100px;
  background: red;
  border-radius: 100px / 50px;
}

5.上三角

1555920540-9812-v5w2fgnwuw
#triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}

6.下三角

1555920541-2519-mna60vffgb
#triangle-down {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-top: 100px solid red;
}

7.左三角

1555920548-6518-mazrvjyfbf
#triangle-left {
  width: 0;
  height: 0;
  border-top: 50px solid transparent;
  border-right: 100px solid red;
  border-bottom: 50px solid transparent;
}

8.右三角

1555920548-3876-dbkk3ni2pn
#triangle-right {
  width: 0;
  height: 0;
  border-top: 50px solid transparent;
  border-left: 100px solid red;
  border-bottom: 50px solid transparent;
}

9.左上角

1555920548-7309-5281l9kr4j
#triangle-topleft {
  width: 0;
  height: 0;
  border-top: 100px solid red;
  border-right: 100px solid transparent;
}

10.右上角

1555920548-7953-6usd6ua1sm
#triangle-topright {
  width: 0;
  height: 0;
  border-top: 100px solid red;
  border-left: 100px solid transparent;
}

11.左下角

1555920548-1871-6cfqjsgqzj
#triangle-bottomleft {
  width: 0;
  height: 0;
  border-bottom: 100px solid red;
  border-right: 100px solid transparent;
}

12.右下角

1555920548-8490-it3p7fpxak
#triangle-bottomright {
  width: 0;
  height: 0;
  border-bottom: 100px solid red;
  border-left: 100px solid transparent;
}

13.箭头

1555920556-9955-94kri0bujn
#curvedarrow {
  position: relative;
  width: 0;
  height: 0;
  border-top: 9px solid transparent;
  border-right: 9px solid red;
  transform: rotate(10deg);
}
#curvedarrow:after {
  content: "";
  position: absolute;
  border: 0 solid transparent;
  border-top: 3px solid red;
  border-radius: 20px 0 0 0;
  top: -12px;
  left: -9px;
  width: 12px;
  height: 12px;
  transform: rotate(45deg);
}

14.梯形

1555920555-8764-89vuvjwknv
#trapezoid {
  border-bottom: 100px solid red;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  height: 0;
  width: 100px;
}

15.平行四边形

1555920556-1272-85ekanr2mk
#parallelogram {
  width: 150px;
  height: 100px;
  transform: skew(20deg);
  background: red;
}

16.星星 (6角)

1555920555-9404-luli3pn3js
#star-six {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
  position: relative;
}
#star-six:after {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-top: 100px solid red;
  position: absolute;
  content: "";
  top: 30px;
  left: -50px;
}

17.星星 (5角)

1555920555-5612-u6j9nn5zrt
#star-five {
  margin: 50px 0;
  position: relative;
  display: block;
  color: red;
  width: 0px;
  height: 0px;
  border-right: 100px solid transparent;
  border-bottom: 70px solid red;
  border-left: 100px solid transparent;
  transform: rotate(35deg);
}
#star-five:before {
  border-bottom: 80px solid red;
  border-left: 30px solid transparent;
  border-right: 30px solid transparent;
  position: absolute;
  height: 0;
  width: 0;
  top: -45px;
  left: -65px;
  display: block;
  content: '';
  transform: rotate(-35deg);
}
#star-five:after {
  position: absolute;
  display: block;
  color: red;
  top: 3px;
  left: -105px;
  width: 0px;
  height: 0px;
  border-right: 100px solid transparent;
  border-bottom: 70px solid red;
  border-left: 100px solid transparent;
  transform: rotate(-70deg);
  content: '';
}

18.五边形

1555920555-5853-39fj96ppzf
#pentagon {
  position: relative;
  width: 54px;
  box-sizing: content-box;
  border-width: 50px 18px 0;
  border-style: solid;
  border-color: red transparent;
}
#pentagon:before {
  content: "";
  position: absolute;
  height: 0;
  width: 0;
  top: -85px;
  left: -18px;
  border-width: 0 45px 35px;
  border-style: solid;
  border-color: transparent transparent red;
}

19.六边形

1555920562-9701-85tfgk090z
#hexagon {
  width: 100px;
  height: 55px;
  background: red;
  position: relative;
}
#hexagon:before {
  content: "";
  position: absolute;
  top: -25px;
  left: 0;
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 25px solid red;
}
#hexagon:after {
  content: "";
  position: absolute;
  bottom: -25px;
  left: 0;
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-top: 25px solid red;
}

20.八边形

1555920562-3808-6keelsm0vb
#octagon {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
}
#octagon:before {
  content: "";
  width: 100px;
  height: 0;
  position: absolute;
  top: 0;
  left: 0;
  border-bottom: 29px solid red;
  border-left: 29px solid #eee;
  border-right: 29px solid #eee;
}
#octagon:after {
  content: "";
  width: 100px;
  height: 0;
  position: absolute;
  bottom: 0;
  left: 0;
  border-top: 29px solid red;
  border-left: 29px solid #eee;
  border-right: 29px solid #eee;
}

21.爱心

1555920563-9495-qlc2eyp66r
#heart {
  position: relative;
  width: 100px;
  height: 90px;
}
#heart:before,
#heart:after {
  position: absolute;
  content: "";
  left: 50px;
  top: 0;
  width: 50px;
  height: 80px;
  background: red;
  border-radius: 50px 50px 0 0;
  transform: rotate(-45deg);
  transform-origin: 0 100%;
}
#heart:after {
  left: 0;
  transform: rotate(45deg);
  transform-origin: 100% 100%;
}

22.无穷大

1555920562-6265-yq1e4m8kjd
#infinity {
  position: relative;
  width: 212px;
  height: 100px;
  box-sizing: content-box;
}
#infinity:before,
#infinity:after {
  content: "";
  box-sizing: content-box;
  position: absolute;
  top: 0;
  left: 0;
  width: 60px;
  height: 60px;
  border: 20px solid red;
  border-radius: 50px 50px 0 50px;
  transform: rotate(-45deg);
}
#infinity:after {
  left: auto;
  right: 0;
  border-radius: 50px 50px 50px 0;
  transform: rotate(45deg);
}

23.菱形

1555920562-1011-cr6nbch1a1
#diamond {
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-bottom-color: red;
  position: relative;
  top: -50px;
}
#diamond:after {
  content: '';
  position: absolute;
  left: -50px;
  top: 50px;
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-top-color: red;
}

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

24.钻石1

1555920563-2362-aq5env1pic
#diamond-shield {
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-bottom: 20px solid red;
  position: relative;
  top: -50px;
}
#diamond-shield:after {
  content: '';
  position: absolute;
  left: -50px;
  top: 20px;
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-top: 70px solid red;
}

25.钻石2

1555920570-6519-41iu9fau8q
#cut-diamond {
  border-style: solid;
  border-color: transparent transparent red transparent;
  border-width: 0 25px 25px 25px;
  height: 0;
  width: 50px;
  box-sizing: content-box;
  position: relative;
  margin: 20px 0 50px 0;
}
#cut-diamond:after {
  content: "";
  position: absolute;
  top: 25px;
  left: -25px;
  width: 0;
  height: 0;
  border-style: solid;
  border-color: red transparent transparent transparent;
  border-width: 70px 50px 0 50px;
}

26.钻戒

1555920570-3764-7zt0mxmacs
#diamond-narrow {
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-bottom: 70px solid red;
  position: relative;
  top: -50px;
}
#diamond-narrow:after {
  content: '';
  position: absolute;
  left: -50px;
  top: 70px;
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-top: 70px solid red;
}

27. 鸡蛋

1555920570-3901-90u4mhvc51
#egg {
  display: block;
  width: 126px;
  height: 180px;
  background-color: red;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
}

28.吃豆人

1555920570-4027-lix78qjb2p
#pacman {
  width: 0px;
  height: 0px;
  border-right: 60px solid transparent;
  border-top: 60px solid red;
  border-left: 60px solid red;
  border-bottom: 60px solid red;
  border-top-left-radius: 60px;
  border-top-right-radius: 60px;
  border-bottom-left-radius: 60px;
  border-bottom-right-radius: 60px;
}

29.对话泡泡

1555920570-2424-5eb6e64ju8
#talkbubble {
  width: 120px;
  height: 80px;
  background: red;
  position: relative;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
}
#talkbubble:before {
  content: "";
  position: absolute;
  right: 100%;
  top: 26px;
  width: 0;
  height: 0;
  border-top: 13px solid transparent;
  border-right: 26px solid red;
  border-bottom: 13px solid transparent;
}

30. 12点 爆发

1555920570-3819-xss6p6taac
#burst-12 {
  background: red;
  width: 80px;
  height: 80px;
  position: relative;
  text-align: center;
}
#burst-12:before,
#burst-12:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 80px;
  width: 80px;
  background: red;
}
#burst-12:before {
  transform: rotate(30deg);
}
#burst-12:after {
  transform: rotate(60deg);
}

31. 8点 爆发

1555920577-6692-5c7v2mdrgb
#burst-8 {
  background: red;
  width: 80px;
  height: 80px;
  position: relative;
  text-align: center;
  transform: rotate(20deg);
}
#burst-8:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 80px;
  width: 80px;
  background: red;
  transform: rotate(135deg);
}

32.太极

1555920577-9643-wjx9rogtp2
#yin-yang {
  width: 96px;
  box-sizing: content-box;
  height: 48px;
  background: #eee;
  border-color: red;
  border-style: solid;
  border-width: 2px 2px 50px 2px;
  border-radius: 100%;
  position: relative;
}
#yin-yang:before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  background: #eee;
  border: 18px solid red;
  border-radius: 100%;
  width: 12px;
  height: 12px;
  box-sizing: content-box;
}
#yin-yang:after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: red;
  border: 18px solid #eee;
  border-radius: 100%;
  width: 12px;
  height: 12px;
  box-sizing: content-box;
}

33.徽章丝带

1555920577-4075-nd4r68sv4z
#badge-ribbon {
  position: relative;
  background: red;
  height: 100px;
  width: 100px;
  border-radius: 50px;
}
#badge-ribbon:before,
#badge-ribbon:after {
  content: '';
  position: absolute;
  border-bottom: 70px solid red;
  border-left: 40px solid transparent;
  border-right: 40px solid transparent;
  top: 70px;
  left: -10px;
  transform: rotate(-140deg);
}
#badge-ribbon:after {
  left: auto;
  right: -10px;
  transform: rotate(140deg);
}

34.太空入侵者(电脑游戏名)

1555920578-4427-dzgg8erh4x
#space-invader {
  box-shadow: 0 0 0 1em red,
  0 1em 0 1em red,
  -2.5em 1.5em 0 .5em red,
  2.5em 1.5em 0 .5em red,
  -3em -3em 0 0 red,
  3em -3em 0 0 red,
  -2em -2em 0 0 red,
  2em -2em 0 0 red,
  -3em -1em 0 0 red,
  -2em -1em 0 0 red,
  2em -1em 0 0 red,
  3em -1em 0 0 red,
  -4em 0 0 0 red,
  -3em 0 0 0 red,
  3em 0 0 0 red,
  4em 0 0 0 red,
  -5em 1em 0 0 red,
  -4em 1em 0 0 red,
  4em 1em 0 0 red,
  5em 1em 0 0 red,
  -5em 2em 0 0 red,
  5em 2em 0 0 red,
  -5em 3em 0 0 red,
  -3em 3em 0 0 red,
  3em 3em 0 0 red,
  5em 3em 0 0 red,
  -2em 4em 0 0 red,
  -1em 4em 0 0 red,
  1em 4em 0 0 red,
  2em 4em 0 0 red;
  background: red;
  width: 1em;
  height: 1em;
  overflow: hidden;
  margin: 50px 0 70px 65px;
}

35.电视

1555920577-9174-pajfavgico
#tv {
  position: relative;
  width: 200px;
  height: 150px;
  margin: 20px 0;
  background: red;
  border-radius: 50% / 10%;
  color: white;
  text-align: center;
  text-indent: .1em;
}
#tv:before {
  content: '';
  position: absolute;
  top: 10%;
  bottom: 10%;
  right: -5%;
  left: -5%;
  background: inherit;
  border-radius: 5% / 50%;
}

36.雪佛龙

1555920578-4004-8fxu68r0ac
#chevron {
  position: relative;
  text-align: center;
  padding: 12px;
  margin-bottom: 6px;
  height: 60px;
  width: 200px;
}
#chevron:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 51%;
  background: red;
  transform: skew(0deg, 6deg);
}
#chevron:after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 50%;
  background: red;
  transform: skew(0deg, -6deg);
}

37.放大镜

1555920585-4418-bavd9hoid4
#magnifying-glass {
  font-size: 10em;
  display: inline-block;
  width: 0.4em;
  box-sizing: content-box;
  height: 0.4em;
  border: 0.1em solid red;
  position: relative;
  border-radius: 0.35em;
}
#magnifying-glass:before {
  content: "";
  display: inline-block;
  position: absolute;
  right: -0.25em;
  bottom: -0.1em;
  border-width: 0;
  background: red;
  width: 0.35em;
  height: 0.08em;
  transform: rotate(45deg);
}

38.Facebook图标

1555920585-4803-lfd04facxu
#facebook-icon {
  background: red;
  text-indent: -999em;
  width: 100px;
  height: 110px;
  box-sizing: content-box;
  border-radius: 5px;
  position: relative;
  overflow: hidden;
  border: 15px solid red;
  border-bottom: 0;
}
#facebook-icon:before {
  content: "/20";
  position: absolute;
  background: red;
  width: 40px;
  height: 90px;
  bottom: -30px;
  right: -37px;
  border: 20px solid #eee;
  border-radius: 25px;
  box-sizing: content-box;
}
#facebook-icon:after {
  content: "/20";
  position: absolute;
  width: 55px;
  top: 50px;
  height: 20px;
  background: #eee;
  right: 5px;
  box-sizing: content-box;
}

39.月亮

1555920585-5902-54oftem3df
#moon {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  box-shadow: 15px 15px 0 0 red;
}

40.旗

1555920585-6712-ek6zr17xvt
#flag {
  width: 110px;
  height: 56px;
  box-sizing: content-box;
  padding-top: 15px;
  position: relative;
  background: red;
  color: white;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-align: center;
  text-transform: uppercase;
}
#flag:after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 0;
  border-bottom: 13px solid #eee;
  border-left: 55px solid transparent;
  border-right: 55px solid transparent;
}

41.圆锥

1555920585-9424-v16dp8ajj6
 #cone {
  width: 0;
  height: 0;
  border-left: 70px solid transparent;
  border-right: 70px solid transparent;
  border-top: 100px solid red;
  border-radius: 50%;
}

42.十字架

1555920585-9326-87bq1dfxge
#cross {
  background: red;
  height: 100px;
  position: relative;
  width: 20px;
}
#cross:after {
  background: red;
  content: "";
  height: 20px;
  left: -40px;
  position: absolute;
  top: 40px;
  width: 100px;
}

43.根基

1555920590-1712-yw2u85cogf
 #base {
  background: red;
  display: inline-block;
  height: 55px;
  margin-left: 20px;
  margin-top: 55px;
  position: relative;
  width: 100px;
}
#base:before {
  border-bottom: 35px solid red;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  content: "";
  height: 0;
  left: 0;
  position: absolute;
  top: -35px;
  width: 0;
}

44.指示器

1555920590-7140-omz3qy9ep1
#pointer {
  width: 200px;
  height: 40px;
  position: relative;
  background: red;
}
#pointer:after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 0;
  border-left: 20px solid white;
  border-top: 20px solid transparent;
  border-bottom: 20px solid transparent;
}
#pointer:before {
  content: "";
  position: absolute;
  right: -20px;
  bottom: 0;
  width: 0;
  height: 0;
  border-left: 20px solid red;
  border-top: 20px solid transparent;
  border-bottom: 20px solid transparent;
}

45.锁

1555920590-1045-804p4klbbk
#lock {
  font-size: 8px;
  position: relative;
  width: 18em;
  height: 13em;
  border-radius: 2em;
  top: 10em;
  box-sizing: border-box;
  border: 3.5em solid red;
  border-right-width: 7.5em;
  border-left-width: 7.5em;
  margin: 0 0 6rem 0;
}
#lock:before {
  content: "";
  box-sizing: border-box;
  position: absolute;
  border: 2.5em solid red;
  width: 14em;
  height: 12em;
  left: 50%;
  margin-left: -7em;
  top: -12em;
  border-top-left-radius: 7em;
  border-top-right-radius: 7em;
}
#lock:after {
  content: "";
  box-sizing: border-box;
  position: absolute;
  border: 1em solid red;
  width: 5em;
  height: 8em;
  border-radius: 2.5em;
  left: 50%;
  top: -1em;
  margin-left: -2.5em;
}

 

ContOS使用vsftpd服务器的问题

一直都不适用vsftp,但是最近因为公司需要一个官网,所以才启动起来,安装vsftp很简单,可以搜索本站的资源“vsftpd”进行查阅,这个帖子只要是记录使用过程中的问题。

以前服务器的ContOS是6.5版本的,现在的版本是7.5,问题就随之而来了,以前出现过一次无法上传文件的问题,该问题是防火墙,帖子:“http://www.lanxinbase.com/?p=607”。

问题1:500 OOPS: vsftpd: refusing to run with writable root inside chroot ()。

解答:这个问题是因为你在vsftpd目录下的chroot_list文件中加入了FTP的用户名,只要把它删除就可以了;也可以把写入的权限去掉:chmod a-w /www。或者你可以在vsftpd的配置文件中增加下列两项中的一项:allow_writeable_chroot=YES

造成这个原因是因为,如:我们新建了一个www的用户,目录指向/www,并给/www赋予了写入的权限,所有就出现了500的错误。而chroot_list文件列表是制定需要锁定用户在它当前根目录的一个权限文件。简单点,如果你给了写入的权限,而又限制用户只能在它当前的根目录下,这样子会造成冲突,比如我上传一个文件夹。

*注:以前也遇到过这个问题是selinux的问题,所以要排除一下。

问题2:修改vsftp用户目录的问题。

解答:修改用户信息,使用usermod命令,其参数:

[root@iZ2zed1931stl3pem7ew6vZ vsftpd]# usermod –help
Usage: usermod [options] LOGIN

Options:
-c, –comment COMMENT new value of the GECOS field
-d, –home HOME_DIR new home directory for the user account
-e, –expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE
-f, –inactive INACTIVE set password inactive after expiration
to INACTIVE
-g, –gid GROUP force use GROUP as new primary group
-G, –groups GROUPS new list of supplementary GROUPS
-a, –append append the user to the supplemental GROUPS
mentioned by the -G option without removing
him/her from other groups
-h, –help display this help message and exit
-l, –login NEW_LOGIN new value of the login name
-L, –lock lock the user account
-m, –move-home move contents of the home directory to the
new location (use only with -d)
-o, –non-unique allow using duplicate (non-unique) UID
-p, –password PASSWORD use encrypted password for the new password
-R, –root CHROOT_DIR directory to chroot into
-s, –shell SHELL new login shell for the user account
-u, –uid UID new UID for the user account
-U, –unlock unlock the user account
-Z, –selinux-user SEUSER new SELinux user mapping for the user account

我就不翻译出来了,具体的自己拷贝到翻译软件里看一下就清楚了,但是这里主要介绍一下参数:-d、-u。

  • -d:new home directory for the user account(用户账号的新目录)
  • -u:new UID for the user account(用户的UID,应该就是唯一标识)

-d参数后面跟的目录很好解决,但是如果是-u的UID,你不知道是多少,那么可以使用命令: cat /etc/passwd |grep www

[root@iZ2zed1931stl3pem7ew6vZ vsftpd]# cat /etc/passwd |grep www
www:x:1000:1000::/www:/sbin/nologin

其中第一个1000就是UID,那么修改目录的命令,就应该如下:

usermod -m -d /www/home -u 1000 www;

usermod -d /www/home -m -u 1000 www;

*注:有些系统可能不需要-m的参数。

问题3:修改vsftp用户登陆密码。

解答:这个应该不是问题,就是:passwd www。

问题4:访问vsftp服务器出现200、227错误。

 

解答:ftp服务器有两种工作模式,port和pasv(主动和被动),这两种模式都是客户端先向服务器端发出请求,服务器建立链接,以服务器为对象,当传输数据时,如果是服务器从20端口向客户端空闲端口发送请求建立链接,就是port(主动),反之,如果是客户端向服务器空闲端口请求建立链接,就是pasv(被动)。

打开IE浏览器:选择设置—-internet—–高级—-使用被动FTP(为防火墙和DSL调制解调器兼容性)”前面的勾去掉。

001

 

问题5:450:读取目录列表失败。

解答:这个挺困扰的,我找了很久才发现,只需要在vsftp的配置文件vsftpd.conf加入pasv_enable=NO就可以了,接着重启一下服务器,引起整个原因是pasv的问题。

问题6:中文乱码的问题。

解答:中文乱码的问题其实我没有遇到过,网上的解决方案是改i18n,不过我们服务器的名称一般都是英文的,所以就不需要搭理它了。

问题7:530 Login incorrect.

解答:请检查一下密码是否输入错误。

问题8:550 外网无法登录。

解答:这个可能是没有开放tcp 20的端口,请检查一下防火墙规则配置文件。

问题9:其他问题。

这次出现过一次很奇葩的问题,但其实是FTP客户端的问题,我在登陆www账号的时候,FTP客户端居然把服务器“/”目录当成了用户的主目录,0.0吓死我了,搞了我一下午都没有找出问题来,后来第二天再登陆进去,发现正常了,根目录是/www,这就奇怪了,后来我再次改一下配置文件,然后换了不同的FTP客户端登陆,确定这个是客户端的问题。

所以遇到问题不要怕麻烦,一个个去排查就可以了。

 

 

 

12526272829115
 
Copyright © 2008-2021 lanxinbase.com Rights Reserved. | 粤ICP备14086738号-3 |