Action 跟 Actionsupport 的区别

Action 跟 Actionsupport 的区别 当我们在写action的时候,可以实现Action接口,也可以继承Actionsupport这个类.到底这两个有什么区别呢?

Action接口有: public static final java.lang.String SUCCESS = "success"; public static final java.lang.String NONE = "none"; public static final java.lang.String ERROR = "error"; public static final java.lang.String INPUT = "input"; public static final java.lang.String LOGIN = "login";

public abstract java.lang.String execute() throws java.lang.Exception;

而Actionsupport这个工具类在实现了Action接口的基础上还定义了一个validate()方法,重写该方法,它会在execute()方法之前执行,如校验失败,会转入input处,必须在配置该Action时配置input属性。

另外,Actionsupport还提供了一个getText(String key)方法还实现国际化,该方法从资源文件上获取国际化信息.

这样在自定义标签时可以定义一个变量为new actionsupport对象实现国际化。

ActionSupport类的作用 struts2不要求我们自己设计的action类继承任何的struts基类或struts接口,但是我们为了方便实现我们自己的action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用借口,提供了很多默认方法,这些默认方法包括国际化信息的方法、默认的处理用户请求的方法等,这样可以大大的简化Acion的开发。 Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。

========================== 关于struts2标签取值的备忘录

取值要通过或在任意的标签内使用%{};

当Action的valueStack中有该属性的值时,只需直接使用该属性的名字即可;

当Action的valueStack中没有该属性的值时,比如在session,application范围中的属性值时,需要加#或者#attr.;

例子: 假设某Action中有person成员变量,在application中存在company属性 那么我们可以通过以下方法取值: //无法取到,因为company不在action的valueStack中

//错误,value会直接显示person.name字样

===================== 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext.getContext() ValueStack由OGNL框架实现 可以把它简单的看作一个集合

Stack Object:放入stack中的对象,一般是action Stack Context(map):stack上下文,它包含一些列对象,包括request/session/attr/application map等。

EL:存取对象的任意属性,调用对象的方法,遍历整个对象结…

=========== WebWork2.2笔记(二)ActionSupport及其他基础知识 绝大多数情况下,WebWork不是直接实现com.opensymphony.xwork.Action接口,而是扩展 com.opensymphony.xwork.ActionSupport类。ActionSupport实现了除Action以外的其他几个接口,主要的几个接口是: com.opensymphony.xwork.Validateable com.opensymphony.xwork.Validateaware com.opensymphony.xwork.TextProvider com.opensymphony.xwork.LocaleProvider 这些接口主要是提供给WebWork的拦截器使用的,接口配合拦截器可以实现AOP功能。比如Validateable接口和Validateaware 接口配合DefailtWorkflowInterceptor就可以实现对用户输入进行检验的功能,当用户调用Action时,首先执行 Validateable接口定义的validate()方法,如果在这个方法中用户使用接口Validateaware中的方法设置了错误信息,则 DefaultWorkflowInterceptor会自动终止Action的执行,并产生一个INPUT的result,只有没有任何错误信息才会执行Action的剩余部分。

前面我们定义的xwork.xml配置文件中包含了一句:,这个webwork-default.xml包含在webwork的jar包中。 webwork-default.xml预建了很多常用的result-type、interceptor和interceptor-stack。其中 interceptor和interceptor-stack用于定义webwork将要使用那些拦截器。interceptor定义一个拦截器,而 interceptor定义一组拦截器。如果一个Action使用一组拦截器,则这些拦截器将以其定义的顺序执行,可见,interceptor- stack中拦截器的顺序时很重要的。

在webwork-default.xml中有如下定义: ...... 而名为validationWorkflowStack和completeStack这两个预建的interceptor-stack则包含了workflow这个interceptor。

下面做一个检查用户输入的练习,如果用户没有输入内容,则让用户重新输入,并且提示错误信息。

web.xml 与上次的相同。

xwork.xml xml 代码

1. 2. "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

3. 4. 5.

6. 7. 8.

9. 10. 11. success.jspresult> 12. input.jspresult> 13. action> 14. 15. package> 16. xwork>

input.jsp xml 代码

