文章目录

  • 资源文件的命名
  • 资源文件基名的指定
    • struts.xml 文件指定资源文件的基名
    • struts.properties 文件指定资源文件的基名
    • 通过标签 i18n 指定资源文件的基名
  • 资源文件的位置
    • 包级资源文件
    • 类级资源文件
    • 全局级资源文件
    • 默认资源文件
  • 资源文件的加载顺序
    • Action 中加载资源文件
    • 在 JSP 中访问资源文件
  • 怎么获取资源文件中指定key的值
    • s:text
    • s:submit
    • s:textfield
  • s:password
  • s:radio
  • 在自定义的 Action 中获取资源文件中指定 key 的值
    • ActionSupport
  • 资源文件中消息值中的占位符
  • 消息值中使用表达式
  • 设置和获取默认的语言环境
  • 拦截器 i18n
  • 案例演示
    • 案例一
    • 案例二
  • 参考文章

资源文件的国际化 internationalization,这个单词是以 i 开头 n 结尾,中间共 18 个字母,所以缩写为 i18n,国际化的核心:页面显示的文字语言是可配置的。

Struts2 国际化是建立在 Java 国际化的基础上的,一样是通过提供不同语言环境的消息资源(资源属性文件),然后通过ResourceBundle 加载指定 Locale 对应的资源文件,再取得该资源文件中指定 key 对应的消息(值),其整个过程与 JAVA 程序的国家化完全相同,只是 Struts2 框架对 JAVA 程序国际化进行了进一步封装,从而简化了应用程序的国际化。

资源文件的命名

资源文件必须是 properties 文件,命名规则为:基名 _语言代号_地区代号(即国家代号).properties

资源文件基名的指定

struts.xml 文件指定资源文件的基名

基名是需要指明出来的,例如,资源文件名称为 globalMessages_en_US.properties,那么基名 globalMessages 可以在配置文件 struts.xml 中指明出来,如下所示:

<struts><!-- 设置常量 struts.custom.i18n.resources 的值,其实就是指明资源文件的基名 --><constant name="struts.custom.i18n.resources" value="globalMessages"/>
</struts>

上述方式指定的是全局性的资源文件。

struts.properties 文件指定资源文件的基名

struts.custom.i18n.resources=baseName
struts.i18n.encoding=GBK

上述方式指定的是全局性的资源文件。

通过标签 i18n 指定资源文件的基名

如果不在配置文件 struts.xml 中指明,也可以通过 i18n 标签来指明,如下所示:

<s:i18n name="globalMessages">
<s:text name="firstname"/>
</s:i18n>

标签 i18n 的属性 name 就是用来指明资源文件的基名。标签体中的标签 text 的属性 name 指定 key 的名称。

指明了基名之后呢,<s:text name="firstname"/> 这个标签的底层代码,会调用 Action 的某个方法,这个方法会根据当前系统的语言环境去读取名称以 globalMessages 开头的资源文件,获取 key 为 firstname 的值,如果获取不到,则会到配置文件 struts.xml 或者 struts.properties 所指定的资源文件中获取 key 为 firstname 的值,如果还是找不到则会直接输出属性 name 的值到页面中(即直接输出 key 的名称)。

资源文件的位置

如果项目非常大,所有资源文件放入同一个目录下是不好的。资源文件需要分层和分类。

Maven 项目中,资源文件只能放在目录 resources 下。其实除了包级别资源文件和类级别资源文件的位置有强制要求外,全局级别的资源文件可以存放在目录 classes 中的任意位置上。只是在 struts.xml 需要指定资源文件的具体路径罢了。

如下图展示在 Maven 项目中将资源文件存放在 LoginAction 所在包目录下:

在 struts.xml 要指明资源文件的具体路径:

如下图展示了 eclipse 中如何存放资源文件:

上图所示的包级资源文件 package_zh_CN.properties 能被 com.tarena.com.outman.day05 下所有 Action 使用;包级资源文件 package_zh_CN.properties 能被 com.tarena.com.outman 下所有 Action 使用;类级资源文件 OneAction_zh_CN.properties 只能被 com.tarena.com.outman.day05 下的 OneAction 访问。

包级资源文件

存放在某个包下面的资源文件。命名规则:package_language_country.properties,其中 package 就是固定的基名。

表示某资源文件是被一个包中所有 Action 所使用的。
包级资源文件是其所在包及子包中的所有 Action 共享的资源文件。

