一、简单例子

说明:本例基于struts2 2.1.6。

1.引入jar包,struts2-core-2.1.6.jar、xwork-2.1.2.jar、ognl-2.6.11.jar、freemarker-2.3.13.jar、commons-logging-1.1.jar、commons-io-1.3.2.jar、commons-fileupload-1.2.1.jar。

2.在web.xml中添加:

<filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.在src下新建struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
 <package name="default" namespace="/" extends="struts-default">
        <action name="hello">
            <result>/hello.jsp</result>
        </action>
 </package>
</struts>

4.在地址栏中输入".../hello.action"就会进入hello.jsp页面。(".action"可省略)

二、进一步探索

1.新建com.hanjun.action.HelloAction类:

public class HelloAction {
 public String execute(){
  return "success";
 }
}

说明:可实现Action接口或继承已实现Action接口的类ActionSupport。

配置action时指定class属性:

<action name="hello" class="com.hanjun.action.HelloAction">
        <result name="success">/hello.jsp</result>
    </action>

说明:进入hello.jsp前会执行HelloAction的execute方法,根据execute方法的返回值,在该action的配置中打到name为对应值的result,进入指定页面。如果返回值为success,result的name可不配置。

2.action不指定class属性时,默认执行ActionSupport类。action不指定执行方法时,默认为execute方法。action的method属性可指定进入什么方法。

3.可以通过url来指定进入什么方法:hello!addUser.action、hello!deleteUser.action:

public class HelloAction {
 public String addUser(){
  return "addUser";
 }
 public String deleteUser(){
  return "deleteUser";
 }
}

<action name="hello" class="com.hanjun.action.HelloAction">
        <result name="addUser">/adduser_success.jsp</result>
        <result name="deleteUser">/deleteuser_success.jsp</result>
    </action>

4.通配符(精确配置优先于通配符配置):

<action name="Student*" class="com.hanjun.action.StudentAction" method="{1}">
            <result>/Student{1}_success.jsp</result>
        </action>
        <action name="*_*" class="com.hanjun.action.{1}Action" method="{2}">
            <result>/{1}_{2}_success.jsp</result>
        </action>

说明:Studentadd.action(符合Student*)进入add方法返回Studentadd_success.jsp页面;

Student_delete.action(符合*_*)进入delete方法,返回Student_delete.jsp页面;(*_*中的_不能用!)

5.多个struts配置文件:在struts.xml中:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
    <include file="login.xml" />
</struts>

login.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="login" extends="struts-default" namespace="/login">
        <action name="login*" class="com.hanjun.action.LoginAction{1}">
            <result>/user_login_success.jsp</result>
        </action>
    </package>
</struts>

6.如果action不存在则进入默认action(不会拦截web.xml中配置的首页或jsp页面):

<default-action-ref name="index"></default-action-ref>
     <action name="index">
      <result>/default.jsp</result>
     </action>

7.result的type属性:

dispatcher : forward到一个页面

redirect : sendRedirect到一个页面

chain : forward到另一个action(值为另一个aciton的name值)

redirectAction : sendRedirect到另一个actoion

说明:如果转到另一个包的action,则配置为:

<result type="redirectAction">
       <param name="actionName">r2</param>
       <param name="namespace">/包名</param>
      </result>

8.共用的result,配置在package内:

<global-results>
   <result name="mainpage">/main.jsp</result>
</global-results>

说明:如果另一个包也想用:则把另一个package的extends设为本包的name值。(包继承)

9.可以在result中使用${变量名}获取action中的值。

10.配置异常映射,当所请求的antion方法出现异常时进入指定页面:

<global-results>
   <result name="error">/error.jsp</result>
 </global-results>
 <global-exception-mappings>
   <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
 </global-exception-mappings>

也可以单独使用:

<action name="*_*" class="com.hanjun.action.{1}Action" method="{2}">
   <result>/{1}_{2}.jsp</result>
   <exception-mapping result="error" exception="java.sql.SQLException" />  
   <result name="error">/error.jsp</result>
 </action>