1. 2. 3.

Input Somethingtitle>head> 4.

5. 6.

7. ww:textfield>

8. ww:submit> 9. ww:form> 10. 11. body> 12. html>

success.jsp xml 代码

1. 2. 3.

Success!title>head> 4. 5. 6. body> 7. html>

============================== Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问 ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。

Struts2中OGNL,valueStack,stackContext的学习 学习Struts2,一直不明白表单中的值是怎么传给Action的,上网查了些资料,基本了解了!下面基本是从几个人的BOLG转载过来,以后记不清了再来看~

[color=red]先看看我做的实验jsp页面 Java代码

结果图(是通过得到的) value stack:

[点击查看原始大小图片]

Stack context:

通过图中我们可以看到 valuestack中包括我传递的值(point,point2,point3,age,date) stack context中包括了 request application OgnlValueStack(root) session parameters 等属性

值栈(ValueStack)     Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。     我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用 “#”。     假设值栈中有两个对象:student和employee,两个对象都有name属性,student有学号属性number,而 employee有薪水属性salary。employee先入栈,student后入栈,位于栈顶,那么对于表达式name,访问的就是student 的name属性,因为student对象位于栈顶;表达式salary,访问的就是employee的salary属性。正如你所见,访问值栈中的对象属性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2在OGNL基础上做出的改进。

值栈中的Action实例   Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。

Struts2中的命名对象     Struts2还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型。

parameters     用于访问请求参数。如:#parameters['id']或#parameters.id,相当于调用了HttpServletRequest对象的getParameter()方法。     注意,parameters本质上是一个使用HttpServletRequest对象中的请求参数构造的Map对象,一量对象被创建(在调用Action实例之前就已经创建好了),它和HttpServletRequest对象就没有了任何关系。

request     用于访问请求属性。如:#request['user']或#request.user,相当于调用了HttpServletRequest对象的getAttribute()方法。

session     用于访问session属性。如:#session['user']或#session.user,相当于调用了HttpSession对象的getAttribute()方法。

application     用于访问application属性。如:#application['user']或#application.user,相当于调用了ServletContext的getAttribute()方法。

attr     如果PageContext可用,则访问PageContext,否则依次搜索request、session和application对象。

以下是转过来的:先分清楚下ActionContext 、ValueStack 、Stack Context三者

ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionContext.getContext()

ValueStack 由OGNL框架实现 可以把它简单的看作一个栈(List) 。

Stack Object:放入stack中的对象,一般是action。 Stack Context(map):stack上下文,它包含一系列对象,包括request/session/attr/application map等。 EL:存取对象的任意属性,调用对象的方法,遍历整个对象结…

ActionContext是Action上下文,可以得到request session application ValueStack是值栈 存放表单中的值 Stack Context 栈上下文 也是用来存值的

struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:

|--request

|

|--application

|

context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]

|

|--session

|

|--attr

|

|--parameters

在Struts2中,采用标准命名的上下文(Context)来处理OGNL表达式。处理OGNL的顶级对象是一个Map(也叫context map),而OGNL在这个context中就是一个顶级对象(root)。在用法上,顶级对象的属性访问,是不需要任何标记前缀的。而其它非顶级的对象访问,需要使用#标记。 Struts2框架把OGNL Context设置为我们的ActionContext。并且ValueStack作为OGNL的根对象。除value stack之外,Struts2框架还把代表application、session、request这些对象的Map对象也放到 ActionContext中去。(这也就是Struts2建议在Action类中不要直接访问Servlet API的原因,他可以通过ActionContext对象来部分代替这些(Servlet API)功能,以方便对Action类进行测试!) Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问 ActionContext中其它对象的属性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。 那么访问Action中的属性的代码就可以这样写

其它ActionContext中的非根对象属性的访问要像下面这样写: or or 对Collection的处理,内容就很简单。 这是处理List。这个代码在页面上建立一个下拉选项,内容是list中的内容,默认值是name2. 处理map