Maven 项目中, 必须将资源文件存放在目录 resources 下面,如果要创建包级资源文件,那么要先在目录 resources 下面创建对应的包目录,然后在该包目录下创建资源文件,在构建项目时会将资源文件复制到 classes 目录中相对应的包目录下。


struts.xml 文件中不需要指定资源文件的基名。如下图所示指定包级资源文件的基名也可以,是因为查找包级资源文件时根本就不会去解析常量 struts.custom.i18n.resources 的值。这个常量是用来指定全局级别的资源文件的基名的。

类级资源文件

以某个类名命名的资源文件。命名规则:ActionName_language_country.properties,其中 ActionName 是 Action 类的类名,也就是以 Action 类的类名作为资源文件的基名。

表示某资源文件只能被指定类使用。
类级资源文件是指定类专享的资源文件。

下图展示 Maven 项目如何存放类级资源文件:

类级别的资源文件,不需要在 struts.xml 中指定资源文件的基名。

全局级资源文件

全局级资源文件直接存放在目录 resources 下即可。

全局级的资源文件,必须通过文件 struts.xml 或者 struts.properties 指定资源文件的基名,否则找不到资源文件:

默认资源文件

当在中文操作系统下,如果 myres_zh_CN.properties、myres.properties 两个文件都存在,则优先会使用 myres_zh_CN.properties,当myres_zh_CN.properties 不存在时候,会使用默认的 myres.properties。没有提供语言和地区的资源文件则会去读取系统默认的资源文件。

资源文件都必须是 ISO-8859-1 编码,因此,对于所有非西方语系的处理,都必须先转换为 Java Unicode Escape 格式。转换方法是通过 JDK 自带的工具 native2ascii。

资源文件的加载顺序

Action 中加载资源文件

假设我们在 ChildAction 中调用了 getText("title"),Struts 2.0 将会按下面的顺序来加载资源文件:

(1)优先加载系统中 ChildAction 类文件所在目录下的,且 baseName 为 ChildAction 的系列资源文件。

(2)如果在(1)中找不到指定 key 对应的消息值,且 ChildAction 有父类 ParentAction,则加载 ParentAction 类文件所在目录下的,且 baseName 为 ParentAction 的系列资源文件。

(3)如果在(2)中找不到指定 key 对应的消息值,且 ChildAction 有实现接口 IChildAction,则加载 IChildAction 类文件所在目录下的,且 baseName 为 IChildAction 的系列资源文件。

(4)如果在(3)中找不到指定 key 对应的消息值,且 ChildAction 有实现接口 ModelDriven(即使用模型驱动模式),则对于 getModel()方法返回的 model 对象,重新执行第(1)步操作。

(5)如果在(4)中找不到指定 key 对应的消息值,则加载 ChildAction 类文件所在目录下的,且 baseName 为 package 的系列资源文件。

(6)如果在(5)中找不到指定 key 对应的消息值,则沿着当前包上溯,直到最顶层包去查找 baseName 为 package 的系列资源文件。

(7)如果在(6)中找不到指定 key 对应的消息值,则查找以常量 struts.custom.i18n.resources 的值作为 baseName 的系列资源文件。

(8)如果经过上面的步骤一直找不到 key 对应的消息值,将直接将 key 的名称输出。

在 JSP 中访问资源文件

对于在 JSP 中访问国际化消息,则简单的多,可以分为两种形式:

1.使用 <s:i18n/> 标签作为父标签
(1)从 <s:i18n/> 标签指定的国际化资源文件中读取指定 key 对应的消息值。
(2)如果在(1)中找不到指定 key 对应的消息值,则查找以常量 struts.custom.i18n.resources 的值作为基名的系列资源文件。
(3)如果经过上面步骤还是找不到指定 key 对应的消息值,则直接将 key 的名称输出。

2.没使用 <s:i18n/> 标签作为父标签

直接查找以常量 struts.custom.i18n.resources 的值作为基名的系列资源文件,如果找不到指定 key 对应的值,则直接将 key 的名称输出。

怎么获取资源文件中指定key的值

s:text

这个标签的属性 name 是用来指定显示在页面上的文本。

<s:text name="firstname"/> 这个标签的底层代码,会调用 Action 的某个方法,这个方法会根据当前系统的语言环境去读取资源文件,然后查找名为 firstname 的 key,找到则将该 key 的值返回,找不到就直接输出属性 name 的值到页面中。

s:submit