三、URL参数接收

1.在action中声明变量:

private String name;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

说明:可接收url参数name的值:如url?name=zhangsan

2.在action中声明实体类:

private User user;
 public User getUser() {
  return user;
 }
 public void setUser(User user) {
  this.user = user;
 }

说明:可接收url参数user.name、user.age ...的值(User类的属性也要有对应的get、set方法)。

3.action实现ModelDriven接口(不常用):

public class UserAction extends ActionSupport implements ModelDriven<User>{
 
 private User user = new User();
 
 public String add() {
  System.out.println("name=" + user.getName());
  System.out.println("age=" + user.getAge());
  return SUCCESS;
 }
 @Override
 public User getModel() {
  return user;
 }
}

说明:这样还可以直接接收name、age参数。注意:user属性必须手动初使化。

四、常用属性

struts2常量读取的先后顺序(后读取的覆盖先读取的):

struts-default.xml、struts-plugin.xml、struts.xml、struts.properties、web.xml

1.开发模式,设为true修改struts2配置后不用重启服务器:

<constant name="struts.devMode" value="true" />

2.设置接收参数时的编码:

<constant name="struts.i18n.encoding" value="GBK" />

说明:struts2.1.6在web.xml中配置的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 对此配置无效。配置为struts2.0的filter:org.apache.struts2.dispatcher.FilterDispatcher就可以。

3.设置后缀:

<constant name="struts.action.extension" value="action,," />

4.设置可以调用静态方法:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

五、数据效验

1.进入方法后手动效验:

public String add() {
  if(name == null || !name.equals("admin")) {
   this.addFieldError("name", "name is error");
   this.addFieldError("name", "name is too long");
   return ERROR;
  } 
  return SUCCESS;
 }

在错误页面引入struts2的标签:

<%@taglib uri="/struts-tags" prefix="s" %>

打印错误信息的两种方法:

<s:fielderror fieldName="name"/>  //以ul方法展示,两个错误信息各为一个li

<s:property value="fieldErrors.name[1]"/> //打印key为name的第一个错误信息"name is error"

六、获取JSP对象

1. 获取jsp对象有四种方法,第一种:

Map request = (Map)ActionContext.getContext().get("request");
  Map session = ActionContext.getContext().getSession();
  Map application = ActionContext.getContext().getApplication();

2.第二种是第一种的注入形式,实现RequestAware,SessionAware, ApplicationAwar接口:

private Map<String, Object> request;
 private Map<String, Object> session;
 private Map<String, Object> application;
 @Override
 public void setRequest(Map<String, Object> request) {
  this.request = request;
 }
 @Override
 public void setSession(Map<String, Object> session) {
  this.session = session;
 }
 @Override
 public void setApplication(Map<String, Object> application) {
  this.application = application;
 }

3.第三种:

HttpServletRequest request = ServletActionContext.getRequest();
  HttpSession session = request.getSession();
  ServletContext application = session.getServletContext();

4.第四种是第三种的注入形式,实现ServletRequestAware接口:

private HttpServletRequest request;
 private HttpSession session;
 private ServletContext application;
 @Override
 public void setServletRequest(HttpServletRequest request) {
  this.request = request;
  this.session = request.getSession();
  this.application = session.getServletContext();
 }

5.说明:

第1种和第2种获取的request不能获取从页面传过来的参数值。

七、OGNL

在jsp中引入<%@ taglib uri="/struts-tags" prefix="s" %>

1. 获取并打印username属性:

<s:property value="username"/>  //完整写法为:<s:property value="%{username}"/>

2.获取并打印user的age属性:

<s:property value="user.age"/>

3.获取并打印cat的friend的name属性:

<s:property value="cat.friend.name"/>

4.直接使用java的方法:

<s:property value="password.length()"/>

5.防问静态方法:

<s:property value="@com.hanjun.struts2.ognl.S@s()"/>

说明:需要在struts.xml中配置:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

6.防问静态变量:

<s:property value="@com.hanjun.struts2.ognl.S@STR"/>

7.访问Math类的静态方法:

<s:property value="@@max(2,3)" />

8.访问普通类的构造方法:

<s:property value="new com.hanjun.struts2.ognl.User(8)"/>

9.防问集合:

<li>访问List:<s:property value="users"/></li>
  <li>访问List中某个元素:<s:property value="users[1]"/></li>
  <li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
  <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
  <li>访问Set:<s:property value="dogs"/></li>
  <li>访问Map:<s:property value="dogMap"/></li>
  <li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
  <li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
  <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
  <li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>

10.投影:

<li>获取age=1的第一个user:<s:property value="users.{?#this.age==1}[0]"/></li>
  <li>获取age大于1的第一个user:<s:property value="users.{^#this.age>1}"/></li>
  <li>投影age大于1的最后一个user:<s:property value="users.{$#this.age>1}"/></li>

获取当前堆栈中的第一个元素:<s:property value="[0]"/>  //[0]也可以用top

11.lambda表达式:

#fact=:[#this<=1?1:#this*fact(#this-1)],#fact(30H) //声明一个使用递归来计算阶乘的函数然后调用它

八、常用标签

在jsp中引入<%@ taglib uri="/struts-tags" prefix="s" %>

1.property:

<s:property value="username"/>  //获取属性username的值

<s:property value="admin" default="管理员"/> //default设置默认值

<s:property value="'<hr/>'" escape="false"/> //解析并输出html元素。

<s:property value="#request.adminName" /> //从request中取值

<s:property value="#adminName" /> //从ActionContext中取值

<s:property value="#parameters.age[0]" /> //获取url参数的值

2.set:

<s:set var="adminPassword" value="password" scope="session"/>

说明:scope的值有:page、request、session、action、application

3.bean:

<s:bean name="com.hanjun.struts2.tags.Dog" var="myDog">
    <s:param name="name" value="'oudy'"></s:param>
   </s:bean>
   拿出值:
   <s:property value="#myDog.name"/>

4.if:

<s:if test="#age < 0">wrong age!</s:if>
  <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>
  <s:else>yeah!</s:else>

5.iterator:

<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
   <s:property value="#x.toUpperCase()"/> |
  </s:iterator>

<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
   <s:property/> | 
   遍历过的元素总数:<s:property value="#status.count"/> |
   遍历过的元素索引:<s:property value="#status.index"/> |
   当前是偶数(从1开始)?:<s:property value="#status.even"/> |
   当前是奇数(从1开始)?:<s:property value="#status.odd"/> |
   是第一个元素吗?:<s:property value="#status.first"/> |
   是最后一个元素吗?:<s:property value="#status.last"/>
   <br />
  </s:iterator>

6.date:

<s:date name="date" format="yyyy-MM-dd HH:mm:ss"/>  //name指定ognl

九、转换器

1.例如在MyAction中有Point point类,Point类有int x,int y属性。页面表单有一文本框 name="point",用户输入"3,4"。那么就需要写一个转换器将3和4分别装入point的x和y。

2.新建PointConverter类,继承org.apache.struts2.util.StrutsTypeConverter类:

public class MyPointConverter extends StrutsTypeConverter {
 public Object convertFromString(Map context, String[] values, Class toClass) {
  Point p = new Point();
  String[] strs = (String[]) values;
  String[] xy = strs[0].split(",");
  p.x = Integer.parseInt(xy[0]);
  p.y = Integer.parseInt(xy[1]);
  return p;
 }
 public String convertToString(Map context, Object o) {
  Point p =(Point) o;
  return p.getX()+","+p.getY();
 }
}

3.在MyAction同包下新建文件MyAction-conversion.properties:

point=com.hanjun.converter.MyPointConverter

十、拦截器