需要注意的是,判断一个值是否在collection中。我们要使用in或者not in来处理。 muhahaha boo 另外,可以使用通配符来选择collection对象的子集。 ?——所有匹配选择逻辑的元素 ^——只提取符合选择逻辑的第一个元素 $——只提取符合选择逻辑的最后一个元素 person.relatives.{? #this.gender == 'male'}

`````````````````````````````````````````````````````````````````````````````````

以下为补充摘录的一些问题:

提问:在Struts2中,如何使用自身的Tag读取Action中的变量?

Struts2自身的Tag会根据value中的OGNL表达式,在ValueStack中寻找相应的对象。因为action在 ValueStack的顶部,所以默认情况下,Struts2的Tag中的OGNL表达式将查找action中的变量。请注意,value中的内容直接是 OGNL表达式,无需任何el的标签包装。

例如:

提问:在Struts2中,如何使用自身的Tag读取HttpServletRequest,HttpSession中的变量?

在上面的知识中,我们知道,Struts2中OGNL的上下文环境中,包含request,session,application等 servlet对象的Map封装。既然这些对象都在OGNL的上下文中,那么根据OGNL的基本知识,我们可以通过在表达式前面加上#符号来对这些变量的值进行访问。

例如:

提问:在Struts2中,如何使用JSTL来读取Action中的变量?

这是一个历史悠久的问题。因为事实上,很多朋友(包括我在内)是不使用Struts2自身的标签库,而是使用JSTL的,可能因为JSTL标签库比较少,简单易用的原因吧。

我们知道,JSTL默认是从page,request,session,application这四个Scope逐次查找相应的EL表达式所对应的对象的值。那么如果要使用JSTL来读取Action中的变量,就需要把Action中的变量,放到request域中才行。所以,早在 Webwork2.1.X的年代,我们会编写一个拦截器来做这个事情的。大致的原理是:在Action执行完返回之前,依次读取Action中的所有的变量,并依次调用request.setAttribute()来进行设置。具体的整合方式,请参考以下这篇文档:http://wiki.opensymphony.com/display/WW /Using+WebWork+and+XWork+with+JSP+2.0+and+JSTL+1.1

不过随着时代的发展,上面的这种方式,已经不再被推荐使用了。(虽然如此,我们依然可以学习它的一个解决问题的思路)目前来说,自从 Webwork2.2以后,包括Struts2,都使用另外一种整合方式:对HttpServletRequest进行装饰。让我们来看一下源码: Java代码

public class StrutsRequestWrapper extends HttpServletRequestWrapper {

/** * The constructor * @param req The request */ public StrutsRequestWrapper(HttpServletRequest req) { super(req); }

/**

* Gets the object, looking in the value stack if not found * * @param s The attribute key */ public Object getAttribute(String s) {

if (s != null && s.startsWith("javax.servlet")) { // don't bother with the standard javax.servlet attributes, we can short-circuit this

// see WW-953 and the forums post linked in that issue for more info

return super.getAttribute(s); }

ActionContext ctx = ActionContext.getContext(); Object attribute = super.getAttribute(s);

boolean alreadyIn = false; Boolean b = (Boolean) ctx.get("__requestWrapper.getAttribute"); if (b != null) { alreadyIn = b.booleanValue(); }

// note: we don't let # come through or else a request for // #attr.foo or #request.foo could cause an endless loop if (!alreadyIn && attribute == null && s.indexOf("#") == -1) {

try { // If not found, then try the ValueStack

ctx.put("__requestWrapper.getAttribute", Boolean.TRUE); ValueStack stack = ctx.getValueStack(); if (stack != null) { attribute = stack.findValue(s); } } finally {

ctx.put("__requestWrapper.getAttribute", Boolean.FALSE); } }

return attribute; } }

看到了嘛?这个类会在Struts2初始化的时候,替换HttpServletRequest,运行于整个Struts2的运行过程中,当我们试图调用 request.getAttribute()的时候,就会执行上面的这个方法。(这是一个典型的装饰器模式)在执行上面的方法时,会首先调用 HttpServletRequest中原本的request.getAttribute(),如果没有找到,它会继续到ValueStack中去查找,而action在ValueStack中,所以action中的变量通过OGNL表达式,就能找到对应的值了。

在这里,在el表达式广泛使用的今天,JSTL1.1以后,也支持直接使用el表达式。注意与直接使用struts2的tag的区别,这里需要使用el的表示符号:${}

例如:${user.name},

提问:在Struts2中,如何使用Freemarker等模板来读取Action中的变量以及HttpServletRequest和HttpSession中的变量?

Freemarker等模板在Struts2中有对应的Result,而在这些Result中,Freemarker等模板会根据 ValueStack和ActionContext中的内容,构造这些模板可识别的Model,从而使得模板可以以他们各自的语法对ValueStack 和ActionContext中的内容进行读取。

有关Freemarker对于变量的读取,可以参考Struts2的官方文档,非常详细:http://struts.apache.org/2.0.14/docs/freemarker.html

设值计算

Struts2中使用OGNL进行设值计算,就是指View层传递数据到Control层,并且能够设置到相应的Java对象中。这个过程从逻辑上说需要分成两步来完成:

1. 对于每个请求,都建立一个与相应Action对应的ActionContext作为OGNL的上下文环境和ValueStack,并且把Action压入ValueStack

2. 在请求进入Action代码前,通过某种通用的机制,搜集页面上传递过来的参数,并调用OGNL相关的代码,对Action进行设值。 上面的第一个步骤,在处理URL请求时完成,而第二个步骤由struts2内置的拦截器完成。

================================ Struts2教程:使用validate方法验证数据 在Struts2中最简单的验证数据的方法是使用validate。我们从ActionSupport类的源代码中可以看到,ActionSupport类实现了一个Validateable接口。这个接口只有一个validate方法。如果Action类实现了这个接口,Struts2在调用execute方法之前首先会调用这个方法,我们可以在validate方法中验证,如果发生错误,可以根据错误的level选择字段级错误,还是动作级错误。并且可使用addFieldError或addActionError加入相应的错误信息,如果存在Action或 Field错误,Struts2会返回“input”(这个并不用开发人员写,由Struts2自动返回),如果返回了“input”,Struts2就不会再调用execute方法了。如果不存在错误信息,Struts2在最后会调用execute方法。

这两个add方法和ActionErrors类中的add方法类似,只是add方法的错误信息需要一个ActionMessage对象,比较麻烦。除了加入错误信息外,还可以使用addActionMessage方法加入成功提交后的信息。当提交成功后,可以显示这些信息。

以上三个add方法都在ValidationAware接口中定义,并且在ActionSupport类中有一个默认的实现。其实,在 ActionSupport类中的实现实际上是调用了ValidationAwareSupport中的相应的方法,也就是这三个add方法是在 ValidationAwareSupport类中实现的,代码如下:

1. private final ValidationAwareSupport validationAware = new ValidationAwareSupport(); 2. 3. public void addActionError(String anErrorMessage) 4. { validationAware.addActionError(anErrorMessage); 5. } 6. public void addActionMessage(String aMessage) 7. { 8. validationAware.addActionMessage(aMessage); 9. } 10. public void addFieldError(String fieldName, String errorMessage) 11. { 12. validationAware.addFieldError(fieldName, errorMessage); 13. }

下面我们来实现一个简单的验证程序,来体验一个validate方法的使用。

先来在Web根目录建立一个主页面(validate.jsp),代码如下:

1. < %@ page language="java" import="java.util.*" pageEncoding="GBK"%> 2. < %@ taglib prefix="s" uri="/struts-tags" %> 3. < html> 4. < head> 5. < title>验证数据< /title> 6. < /head>

7. 8. < body> 9. < s:actionerror/> 10. < s:actionmessage/> 11. < s:form action="validate.action" theme="simple"> 12. 输入内容:< s:textfield name="msg"/> 13. < s:fielderror key="msg.hello" /> 14. < br/> 15. < s:submit/> 16. < /s:form> 17. < /body> 18. < /html>

在上面的代码中,使用了Struts2的tag:< s:actionerror>、< s:fielderror>和< s:actionmessage>,分别用来显示动作错误信息,字段错误信息,和动作信息。如果信息为空,则不显示。

现在我们来实现一个动作类,代码如下:

1. package action; 2. 3. import javax.servlet.http.*; 4. 5. import com.opensymphony.xwork2.ActionSupport; 6. import org.apache.struts2.interceptor.*; 7. 8. public class ValidateAction extends ActionSupport 9. { 10. private String msg; 11. public String execute() 12. { 13. System.out.println(SUCCESS); 14. return SUCCESS;

15. } 16. public void validate() 17. { 18. if(!msg.equalsIgnoreCase("hello")) 19. { 20. System.out.println(INPUT);

21. this.addFieldError("msg.hello", "必须输入hello!"); 22. this.addActionError("处理动作失败!"); 23. } 24. else 25. { 26. this.addActionMessage("提交成功"); 27. } 28. } 29. public String getMsg() 30. { 31. return msg; 32. } 33. public void setMsg(String msg) 34. { 35. this.msg = msg; 36. } 37. }

大家从上面的代码可以看出,Field错误需要一个key(一般用来表示是哪一个属性出的错误),而Action错误和Action消息只要提供一个信息字符串就可以了。

最后来配置一下这个Action,代码如下:

1. < package name="demo" extends="struts-default"> 2. < action name="validate" class="action.ValidateAction"> 3. < result name="success">/error/validate.jsp< /result> 4. < result name="input">/error/validate.jsp< /result> 5. < /action>

6. < /package>

假设应用程序的上下文路径为demo,则可通过如下的URL来测试程序:

http://localhost:8080/demo/validate.jsp

我们还可以使用ValidationAware接口的其他方法(由ValidationAwareSupport类实现)获得或设置字段错误信息、动作错误信息以及动作消息。如hasActionErrors方法判断是否存在动作层的错误,getFieldErrors获得字段错误信息(一个Map 对象)。下面是ValidationAware接口提供的所有的方法:

1. package com.opensymphony.xwork2;

2. 3. import java.util.Collection; 4. import java.util.Map; 5.

6. public interface ValidationAware 7. { 8. void setActionErrors(Collection errorMessages); 9. Collection getActionErrors();

10. 11. void setActionMessages(Collection messages); 12. Collection getActionMessages(); 13. void setFieldErrors(Map errorMap); 14. Map getFieldErrors(); 15. void addActionError(String anErrorMessage); 16. void addActionMessage(String aMessage); 17. void addFieldError(String fieldName, String errorMessage); 18. boolean hasActionErrors(); 19. boolean hasActionMessages(); 20. boolean hasErrors(); 21. boolean hasFieldErrors(); 22. }

=========================== 实现com.opensymphony.xwork2.TextProvider接口 --需要导入xwork.jar 该接口主要提供读取消息资源文件,获取消息文本的功能。该接口的getText()用来获取消息文本的内容。

一般继承ActionSupport助手类,其实现了TextProvider接口并提供了默认实现 所以在,action/拦截器中(只要其继承了actionSupport)要获取资料文件(properties文件),可以直接放入以下代码:

import com.opensymphony.xwork2.LocaleProvider; import com.opensymphony.xwork2.TextProvider; import com.opensymphony.xwork2.TextProviderFactory;

public class Log拦截器 extends AbstractInterceptor implements LocaleProvider { //初始化拦截器时,获取资源文件 public void init() { protected TextProvider operateCodeProvider = new TextProviderFactory().createInstance( ResourceBundle.getBundle( "LogDefinitions资源文件名", getLocale()), this); }

/** * 获取语言 */ public Locale getLocale() { ActionContext ctx = ActionContext.getContext(); if (ctx != null) { return ctx.getLocale(); } else { sysLogger.debug("Action context not initialized"); return null; } }

调用方法: this.operateCodeProvider.getText("hwj") -->便可获取hwj的值. }

看看ActionSupport 是怎样实现TextProvider的: public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable { protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class); private final transient TextProvider textProvider = new TextProviderFactory().createInstance (getClass(), this); //返回国际化信息的方法 public String getText(String aTextName) { return textProvider.getText(aTextName); }

java actionsupport_Action 跟 Actionsupport 的区别相关推荐

  1. JAVA 中equals()与==的区别

    原文地址:http://www.chineselinuxuniversity.net/articles/29594.shtml 值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存 ...

  2. Java NIO与IO的区别和比较

    Java NIO与IO的区别和比较 导读 J2SE1.4以上版本中发布了全新的I/O类库.本文将通过一些实例来简单介绍NIO库提供的一些新特性:非阻塞I/O,字符转换,缓冲以及通道. 一. 介绍NIO ...

  3. java中Array和ArrayList区别 可以将 ArrayList想象成一种会自动扩增容量的Array

    java中Array和ArrayList区别 1)精辟阐述: 可以将 ArrayList想象成一种"会自动扩增容量的Array https://blog.csdn.net/ywjy10280 ...

  4. JAVA CLASSPATH 和PATH的区别 经典

    JAVA CLASSPATH 和PATH的区别 收藏 PATH: 用来指定 java 虚拟机(JVM) 所在在目录,也就是我们最常用的用来编译java源程序的javac.exe 和用来执行 *.cla ...

  5. java 接口与抽象类的区别

    1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法 ...

  6. 面试必问一:Java 中 == 和 equals 的区别你知道吗

    面试必问一:Java 中 == 和 equals 的区别你知道吗 前言 关于这个问题,一般初中级面试中都会遇到,还记得我当初实习找工作的时候也遇到了这个问题,现在都还记得自己是怎么回答的:== 是基本 ...

  7. POPTEST老李谈JVM、JRE、JDK、java ee sdk with jdk区别

    POPTEST老李谈JVM.JRE.JDK.java ee sdk with jdk区别 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作 ...

  8. 一文告诉你 Java RMI 和 RPC 的区别

    转载自  一文告诉你 Java RMI 和 RPC 的区别 RPC 远程过程调用 RPC(Remote Procedure Call Protocol)远程过程调用协议,通过网络从远程计算机上请求调用 ...

  9. Java之Socket与HTTP区别

    转自: Java之Socket与HTTP区别 - 曹刚 - 博客园我们都知道TCP/IP协议共分四层:①链路层,有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接 ...

最新文章

  1. 云栖社区 正文 永久免费SSL安全证书Letsencrypt安装使用方法
  2. 撕裂者cpu三代文件服务器,AMD三代线程撕裂者CPU开盖:钎焊散热、64核若隐若现...
  3. fusion 360安装程序的多个实例正在同时运行。_SpringMVC运行原理
  4. 农产品流通信息化及农超对接体系的现状
  5. opencv + python3 利用ros 的 cv_bridge 传送图像消息的一种替代方法
  6. JS获取当前/指定URL参数
  7. jsp stc_为什么说jsp的本质是servlet?
  8. 四十九、深入了解两个并发接口Callable和Runnable的区别
  9. IT知识架构和操作系统简介1
  10. 如何让VPC与VM共存?
  11. 存档:命令行程序的路径参数不能有空格
  12. 人机协同、数据驱动,云时代SOC的演进之路
  13. 《Android开发秘籍(第2版)》——第1.4节Android设备间的硬件差异
  14. C#把汉字转换成16进制(HEX)并向串口发送数据
  15. MLPlatform project的统一结构-----------Model层代码编写--------业务逻辑子层:编程思路...
  16. 测不准原理(还真有此事?)
  17. 网站备案 服务器变更,网站变更服务器备案
  18. DAMA数据管理知识体系指南pdf
  19. 程序员必备:Git入门,超详细
  20. gateway sentinel 熔断 不起作用_技术丨纯电动汽车高压熔断器计算及选型

热门文章

  1. 小结过去几个月+复盘遇到的一些问题
  2. 2023 Bty分销系统开源源码 v1.1
  3. 手机号码归属地查询JS跨域
  4. PIPI的逃跑路线Ⅳ
  5. PCB 文字喷印/LDI CAM软件
  6. MIUI和Android的关系,【最新系统】小米:MIUI和Android没有对应关系 - 爱应用
  7. 字节某正式员工吐槽:外包员工在外面倒卖字节粽子,没人管吗?网友:都是打工人,哪来的优越感?...
  8. 纯ALOHA和时隙ALOHA有什么区别?
  9. 金山开源安全卫士全套代码编译
  10. 全球最厉害的14位程序员是谁?我们来膜拜下这些大神都有哪些?