java框架之Struts2(1)-简介及入门
简介
Struts2 是一个基于 MVC 设计模式的 Web 应用框架,它本质上相当于一个 servlet,在 MVC 设计模式中,Struts2 作为控制器 (Controller) 来建立模型与视图的数据交互。
Struts2 是 Struts1 的下一代产品,是在 struts1和 WebWork 的技术基础上进行了合并的全新的 Struts2 框架。其全新的 Struts2 的体系结构与 Struts1 的体系结构差别巨大。
Struts2 以 WebWork 为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以 Struts2 可以理解为 WebWork 的更新产品。
虽然从 Struts1到 Struts2 有着太大的变化,但是相对于 WebWork,Struts2 的变化很小。
开发环境官网下载,下面示例使用版本为 struts-2.3.37,点击可直接下载 。
快速开始
导包
这里可以直接导入解压目录下 apps/struts2-blank.war 中所有 jar 。
Hello Struts2
代码
1、编写 Action 类:
package com.zze.action; public class HelloAction { public String execute() { System.out.println("hello Struts 2"); return "hello"; } }
com.zze.action.HelloAction
2、新建要跳转到的 jsp 页:
<%-- Created by zze. Date: 2019/1/22 Time: 10:48 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Hello</title> </head> <body> <h3>hello Struts2</h3> </body> </html>
WEB-INF/hello.jsp
3、在 src 下新建如下配置文件:
<?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> <!--配置 Strut 2 的包--> <package name="test1" extends="struts-default" namespace="/"> <!--配置 Action--> <action name="hello" class="com.zze.action.HelloAction"> <result name="hello">/WEB-INF/hello.jsp</result> </action> </package> </struts>
struts.xml
4、在 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>
web.xml
5、部署到 tomcat,运行:
执行流程
1、首先浏览器请求 localhost:8080/hello 。
2、在 web.xml 中配置的核心过滤器会拦截到请求。
3、拦截器会解析 url,在 struts.xml 中根据 package 标签上的 namespace 属性和 action 标签上的 name 找到对应请求路径的 action。
4、执行对应 action 标签对应 Action 类对象的 execute 方法。
5、execute 方法返回字符串,这个字符串与 action 标签下的 result 标签的 name 匹配。
6、返回匹配到的 result 标签中定义的路径对应的 jsp。
7、浏览器接收、渲染。
配置文件的加载顺序
已经知道 Struts2 的入口就是核心过滤器 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter ,在程序启动时会执行过滤器的 init 方法,及会执行核心过滤器的 init 方法:
public void init(FilterConfig filterConfig) throws ServletException { InitOperations init = new InitOperations(); Dispatcher dispatcher = null; try { FilterHostConfig config = new FilterHostConfig(filterConfig); init.initLogging(config); dispatcher = init.initDispatcher(config); init.initStaticContentLoader(config, dispatcher); prepare = new PrepareOperations(dispatcher); execute = new ExecuteOperations(dispatcher); this.excludedPatterns = init.buildExcludedPatternsList(dispatcher); postInit(dispatcher, filterConfig); } finally { if (dispatcher != null) { dispatcher.cleanUpAfterInit(); } init.cleanup(); } }
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter#init
而 Struts2 相关的配置文件就是在第 7 行的 init.initDispatcher(config) 中加载的:
public Dispatcher initDispatcher( HostConfig filterConfig ) { Dispatcher dispatcher = createDispatcher(filterConfig); dispatcher.init(); return dispatcher; }
org.apache.struts2.dispatcher.ng.InitOperations#initDispatcher
再看到 dispatcher.init() :
public void init() { if (configurationManager == null) { configurationManager = createConfigurationManager(DefaultBeanSelectionProvider.DEFAULT_BEAN_NAME); } try { init_FileManager(); init_DefaultProperties(); // [1] init_TraditionalXmlConfigurations(); // [2] init_LegacyStrutsProperties(); // [3] init_CustomConfigurationProviders(); // [5] init_FilterInitParameters() ; // [6] init_AliasStandardObjects() ; // [7] Container container = init_PreloadConfiguration(); container.inject(this); init_CheckWebLogicWorkaround(container); if (!dispatcherListeners.isEmpty()) { for (DispatcherListener l : dispatcherListeners) { l.dispatcherInitialized(this); } } errorHandler.init(servletContext); } catch (Exception ex) { if (LOG.isErrorEnabled()) LOG.error("Dispatcher initialization failed", ex); throw new StrutsException(ex); } }
org.apache.struts2.dispatcher.Dispatcher#init
在上述 9-14 行就会加载 Struts2 相关配置文件,如下:
init_DefaultProperties(); // [1] 加载 struts2-core-2.3.37.jar!/org/apache/struts2/default.properties init_TraditionalXmlConfigurations(); // [2] 加载 struts2-core-2.3.37.jar!/struts-default.xml、src:struts-plugin.xml、src:struts.xml init_LegacyStrutsProperties(); // [3] 加载 src:struts.properties init_CustomConfigurationProviders(); // [5] 加载配置提供类 init_FilterInitParameters() ; // [6] 加载 web.xml中 过滤器初始化参数 init_AliasStandardObjects() ; // [7] 加载 Bean 对象
- 总结上述,配置文件的加载顺序为:
-
-> default.properties
-> struts-default.xml
-> struts-plugin.xml
-> struts.xml
-> struts.properties
-> web.xml
标绿的是我们可配置的。
注意:后配置的常量会覆盖之前配置的常量。
配置相关
struts.xml
package标签
package 标签称为包,这个包与 Java 中的包概念不一致,它是为了更好地管理 action 的配置。
属性:
- name:包的名称,只要在一个项目中不重名即可。
- extends:继承一个包,通常值为 "struts-default"。
- namespace:名称空间,与 action 标签的 name 属性共同组成访问路径。
名称空间匹配的优先级从高到低有如下三种:
1、带名称的名称空间:namespace="/aaa"。
2、根名称空间:namespace="/"。
3、默认名称空间:namespace=""。
- abstract:标识当前包是用来被继承的。
action标签
配置 action 类。
属性:
- name:与 package 标签上的 namespace 属性共同组成访问路径。
- class:Action 类的全路径。
- method:方法名,标识执行 Action 中哪个方法,默认值为 "execute" 。
- converter:用于配置类型转换器。
constant标签
配置常量。
属性:
- name:常量名。
- value:常量值。
include标签
分模块开发时使用,用来引入其它配置文件。
属性:
- file:要引入的配置文件路径,如:"com/zze/config/demo1/struts.xml"。
常量配置
默认常量
在 Struts2 中提供了非常多默认的常量,在 "struts2-core-2.3.37.jar!/org/apache/struts2/default.properties" 中,如下:
# # $Id$ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ### START SNIPPET: complete_file ### Struts default properties ###(can be overridden by a struts.properties file in the root of the classpath) ### ### This can be used to set your default locale and encoding scheme # struts.locale=en_US struts.i18n.encoding=UTF-8 ### if specified, the default object factory can be overridden here ### Note: short-hand notation is supported in some cases, such as "spring" ### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here # struts.objectFactory = spring ### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name ### indicates to the struts-spring integration if Class instances should be cached ### this should, until a future Spring release makes it possible, be left as true ### unless you know exactly what you are doing! ### valid values are: true, false (true is the default) struts.objectFactory.spring.useClassCache = true ### ensures the autowire strategy is always respected. ### valid values are: true, false (false is the default) struts.objectFactory.spring.autoWire.alwaysRespect = false ### By default SpringObjectFactory doesn't support AOP ### This flag was added just temporally to check if nothing is broken ### See https://issues.apache.org/jira/browse/WW-4110 struts.objectFactory.spring.enableAopSupport = false ### if specified, the default object type determiner can be overridden here ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger" ### Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here ### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection ### using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's ### functions are integrated in DefaultObjectTypeDeterminer now. ### To disable tiger support use the "notiger" property value here. #struts.objectTypeDeterminer = tiger #struts.objectTypeDeterminer = notiger ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data # struts.multipart.parser=cos # struts.multipart.parser=pell # struts.multipart.parser=jakarta-stream struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152 ### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org/apache/struts2/extension/custom ### How request URLs are mapped to and from actions #struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper ### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do ### The blank extension allows you to match directory listings as well as pure action names ### without interfering with static resources, which can be specified as an empty string ### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,, struts.action.extension=action,, ### Used by FilterDispatcher ### If true then Struts serves static content from inside its jar. ### If false then the static content must be available at <context_path>/struts struts.serve.static=true ### Used by FilterDispatcher ### This is good for development where one wants changes to the static content be ### fetch on each request. ### NOTE: This will only have effect if struts.serve.static=true ### If true -> Struts will write out header for static contents such that they will ### be cached by web browsers (using Date, Cache-Content, Pragma, Expires) ### headers). ### If false -> Struts will write out header for static contents such that they are ### NOT to be cached by web browser (using Cache-Content, Pragma, Expires ### headers) struts.serve.static.browserCache=true ### Set this to false if you wish to disable implicit dynamic method invocation ### via the URL request. This includes URLs like foo!bar.action, as well as params ### like method:bar (but not action:foo). ### An alternative to implicit dynamic method invocation is to use wildcard ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}"> struts.enable.DynamicMethodInvocation = false ### Set this to true if you wish to allow slashes in your action names. If false, ### Actions names cannot have slashes, and will be accessible via any directory ### prefix. This is the traditional behavior expected of WebWork applications. ### Setting to true is useful when you want to use wildcards and store values ### in the URL, to be extracted by wildcard patterns, such as ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or ### "/foo/save". struts.enable.SlashesInActionNames = false ### Disables support for action: prefix struts.mapper.action.prefix.enabled = false ### Blocks access to actions in other namespace than current with action: prefix struts.mapper.action.prefix.crossNamespaces = false ### use alternative syntax that requires %{} in most places ### to evaluate expressions for String attributes for tags struts.tag.altSyntax=true ### when set to true, Struts will act much more friendly for developers. This ### includes: ### - struts.i18n.reload = true ### - struts.configuration.xml.reload = true ### - raising various debug or ignorable problems to errors ### For example: normally a request to foo.action?someUnknownField=true should ### be ignored (given that any value can come from the web and it ### should not be trusted). However, during development, it may be ### useful to know when these errors are happening and be told of ### them right away. struts.devMode = false ### when set to true, resource bundles will be reloaded on _every_ request. ### this is good during development, but should never be used in production ### struts.i18n.reload=false ### Standard UI theme ### Change this to reflect which path should be used for JSP control tag templates by default struts.ui.theme=xhtml struts.ui.templateDir=template ### Change this to use a different token to indicate template theme expansion struts.ui.theme.expansion.token=~~~ #sets the default template type. Either ftl, vm, or jsp struts.ui.templateSuffix=ftl ### Configuration reloading ### This will cause the configuration to reload struts.xml when it is changed ### struts.configuration.xml.reload=false ### Location of velocity.properties file. defaults to velocity.properties struts.velocity.configfile = velocity.properties ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext struts.velocity.contexts = ### Location of the velocity toolbox struts.velocity.toolboxlocation= ### used to build URLs, such as the UrlTag struts.url.http.port = 80 struts.url.https.port = 443 ### possible values are: none, get or all struts.url.includeParams = none ### Load custom default resource bundles # struts.custom.i18n.resources=testmessages,testmessages2 ### workaround for some app servers that don't handle HttpServletRequest.getParameterMap() ### often used for WebLogic, Orion, and OC4J struts.dispatcher.parametersWorkaround = false ### configure the Freemarker Manager class to be used ### Allows user to plug-in customised Freemarker Manager if necessary ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager ### Enables caching of FreeMarker templates ### Has the same effect as copying the templates under WEB_APP/templates ### struts.freemarker.templatesCache=false ### Enables caching of models on the BeanWrapper struts.freemarker.beanwrapperCache=false ### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap=true ### maxStrongSize for MruCacheStorage for freemarker, when set to 0 SoftCacheStorage which performs better in heavy loaded application ### check WW-3766 for more details struts.freemarker.mru.max.strong.size=0 ### configure the XSLTResult class to use stylesheet caching. ### Set to true for developers and false for production. struts.xslt.nocache=false ### Whether to always select the namespace to be everything before the last slash or not struts.mapper.alwaysSelectFullNamespace=false ### Whether to allow static method access in OGNL expressions or not struts.ognl.allowStaticMethodAccess=false ### Whether to throw a RuntimeException when a property is not found ### in an expression, or when the expression evaluation fails struts.el.throwExceptionOnFailure=false ### Logs as Warnings properties that are not found (very verbose) struts.ognl.logMissingProperties=false ### Caches parsed OGNL expressions, but can lead to memory leaks ### if the application generates a lot of different expressions struts.ognl.enableExpressionCache=true ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError() ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security struts.handle.exception=true ### END SNIPPET: complete_file
struts2-core-2.3.37.jar!/org/apache/struts2/default.properties
下面描述部分配置的含义:
struts.i18n.encoding=UTF-8 # 处理了 POST 请求中文乱码 struts.multipart.saveDir= # 上传文件默认保存位置 struts.multipart.maxSize=2097152 # 上传文件最大大小 struts.action.extension=action,, # 请求路径默认后缀为 action 或空白
修改常量
可以在三个位置修改常量的值:
- struts.xml
直接通过 constant 标签修改常量。
<constant name="struts.action.extension" value="do"/>
struts.xml
- struts.properties
需在 src 下新建一个 struts.properties 文件,在其中以 key=value 的形式修改常量,例:
struts.action.extension=do
struts.properties
- web.xml
需在过滤器中通过配置过滤器的初始化参数修改常量,例:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <init-param> <param-name>struts.action.extension</param-name> <param-value>do</param-value> </init-param> </filter>
web.xml
Action相关
Action的编写
Action 类的编写可有三种方式如下:
POJO
Action 类可以是一个 POJO(简单的 Java 类),例:
package com.zze.action; public class HelloAction1 { public String execute() { System.out.println("hello Struts2"); return "hello"; } }
com.zze.action.HelloAction1
实现Action接口
Action 类也可以实现 Action 接口,例:
package com.zze.action; import com.opensymphony.xwork2.Action; /** * 实现接口 Action * Action 接口中提供了五个逻辑视图名称常量: * public static final String SUCCESS = "success"; * public static final String NONE = "none"; * public static final String ERROR = "error"; * public static final String INPUT = "input"; * public static final String LOGIN = "login"; */ public class HelloAction2 implements Action { @Override public String execute() throws Exception { System.out.println("hello Struts2"); return SUCCESS; } }
com.zze.action.HelloAction2
继承ActionSupport(推荐)
Action 类还可以继承 ActionSupport 类,例:
package com.zze.action; import com.opensymphony.xwork2.ActionSupport; public class HelloAction3 extends ActionSupport { @Override public String execute() throws Exception { System.out.println("hello Struts2"); return super.execute(); } }
com.zze.action.HelloAction3
Action的访问
Action 访问配置也有三种方式,下面通过三种配置来访问下面 Action。
package com.zze.action; import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport { public String save() { System.out.println("from save"); return NONE; } public String delete(){ System.out.println("from delete"); return NONE; } public String select(){ System.out.println("from select"); return NONE; } public String update(){ System.out.println("from update"); return NONE; } }
com.zze.action.TestAction
method配置
<?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> <package name="test" extends="struts-default" namespace="/"> <!--localhost:8080/save--> <action name="save" class="com.zze.action.TestAction" method="save"></action> <!--localhost:8080/delete--> <action name="delete" class="com.zze.action.TestAction" method="delete"></action> <!--localhost:8080/select--> <action name="select" class="com.zze.action.TestAction" method="select"></action> <!--localhost:8080/update--> <action name="update" class="com.zze.action.TestAction" method="update"></action> </package> </struts>
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> <package name="test" extends="struts-default" namespace="/"> <!--localhost:8080/save--> <!--localhost:8080/delete--> <!--localhost:8080/update--> <!--localhost:8080/select--> <!--method:{1} 代表 name 中第一个通配符的取值--> <action name="*" class="com.zze.action.TestAction" method="{1}"></action> <!--localhost:8080/Test_save--> <!--localhost:8080/Test_delete--> <!--localhost:8080/Test_update--> <!--localhost:8080/Test_select--> <!--通配符更抽象写法--> <!--<action name="*_*" class="com.zze.action.{1}Action" method="{2}"></action>--> </package> </struts>
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> <!-- 设置常量,开启动态方法访问 开启之后可通过 <host>:<port>/<actionName>!<methodName> 访问: host : ip port : 端口 actionName : action 名称 methodName : 要访问的方法名称 --> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="test" extends="struts-default" namespace="/"> <!--localhost:8080/test!save--> <!--localhost:8080/test!delete--> <!--localhost:8080/test!select--> <!--localhost:8080/test!delete--> <action name="test" class="com.zze.action.TestAction" method="{1}"></action> </package> </struts>
struts.xml
java框架之Struts2(1)-简介及入门的更多相关文章
- Java框架之Struts2(一)
在学习Struts2之前,我们要知道Java为什么要有反射机制呢?反射机制可以说是填补Java不能动态访问某一个类的空白.利用反射机制,动态的创建一个对象.动态的访问类的某个属性,而且访问哪一个属性自 ...
- java框架之struts2简介
一.Struts2简介 1.Struts2概述 Struts2是Apache发行的MVC开源框架.注意:它只是表现层(MVC)框架. M:model-----数据 ...
- java框架之Struts2(4)-拦截器&标签库
拦截器 概述 Interceptor (拦截器):起到拦截客户端对 Action 请求的作用. Filter:过滤器,过滤客户端向服务器发送的请求. Interceptor:拦截器,拦截的是客户端对 ...
- 【Struts2】简介及入门
一.概述 二.Struts2 快速入门程序 2.1 开发流程比较 2.2 引入依赖 2.2 创建jsp页面 2.3 在web.xml中配置前端控制器 2.4 创建struts.xml配置文件 2.4 ...
- 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例
一.简单介绍 XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象.Json数据的转换.它不需要schema或其他的mapping文件就可以进行java对象和xml ...
- java框架之Hibernate(1)-简介及初使用
简介 hibernate 是一个开源 ORM ( Object / Relationship Mipping ) 框架,它是对象关联关系映射的持久层框架,它对 JDBC 做了轻量级的封装,而我们 ja ...
- java框架之Struts2(2)-访问Servlet API及请求数据封装
准备 为后面测试示例编写代码及配置如下: package com.zze.bean; import java.util.Date; public class User { private String ...
- java框架之Struts2(3)-OGNL&ValueStack
OGNL 概述 OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的.功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用 ...
- Java框架之Struts2(六)
一.OGNL表达式语言 Ognl Object Graphic Navigation Language(对象图导航语言),它是一种功能强大的表达式语言(Expression Language,简称为E ...
随机推荐
- ServiceMesh究竟解决什么问题?
服务网格(ServiceMesh)这两年异常之火,号称是下一代微服务架构,互联网公司经常使用的是微服务分层架构. 随着数据量不断增大,吞吐量不断增加,业务越来越复杂,服务的个数会越来越多,分层会越来越 ...
- .NET Core+NLog+存储配置 日志存入到数据库
nlog-config.xml 配置文件: <?xml version="1.0" encoding="utf-8" ?> <nlog xml ...
- 【原创 Hadoop&Spark 动手实践 9】Spark SQL 程序设计基础与动手实践(上)
[原创 Hadoop&Spark 动手实践 9]SparkSQL程序设计基础与动手实践(上) 目标: 1. 理解Spark SQL最基础的原理 2. 可以使用Spark SQL完成一些简单的数 ...
- 使用python脚本实现iOS图片资源压缩
最近公司有一个新的需求,要把代码进行瘦身,这篇博客记录下如何对图片进行压缩的. 原理: 写一个脚本,把图片文件夹'.xcassets'的所有文件遍历出来,然后使用一个第三方的算法把图片压缩后再替换回去 ...
- MyBatis Plus:No qualifying bean of type 'com.baomidou.mybatisplus.mapper.BaseMapper<?>' available: expected single matching bean but found 4
场景: 应用MyBatis Plus 和通用Mapper 继承自ServiceImpl实现对Service里的方法进行包装再处理. public interface IServiceBase2< ...
- 自动化测试工具Katalon简单使用
前一段时间接触了下Katalon,当时只是简单用了下,今天看到Katalon给发邮件,发现都忘记了,因此重新学习并记录下来 Katalon是在Selemium相同的内核上构建起来的一个自动化测试工具 ...
- 手写LRU算法
import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends Link ...
- [LeetCode] Clone Graph 克隆无向图
Given a reference of a node in a connected undirected graph, return a deep copy (clone) of the graph ...
- Web 端自动化测试
一.环境搭建 准备工具如下:下载 python[python 开发环境](http://python.org/getit/) 下载setuptools: [python 的基础包工具](http:// ...
- 判断网页请求与FTP请求
实例说明 在访问Internet网络时,经常涉及到很多访问协议,其中最明显.最常用的就是访问页面的http协议.访问ftp服务器的FTP协议等.