1.新建类实现com.opensymphony.xwork2.interceptor.Interceptor:

public class MyInterceptor implements Interceptor {
 public void destroy() {
  // TODO Auto-generated method stub
 }
 public void init() {
  // TODO Auto-generated method stub
 }
 public String intercept(ActionInvocation invocation) throws Exception {
  long start = System.currentTimeMillis(); //action方法执行前
  String result = invocation.invoke();
  long end = System.currentTimeMillis(); //action方法执行后
  System.out.println("action time = " + (end - start));
  return result;
 }
}

2.struts.xml中:

<interceptors>
   <interceptor name="myInterceptor" class="com.hanjun.interceptor.MyInterceptor"></interceptor>
  </interceptors>
  <action name="test" class="com.hanjun.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myInterceptor"></interceptor-ref>
   <interceptor-ref name="defaultStack"></interceptor-ref>
  </action>

或:

<interceptors>
   <interceptor name="myInterceptor" class="com.hanjun.interceptor.MyInterceptor"></interceptor>
   <interceptor-stack name="myStack">
    <interceptor-ref name="myInterceptor"></interceptor-ref>
    <interceptor-ref name="defaultStack"></interceptor-ref>
   </interceptor-stack>
  </interceptors>
  <action name="test" class="com.hanjun.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myStack"></interceptor-ref>
  </action>

注:当package的extends="struts-default"时,action默认的拦截器为defaultStack。但在action内指定自定义拦截器或拦截器堆栈后,需手动添加defaultStack。

3.指定拦截的方法:

MyInterceptor继承MethodFilterInterceptor类,此类有两个set属性:excludeMethods(要排除的方法名集合);includeMethods(要拦截的方法集合);

<interceptor name="myInterceptor" class="com.bjsxt.interceptor.MyInterceptor">
    <param name="includeMethods">doLogin,doRegister</param>
   </interceptor>

或在action设置拦截器时指定拦截方法:

<action name="test" class="com.bjsxt.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myStack">
    <param name="myInterceptor.includeMethods">doLogin,doRegister</param>
   </interceptor-ref>
  </action>

十一、禁止重复提交

1.在页面的form中添加:

<s:token></s:token>

注:每次生成一个不同的标识存入session,提交后会校验。

2.struts.xml:

<action name="user" class="com.hanjun.action.UserAction">
   <result>/addOK.jsp</result>
   <interceptor-ref name="defaultStack"></interceptor-ref>
   <interceptor-ref name="token"></interceptor-ref>
   <result name="invalid.token">/error.jsp</result>
  </action>

注:token为struts2定义好的拦截器,如果是重复提交则返回"invalid.token",所以定义一个result,重复提交时进入指定页面。

十二、国际化

1.在src下新建msg_en_US.properties和msg_zh_CN.properties。(msg自定义)

login.username=用户名://msg_en_US.properties中

login.username=username:  //msg_zh_CN.properties中

2.struts.xml中添加:

<constant name="struts.custom.i18n.resources" value="msg"></constant>

3.jsp页面(显示结果根据网页设置的语言而不同):

<s:text name="login.username"/> 或 <s:property value="getText('login.username')"/>

注:也可以使用url参数request_locale=en_US或request_locale=zh_CN手动指定,不过此url必须为struts的url。struts拦截到此参数后会存入session,session失效前不用重新设置。

4.使用占位符:

welcome.msg=欢迎你:{0}  //properties中

<s:text name="welcome.msg">
  <s:param value="username"></s:param>  //value指定ognl表达式
 </s:text>

十三、文件上传

1.页面:

<form action="uploadAction.action" method="post" enctype="multipart/form-data">
  <input type="file" name="file" value="请选择"><br/>
  <input type="submit" value="提交">
 </form>

2.UploadAction:

private File file;
 private String fileFileName;
 private String fileContentType;
 
 //上面三个属性get、set方法...
 public String execute() throws Exception {
  String path = ServletActionContext.getServletContext().getRealPath(
    "/upload");
  File dir = new File(path);
  if (!dir.exists()) {
   dir.mkdir();
  }
  FileInputStream fis = new FileInputStream(file);
  BufferedInputStream bis = new BufferedInputStream(fis);
  FileOutputStream fos = new FileOutputStream(new File(dir, fileFileName));
  BufferedOutputStream bos = new BufferedOutputStream(fos);
  byte[] buf = new byte[1024];
  for (int len = bis.read(buf); len != -1; len = bis.read(buf)) {
   bos.write(buf, 0, len);
  }
  bos.flush();
  bos.close();
  bis.close();
  return super.execute();
 }

3.struts2默认上传文件的最大限制为2M,可以修改全局的上传大小限制:

<constant name="struts.multipart.maxSize" value="999000000"></constant> //999M

注:当上传的文件超过限制大小时,后台报"the request was rejected because its size (文件大小) exceeds the configured maximum (2097152)"并返回input。

可以重写ActionSupport类的addActionError方法将错误信息存入ActionError:

public void addActionError(String anErrorMessage) {
  // 这里要先判断一下,是我们要替换的错误,才处理
  if (anErrorMessage.startsWith("the request was rejected because its size")) {
   Matcher m = Pattern.compile("\\d+").matcher(anErrorMessage);
   String s1 = "";
   if (m.find()){
    s1 = m.group();
   }
   String s2 = "";
   if (m.find()){
    s2 = m.group();
   }
   // 偷梁换柱,将信息替换掉
   super.addActionError("你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");
  } else {// 否则按原来的方法处理
   super.addActionError(anErrorMessage);
  }
 }

4.单独设置一个action的上传文件最大值:

<action name="uploadAction" class="com.hanjun.action.UploadAction">
   <result>/upload_success.jsp</result>
   <result name="input">/test.jsp</result>
   <interceptor-ref name="defaultStack"> 
    <param name="fileUpload.maximumSize">5000000</param> 
   </interceptor-ref> 
  </action>

注:这里设置的大小应小于全局大小。如果文件大于这里设置的大小而小于全局设置的大小,直接返回input,没有错误信息(我的试验结果)。

十四、文件下载

1.jsp:

<form action="download.action" method="post">
     <input name="filename" value="tisr.log">
     <input type="submit" value="下载">
    </form>

2.DownloadAction:

public class DownloadAction extends ActionSupport {
 private String filename;
 private String directory;
 public String execute() throws Exception {
  return SUCCESS;
 }
 public InputStream getInputStream() throws Exception {
  String dir = directory + filename;
  return new FileInputStream(dir); // 如果dir是绝对路径
  //如果dir是Resource下的相对路径
  //return ServletActionContext.getServletContext().getResourceAsStream(dir);
 }
 public String getFilename() {
  return filename;
 }
 public void setFilename(String filename) {
  this.filename = filename;
 }
 public void setDirectory(String directory) {
  this.directory = directory;
 }
}

3.struts.xml:

<action name="download" class="com.bjsxt.action.DownloadAction" >
     <param name="directory">D:/</param>
     <result name="success" type="stream">
         <!--- 指定下载文件的内容类型,text/plain是默认类型 application/octet-stream为无限制-->
         <param name="contentType">application/octet-stream</param>
         <!--- inputName默认值是inputStream,代表从getInputStream方法获取流 -->
         <param name="inputName">inputStream</param>
         <!---动态获取文件名,从Action中的取得filename-->
         <param name="contentDisposition">
             attachment;filename="${filename}"
         </param>
         <param name="bufferSize">2048</param>
     </result>
     <result name="input">/downloadError.jsp</result>
 </action>