<s:submit value="%{getText('login')}"/> 这个标签是通过EL 表达式去调用 Action 的方法 getText() 来获取名为 login 的 key 对应 的值。

getText() 这个方法来自于类 ActionSupport,这个方法的处理逻辑是这样的:

1.先获取 request 中的参数 request_locale,如果获取不到,则会到 session 对象中获取名为 WW_TRANS_I18N_LOCALE 的 key 对应的值,判断用户所使用的语言是哪种

2.根据获取到的语言和指明的资源文件基名到目录 classes 下面读取资源文件,获取并返回指定 key 的值,如果找不到则返回 null。

调用的是谁的 getText()?请求的是 LoginAction,转发到 login.jsp,那么这个 jsp 中获取资源文件中的值的有关标签调用的就是 LoginAction 的 getText()。

这个标签还可以通过属性 key 来指定资源文件中相对应的 key 的名称,从而获得相对应的国际化信息,如下所示:

<s:submit key="loginSubmit" />

s:textfield

这个是文本输入框,属性 name 是用来指定参数名称。属性 label 是用来指定显示在页面中的文本。

通过调用 Action 的方法 getText() 方法来获取资源文件中的值,如下所示:

<s:textfield name="firstname" label="%{getText('firstname')}"/>

属性 label 指定 EL 表达式,调用 Action 的方法 getText() 去国际化资源文件中获取名为 firstname 的 key 对应的值。

还可以通过属性 key 来指定资源文件中的 key,如下所示:

<s:textfield name="username" key="username"/>

s:password

这是密码文本输入框。

通过调用 Action 的方法 getText() 方法来获取资源文件中的值,如下所示:

<s:password name="password" label="%{getText('password')}"/>

通过属性 key 来指定资源文件中的 key,如下所示:

<s:password name="password" key="password"/>

s:radio

单选框

属性 name 指定参数名;属性 list 指定遍历的集合,集合中的元素有两个属性,左边属性指定元素 radio 的属性 value 的值,右边属性则指定元素 label 的文本内容。

通过 Action 的方法 getText 获取资源文件中指定 key 的值,如下所示:

<s:radio name="loginUser.sex" list="#{'1':getText('male'), '0':getText('female')}"/>

在自定义的 Action 中获取资源文件中指定 key 的值

示例代码1:

public String execute() {// 方法getText()继承自父类ActionSupport,用来读取资源文件中的数据,获取指定key所对应的值String str = getText("firstname");System.out.println(str);String[] names = {"liaowenxiong", "liudehua"};// title=欢迎您,{0}String title = getText("title", names);// 返回"欢迎您,liaowenxiong"System.out.println(title);return "success";}

示例代码2:

// 获取默认的语言环境
Locale aDefault = Locale.getDefault();
// 根据语言环境aDefault加载基名为globalMessages的资源文件
ResourceBundle rb = ResourceBundle.getBundle("globalMessages", aDefault);
// title1=欢迎您,{0}
String title = MessageFormat.format(rb.getString("title1"), "liaowenxiong");
System.out.println(title);

ActionSupport

自定义的 Action 必须继承自 ActionSupport。ActionSupport 类中已经封装了对资源文件的访问。

ActionSupport 中主要的方法:
getText(),这个方法中有去获取 ActionContext 对象中的key 为 com.opensymphony.xwork2.ActionContext.locale 的值。
getLocale(),这个方法就是去获取 ActionContext 对象中的key 为 com.opensymphony.xwork2.ActionContext.locale 的值。

扩展:struts.xml 中,标签 <action/> 如果没有指定属性 class 的值,那么调用的就是 ActionSupport 类。

资源文件中消息值中的占位符

title=欢迎您,{0}

如上所示,{0} 就是占位符。

Struts2 中提供了如下两种方式来填充消息字符串中的占位符:

1.JSP 页面,在 <s:text./> 标签中使用多个 <s:param/> 标签来填充消息中的占位符。

2.Action 中,在调用 getText 方法时使用 getText(String aTextName,List args) 或 getText(String key, String[] args) 方法来填充占位符。

String[] names = {"liaowenxiong", "liudehua"};
// title=欢迎您,{0}
String title = getText("title", names);// 返回"欢迎您,liaowenxiong"

消息值中使用表达式

Struts2 还提供了对占位符的一种替代方式,这种方式允许在国际化消息资源文件中使用表达式,对于这种方式,则可避免在使用国际化消息时还需要为占位符传入参数值。

如下在消息值中使用表达式:

succTip=${username}, 欢迎, 您已经登录!

在上面的消息值中,通过使用 EL 表达式,可以从 ValueStack 中取出属性 username 的值,自动填充到消息值中。

设置和获取默认的语言环境

ActionContext context = ActionContext.getContext();
// 获取应用默认的语言环境
Locale locale = context.getLocale();
// 获得应用默认的语言环境
locale = Locale.getDefault();
locale = new Locale("zh", "CN");
// 设置应用默认的语言环境
context.setLocale(locale);

拦截器 i18n

这个拦截器注册在默认的拦截器栈中。

i18n 拦截器在调用 Action 方法前,会到 request 中获取参数 request_locale 的值,这个值就是语言环境,如果获取到这个值会将其封装成 Locale 对象,并将这个对象与用户 Session 中的名为 WW_TRANS_I18N_LOCALE 的 key 进行映射;并且还会将这个对象与 ActionContex 对象中的名为 com.opensymphony.xwork2.ActionContext.locale 的 key 进行映射。

案例演示

案例一

实现 Maven Java Web 项目国际化的步骤:
1.写属性文件(也叫资源文件)
写两个属性文件,一个是中文版本的,一个是英文版本的,名称分别为:globalMessages_en_US.properties 和 globalMessages_zh_CN.properties,把资源文件存放在 resources 目录下。

globalMessages_en_US.properties 内容如下:

firstname=firstname
lastname=lastname
age=age
#title=Welcome,{0}
title=Welcome to xxx
username=username
password=password
login=login
select=Please select your language
chinese=Chinese
english=English

globalMessages_zh_CN.properties 的内容如下:

firstname=姓
lastname=名字
age=年龄
#title=欢迎您,{0}
title=欢迎来到xxx
username=用户名
password=密码
login=登录
select=请选择语言
chinese=中文
english=英文

2.自定义 Action

示例代码:

public class LoginAction extends ActionSupport {public String execute() {return "success";}
}

自定义的 Action 必须继承自 ActionSupport,因为需要调用 ActionSupport 中的方法 getText()。

3.配置 struts.xml

示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd">
<struts><!-- 是否启用开发模式 --><constant name="struts.devMode" value="true"/><!-- 指明资源文件的前缀,也就是资源文件的基名 --><constant name="struts.custom.i18n.resources" value="globalMessages"/><!-- 配置字符编码 --><constant name="struts.i18n.encoding" value="UTF-8"/><package name="struts2-tag" extends="struts-default" namespace=""><!-- http://localhost:8080/si/login1.action --><action name="login1" class="priv.lwx.struts2.i18n.web.LoginAction"><result name="success">/login1.jsp</result></action></package>
</struts>

4.写 jsp 文件

示例代码:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head><title></title>
</head>
<body>
<%-- 通过调用Action的getText方法,获取资源文件中名为 firstname 的key 所对应的值 --%>
<h1><s:text name="firstname"/>
</h1><s:form action="login" method="post"><%--EL表达式的底层是去调用Action的方法getText(),这个方法会根据当前系统的语言环境去读取对应的资源文件,例如,当前系统是中文环境,就会去读取文件globalMessages_zh_CN.properties,获取文件中指定key的值。--%><s:textfield name="firstname" label="%{getText('firstname')}"/><s:textfield name="lastname" label="%{getText('lastname')}"/><s:textfield name="age" label="%{getText('age')}"/><s:submit/>
</s:form>
</body>
</html>

5.测试
测试的时候可以先设置浏览器的语言,再访问这个地址:http://localhost:8080/si/login1.action

chrome 设置语言:

IE 浏览器:
打开IE -> 打开internet选项 -> 点击语言 -> 点击添加,可以看到如下“添加语言”对话框:

案例二

开发一个选择语言环境的页面,这个页面可以嵌入任何Web应用的首页中,这样就可以让用户自行选择语言环境了。

select-language.jsp:

<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="/struts-tags" prefix="s" %>
<html>
<%--我们就可以在JSP页面中通过<s:include .../>标签来包含该页面,包含该页面后,就可以让用户选择语言了。--%>
<head><title>Title</title><script>function langSelecter_onChanged() {// alert("hello");document.getElementById("langForm").submit();}</script>
</head>
<body>
<%--获取Session中的key为“WW_TRANS_I18N_LOCALE”的值,再将这个值存储到ValueStack的context中,将对应的key命名为SESSION_LOCALE--%>
<s:set var="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>
<%--创建Locales的实例,这个对象会存储在ValueStack的context中--%>
<s:bean var="locales" name="priv.lwx.struts2.i18n.bean.Locales"><%--SESSION_LOCALE == null ? locale : SESSION_LOCALE这个三目表达式的含义:判断SESSION_LOCALE的值是否为NULL,若为空则返回locale(从ValueStack的root区获取,root的栈顶存放的是ActionSupport对象,该对象有名为locale的属性,类型是Locale);若不为空则返回SESSION_LOCALE的值--%><%--为什么ValueStack中的root区可以获取到属性locale的值,因为Action对象就是在root区的栈顶,Action对象有属性locale,那么为什么Action有这个属性?从ActionSupport继承下来的。所以转发到此JSP的Action必须继承自ActionSupport--%><s:param name="current" value="#SESSION_LOCALE == NULL ? locale : #SESSION_LOCALE"/><%--Locales实例化后,会调用getCurrent方法,并将属性value的值作为参数传入方法中--%>
</s:bean>
<%--让用户选择语言的表单--%>
<form id="langForm" action="<s:url/>" style="background-color: #bbbbbb;padding-top: 4px;padding-bottom: 4px"><s:text name="selectTips"/><%--使用s:select标签遍历Locales对象的属性locales的值,这个值是一个Map对象,里面存储着应用所支持的语言信息--%><s:select id="langSelecter" label="language" name="request_locale" list="#locales.locales"listKey="value" listValue="key" value="#SESSION_LOCALE == NULL ? locale : #SESSION_LOCALE"onchange="langSelecter_onChanged();" theme="simple"/><%--用户发送请求,携带参数request_locale,那么系统会将该参数的值存储在Session的属性WW_TRANS_I18N_LOCALE中,该属性值直接决定Struts2系统的语言环境。--%>
</form>
<s:debug/>
</body>
</html>

bean 类 Locales 的代码:

package priv.lwx.struts2.i18n.bean;import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;/*** 这个类的作用就是用来获取当前应用所支持的全部语言** @author liaowenxiong* @date 2022/5/26 09:53*/public class Locales {// 因为本示例也需要实现国际化,所以也需要获取到用户的语言环境private Locale current;// Locales实例化的时候会自动调用该方法,将获取到的Locale对象存储到Locales实例的成员变量current中public void setCurrent(Locale cur) {System.out.println("方法setCurrent被调用了...");System.out.println("cur:" + cur);this.current = cur;}/*** 获取当前应用所支持的全部语言,以Map对象返回** @param* @return Map<Locale>* @throws* @author liaowenxiong* @date 2022/5/26 11:49*/public Map<String, Locale> getLocales() {System.out.println("方法getLocales被调用了...");// 构造一个Map对象,将当前应用所支持的语言存储在该对象中Map<String, Locale> locales = new Hashtable<String, Locale>();System.out.println("current:" + current);// current是用户的语言环境,globalMessages是资源属性文件的基名。下面这行代码会根据current所表示的// 语言环境及所指定的基名去读取对应的资源文件,将资源文件中的数据全部载入到ResourceBundle对象中。其实// 这个ResourceBundle对象类似Properties对象,它们都是Map对象ResourceBundle bundle = ResourceBundle.getBundle("globalMessages", current);// 添加当前应用所支持的语言,key是系统支持语言的显示名字,value是系统支持语言的Locale实例// getString方法就是从读取的资源文件中获取指定key对应的值locales.put(bundle.getString("usen"), Locale.US);locales.put(bundle.getString("zhcn"), Locale.CHINA);// 在JSP中会遍历这个Map对象,将里面的数据以下拉列表的形式显示出来return locales;}
}

创建属性文件 globalMessages_en_US.properties:

selectTips=Please select your language
usen=American English
zhcn=Simplified Chinese

创建属性文件 globalMessages_zh_CN.properties:

selectTips=请选择语言
usen=美式英语
zhcn=简体中文

参考文章

1.https://www.likecs.com/show-203884910.html
2.https://www.cnblogs.com/likailan/p/3307409.html

Struts2的资源文件和国际化(i18n)相关推荐

  1. java国际化程序创建属性文件_Java国际化(i18n)ResourceBundle类

    ResourceBundle类用于存储区域设置敏感的文本和对象. 通常使用属性文件来存储特定于语言环境的文本,然后使用ResourceBundle对象来表示它们. 以下是在基于Java的应用程序中使用 ...

  2. Struts2的国际化(一)-国际化资源文件的配置及国际化信息的访问

    一.概述: 1)国际化是一种技术:在程序设计领域,把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化. 2)本地化是一个动作:与国际化对应的是本地化,指让一个具备国际 ...

  3. 国际化资源文件命名规范

    基本格式 基名_语言_地区.properties 常见的资源文件命名规范 i18n_en.properties:所有英文语言的资源 i18n_en_US.properties:美国地区,英文语言的资源 ...

  4. 在Struts 2.0中国际化(i18n)您的应用程序

    国际化是商业系统中不可或缺的一部分,所以无论您学习的是什么Web框架,它都是必须掌握的技能. 其实,Struts 1.x在此部分已经做得相当不错了.它极大地简化了我们程序员在做国际化时所需的工作,例如 ...

  5. Java 对国际化 (i18n) 的支持资源包的调用

    Java 国际化 i18n 国际化信息也成为本地化信息,一般需要2个条件才能确定一个特定的国际化信息,分别是:"语言类型" 和 "国家/地区信息",Java 为 ...

  6. springboot配置国际化资源文件 使用themself模板进行解析

    2019独角兽企业重金招聘Python工程师标准>>> @ConfigurationProperties(prefix = "spring.messages") ...

  7. Android语言国际化values资源文件命名规则

    今天,简单讲讲 android 里如何将语言国际化,和各个国家语言的value文件夹的命名规则. 昨天,需要将app的字符资源国际化,可是却不知道如何命名,在网上找了资料,终于解决了问题. Andro ...

  8. php 正则匹配静态资源,Struts2 配置静态资源文件不经过Strut处理(正则匹配)

    Struts2框架有两个核心配置文件:struts.xml和Struts2默认属性文件default.properties(在struts2-core-2.3.20.jar中) default.pro ...

  9. vc 国际化的资源文件处理

    MS Windows操作系统是一个世界上广泛使用的操作系统,对于不同语种的国家MS Windows有相应语种的版本.在不同语种的Windows平台上应该运行相应语种的应用程序.也就是说程序的用户界面( ...

最新文章

  1. c语言代码,输入两个数,输出第一个数到第二个数之间所有的数
  2. 爱奇艺蒙版AI:弹幕穿人过,爱豆心中坐
  3. 我不想just talk talk
  4. css类选择器或逻辑,深入理解CSS中选择器的逻辑处理
  5. Try Redis : Redis 入门教程
  6. linux手动生成dump文件权限不足_linux下生成dump文件方法及设置
  7. SiteServer 迁移至 Windows 2008 R2 问题汇总
  8. 关于Oracle安装完毕后,登录时遇到的错误的解决的方法
  9. ExtJs 4.1.1 文件结构解析
  10. lombok几个基本注解的使用@Data @AllArgsConstructor @NoArgsConstructor @Builder
  11. 拼多多332亿美金市值超网易,黄铮离目标又近了一步!
  12. pythonwin1064位_在Windows 10 64位中安装Matplotlib
  13. karto探秘之slam_karto
  14. 第三届蓝桥杯省赛---马虎的算式
  15. linux pe ef 详解,PE工具列表(看雪學院)
  16. MTC160-16-ASEMI可控硅模块MTC160-16
  17. Android Property
  18. python实现局域网内使用TCP服务器传输文件
  19. 电子取证volatility
  20. Win10下载nmap!!!!(超详细,学不会直接远程指导)

热门文章

  1. APICloud 的一些常用方法
  2. Latex图片横排和竖排,并在图片下方和左方添加子标题
  3. win7的php兼容win8,window_Win10已兼容绝大多数Win7/Win8.1软硬件,7月29日之后,微软就要逐步向W - phpStudy...
  4. 如何选定你的职业方向(深度长文)
  5. 纯CSS3实现超酷炫的萤火虫动画
  6. 利用:before和:after伪类制作类似微信对话框
  7. 雷石服务器个别点歌机没信号,雷石点歌机触屏没反应怎么回?
  8. java 类继承实例_java继承例子代码,java类的继承示例
  9. 红石电路吧计算机教程,《我的世界》老MC必学的四种红石电路 10分钟带你告别石器时代!...
  10. Word设置页码你真的会了吗?如何从第二页开始开始设置页码为第一页,收藏备用!