struts2从入门到精通相关推荐

  1. java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!

    java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...

  2. java web从入门到精通视频_JavaWeb从入门到精通(视频实战版)

    JavaWeb从入门到精通(视频实战版) 作者:常倬林 出版日期:2010年12月 文件大小:28.02M 支持设备: ¥30.00仅供试读 适用客户端: 言商书局 iPad/iPhone客户端:下载 ...

  3. 视频教程-Word项目实战从入门到精通(兼容2007、2010、2013、2016)-Office/WPS

    Word项目实战从入门到精通(兼容2007.2010.2013.2016) 有十年的开发经验和十年的培训经验,熟悉以下技术: 开源技术:struts2.hibernate.mybatis.spring ...

  4. 视频教程-PowerPoint项目实战从入门到精通视频课程(兼容2007、2010、2013、2016版本)-Office/WPS

    PowerPoint项目实战从入门到精通视频课程(兼容2007.2010.2013.2016版本) 有十年的开发经验和十年的培训经验,熟悉以下技术: 开源技术:struts2.hibernate.my ...

  5. 【动力节点】springmvc框架入门教程-从入门到精通

    目录 一.Springmvc入门 1.Springmvc是什么 2.Springmvc处理流程 3.入门程序 二.springMVC架构 1.springMVC的架构图 2.架构流程 3.spring ...

  6. 《Java Web从入门到精通》PDF 百度网盘

    http://www.java1234.com/a/javabook/javaweb/2014/1219/3407.html <Java Web从入门到精通>PDF 下载 <Java ...

  7. javaweb 入门到精通ServletJSP;-王磊-专题视频课程

    javaweb 入门到精通Servlet&JSP;-7367人已学习 课程介绍         JSP语法,Tomcat服务器应用,状态管理,cookie.session,EL+JSTL,Se ...

  8. 虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通

    UE5 Niagara学习教程  课程获取:虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通-云桥网 你会学到什么 我将通过创建各种各样的实时效果来教你虚幻引擎中强大的粒子系统. 我们将从简单的基 ...

  9. Revit:从入门到精通学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确) |大小:8.07 GB |时长:12h 16m Re ...

  10. 《Java 开发从入门到精通》—— 2.2 编写第一段Java程序

    本节书摘来异步社区<Java 开发从入门到精通>一书中的第2章,第2.2节,作者: 扶松柏 , 陈小玉,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.2 编 ...

最新文章

  1. python读取文件模式_python如何读取文件的数据
  2. centos7 安装mysql5.6_centos7安装mysql5.6
  3. python网络爬虫_Python爬虫实战之网络小说
  4. windbg sx命令与简单应用
  5. 博世 40 亿欧元押注自动驾驶,Waymo 准备接招吧
  6. ias日志察看器(.net)
  7. netdev_priv
  8. FOR XML PATH 应用及其反向分解
  9. AutoCAD2004下载AutoCAD2004中文版安装教程
  10. Idea2021激活码
  11. 【190112】VC++ 电话簿通讯录程序源代码
  12. 电阻电容串联并联关系,一辈子受益
  13. JAVA_OPTS 参数介绍 使用记录
  14. 尚乘集团联手其蛛网生态圈成员及战略伙伴布局进驻元宇宙
  15. oracle 系统资源正忙,oracle提示资源正忙怎么解决?oracle资源正忙解决方法
  16. 在职场遇到一个总是说话带刺的同事怎么相处?
  17. Mac版excel如何快速进行数据拆分?
  18. 【程序人生】那些工作之外的技术挣钱方式
  19. Pyecharts 加载外部地图数据绘图
  20. HEC模型快速入门;RAS-HMS等;防洪评价;洪水建模等

热门文章

  1. Just Cause系列游戏品鉴
  2. 解决warnings potentially fixable with the `--fix`
  3. Netlogo入门(一)
  4. mysql不停机升级_线上不停机部署mysql主从
  5. 群晖NAS用户和用户组权限讲解
  6. Transform.rotation所见非所得
  7. JW Player 使用 RTMP 流
  8. 如何从CDN加载jQuery
  9. 2007年9-11月
  10. 在word中插入目录,不把目录的页数计算在内