ASP.NET站点导航(五)

理解并扩展 ASP.NET 2.0 中的站点导航系统 http://msdn.microsoft.com/zh-cn/library/aa479338.aspx

发布日期 : 2006-3-15 | 更新日期 : 2006-3-15

David Gristwood
Developer & Platform Group, Microsoft

适用于:
Microsoft ASP.NET 2.0 (Beta 2)

摘要:ASP.NET 2.0 站点导航系统构建于一个功能强大、灵活的体系结构之上,设计这样的体系结构是为了使其具有可扩展性。本文探究站点提供程序的体系结构并提供一个示例提供程序,该提供程序将文件系统公开为站点导航的数据源,从而替代了标准的 Web.sitemap XML 文件。

请从此处下载示例。

本页内容

简介 简介
理解 ASP.NET 2.0 中的导航系统 理解 ASP.NET 2.0 中的导航系统
导航控件 导航控件
使用导航系统 使用导航系统
实现您自己的站点地图提供程序 实现您自己的站点地图提供程序
一个文件夹站点地图提供程序 一个文件夹站点地图提供程序
小结 小结

简介

大多数 web 站点采用可视化导航的某种形式来帮助用户轻松地浏览站点,以及查找他们所需的信息和 Web 页。尽管不同站点之间的感观效果千差万别,但是通常会使用相同的基本元素 — 以导航栏或菜单列表的形式使用户定位到 web 站点的特定位置。

ASP.NET 1.x 提供的针对站点导航现成的支持很少,导致很多开发人员和 web 设计人员不是构建自己的导航系统,就是购买第三方控件以满足他们的需求。而 ASP.NET 2.0 对此作出了改进,它引入一个使用可插接式框架的导航系统,该框架能够公开站点层次结构和插入这个新模型的控件,因此易于构造一个高质量的菜单和导航系统。

本文描述 ASP.NET 2.0 导航系统的工作原理并展示如何对其进行扩展 — 不仅仅是使用简单的 XML 文件(Visual Studio 2005 中使用的默认机制)。

返回页首

理解 ASP.NET 2.0 中的导航系统

ASP.NET 2.0 导航系统的一个目标是创建一个可以吸引开发人员和 web 站点设计人员的优秀的导航模型,除此之外,它还有一个目标是创建一个提供可扩展性功能的体系结构,该功能能够灵活地满足广泛的需求。该系统基于一个提供程序模型,该模型的使用贯穿于整个 ASP.NET 2.0 框架,由 ASP.NET 2.0 框架提供一个标准的机制用于插入不同的数据源。

ASP.NET 2.0 导航框架可以分解为几个部分:

  • 开发人员在实际 web 页面上使用的web 导航控件(Menu、TreeView 和 SiteMapPath)。这些控件可以通过自定义改变感观效果。

  • TreeView 和菜单导航控件绑定的 SiteMapDataSource 控件,在 Web 导航控件和导航信息的底层提供程序之间提供一个抽象层。

  • 站点地图提供程序是可插接式提供程序,它用于公开描述 web 站点布局的实际信息。ASP.NET 提供了一个提供程序 XmlSiteMapProvider,它使用一个具有特定结构的 XML 文件作为其数据存储。

这种分层的体系结构在底层的站点层次结构和 web 站点上的控件之间制造了更为松散的耦合,提供了更大的灵活性,而且随着站点的不断发展,更容易实现体系结构和设计的改动。

以下表格说明提供程序和控件之间的关系。

图 1. 导航体系结构

对于导航系统,数据源描述用户能够定位的 web 站点页的层次结构,以及将这些信息显示给用户的方式。它作为一个站点地图被引用。一个简单的 web 站点的布局可以是以下形式:

Home
Products
Product A
Product B
Product C
Latest Offers
Contact Us
Email
Visit us
返回页首

导航控件

在深入研究导航系统的内部工作机制之前,了解开发人员如何与之交互十分重要。最常见的方法是通过 ASP.NET 2.0 中的三个新导航控件。一个站点或页面上可以存在多个 Web 导航控件 — 如,主菜单控件放置在页面左侧,另一个菜单控件放在页面顶部,这种情况还是时有发生的,我们能够以编程方式使一个导航控件控制页面上另一个导航控件,或使它们各自独立操作。

导航系统通常与母版页功能一起使用,母版页功能也是 ASP.NET 2.0 中提供的新功能。通过将导航控件放置在站点的母版页上,可以确保整个站点具有统一的感观效果。但是,导航功能和母版页功能互不相关且各自独立。

这三个新 web 控件是:

  • 菜单控件 — 它提供一个传统的导航界面,通常的情况是沿 web 站点的一侧或横跨顶部。它能够显示任意数目的嵌套子菜单,而且,当用户的鼠标停悬在某一项上时,可以显示任意数目的可选弹出子菜单。

    图 2. 菜单控件
  • TreeView 控件 — 它提供一个垂直的树状用户界面,通过选择单个节点可以展开和折叠用户界面。它还提供用于选定某些项的复选框功能。

    图 3. TreeView 控件
  • SiteMapPath 控件 — 它通常作为“breadcrumb”控件进行引用,因为它可以跟踪用户在站点层次结构内的位置。它将当前位置显示为一个路径,通常是从主页到当前位置的路径,因而用户更容易了解自己所处的位置,并定位回路径上的其他页面。

    图 4. SiteMapPath 控件

从体系结构的角度来看,菜单控件和 TreeView 控件有些相似,两者之间的主要区别是编程以及显示方式不同,因此,各自拥有独特的感观效果。要详细了解这两个控件,请参阅 MSDN 中的文章 Introducing the ASP.NET 2.0 TreeView and Menu Controls。值得注意的是,虽然使用菜单控件和 TreeView 控件的最常见情况离不开站点导航,但是它们也能够用于非导航情况,这有待于用户自己做选择。

SiteMapPath (或“breadcrumb”)控件则略为不同。它直接使用 SiteMapProvider,而不是菜单控件和 TreeView 控件使用的 SiteMapDataSource 控件。这说明它是导航系统内部更有针对性的控件,因此支持将其功能扩展到非导航情况的理论依据更少。

返回页首

使用导航系统

理解站点导航工作原理的一种最简单的方法是,直接在一个应用程序内部访问它,而不是通过一个 Web 控件来访问。下列代码示例说明如何与 SiteMap 对象模型进行交互以显示一部分层次结构化的站点信息。

<%@ Page Language="C#" %>
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
this.Label1.Text = "Current Page Title : " +
SiteMap.CurrentNode.Title;
if(SiteMap.CurrentNode.ChildNodes > 0) {
this.HyperLink1.NavigateUrl =
SiteMap.CurrentNode.ChildNodes[0].Url;
this.HyperLink1.Text =
SiteMap.CurrentNode.ChildNodes[0].Title;
}
}
</script>
<html>
<head>
</head>
<body>
<form id="Form1" runat="server">
<asp:Label ID="Label1" runat="server"
Text="Label"></asp:Label><br />
First Child Node: <asp:HyperLink id="HyperLink1"
runat="server">HyperLink</asp:HyperLink>
</form>
</body>
</html>

导航系统将站点地图模型化为一系列节点,称为 SiteMapNodes,在一个树状结构内,每个节点通常表示用户能够定位到的 web 站点上的一个页面(可能有一些节点只是子页面的占位符,或与之类似,本身没有 Web 页)。

SiteMapNode 类具有一些属性和方法,其中最重要的一些是:

  • Title — 当此节点通过一个 web 控件显示时将呈现的文本

  • Url — SiteMapNode 在 web 站点内表示的实际页面的 URL

  • Description — 当鼠标悬停在 HTML 页面的节点上时显示的工具提示

SiteMapNode 类还有一些属性用于保存各个 SiteMapNodes 之间的关联,这些关联描述出站点地图的结构(ChildNodesNextSiblingPreviousSiblingParentNode 等等)。

返回页首

实现您自己的站点地图提供程序

如前所述,ASP.NET 2.0 发行了一个名为 XmlSiteMapProvider 的导航数据存储提供程序,这是大部分开发人员熟悉的默认提供程序。该提供程序使用一个表示 SiteMapNodes 的 XML 文件中的数据。在使用 Visual Studio 2005 时,如果您在 Web 项目中添加了一个新站点地图,那么在默认情况下,在项目内将创建一个 Web.sitemap 文件,并按照下列模板格式进行填充。

<siteMap
xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title=""  description="">
<siteMapNode url="" title=""  description="" />
<siteMapNode url="" title=""  description="" />
</siteMapNode>
</siteMap>

您一眼就可以看出,前面提到的核心 SiteMapNodes 属性(titleurldescription)就是 Web.sitemap XML 架构中的属性,而且树结构(父级、子级等等)是由嵌套的 SiteMapNodes 表示的。

这是处理站点地图信息的一种简单且精练的方法,对于许多 Web 设计人员而言,使用起来绰绰有余。然而,ASP.NET 提供程序模型具有扩展性并不意味着您能够编写自己的提供程序。创建一个自定义站点地图提供程序要考虑三个可能的主要原因:

  • 站点地图信息保存在一个非 XML 文件的数据源中,例如数据库或目录服务。

  • 站点地图信息以 XML 的形式使用,但是使用的架构与 Web.sitemap 使用的架构不同。

  • 需要一个动态的站点地图结构,该结构需要在运行时构造,或者需要一个安全剪裁不能处理的自定义视图。

为了实现您自己的站点地图提供程序,您需要从 System.Web 命名空间的 SiteMapProvider 抽象类中派生一个自定义的提供程序类。虽然 SiteMapProvider 类具有大约二十几个抽象方法或虚方法,但是在您的自定义站点地图提供程序中,只有少数方法需要重写或实现。

如果您的自定义站点地图提供程序使用的数据存储与默认的 XmlSiteMapProvider 的 Web.sitemap XML 架构相似,则应该选择从 StaticSiteMapProvider 类派生,它提供 SiteMapProvider 类的部分实现,并反过来作为实际的 XmlSiteMapProvider 类的基类。

您的类必须至少实现下列方法:

  • FindSiteMapNode — 返回一个与特定 URL 对应的 SiteMapNode。

  • GetChildNodes — 返回一个特定 SiteMapNode 的子节点集合。

  • GetParentNode — 返回一个特定 SiteMapNode 的父节点。

  • GetRootNodeCore — 返回当前提供程序目前管理的所有节点的根节点。

您还应该重写 SiteMapProvider 的 Initialize 方法,在调用基类 Initialize 之后在该方法中执行您自己的初始化。

如果有必要,您可以选择重写与节点相关的一些属性,从而构造更为复杂的表示站点地图的模型:

  • SiteMapNode — 返回映射到当前 HTTPContext URL 的节点。

  • RootNode — 返回存储根部的节点。

  • RootProvider — 返回根部的提供程序,以允许连锁提供程序。

这些属性和方法代表了 SiteMapProvider、Menu / TreeView 控件(通过 SiteMapDataSource)和 SiteMapPath 控件之间的协定。在以下两种情况下会发生这种交互:控件请求填充显示所需的信息,以及用户通过站点进行导航以跟踪站点导航内的当前位置。它是一个事件驱动模型,在交互过程中,导航系统调入提供程序。

如果编写自己的提供程序,您需要决定 SiteMapNodes 是只读还是可写 — 如果是可写的,您需要考虑线程安全,在适当的情况下锁定更新代码,从而保证实现是线程安全的,因为 ASP.NET 通过一个线程池调度请求,因此一个线程池会被多个线程访问。

一个更细节的问题是有关性能和可伸缩性的。一个 web 站点使用几个导航控件,或者底层导航数据存储容量很大的情况并不少见,因此,您需要保证提供程序可以响应,因为这将影响有关设计方面的事宜,包括存储和检索数据的最佳算法以及缓存的潜在作用。

安全问题也需要考虑。Web 站点的普遍要求是只允许会员或其他经过身份验证的用户查看特定页面,而 ASP.NET 2.0 的角色管理提供了定义明确的方法,以便根据安全角色限制对 Web 文件的访问。这一功能通过一个称为安全剪裁的机制扩展到站点导航系统中。安全剪裁强制在尝试访问页面时也应用 Url 和文件授权。在节点上定义一个 roles 属性用于扩展对该节点的访问 — 如果您是在 roles 属性中定义的角色之一,那么将返回该节点;如果您不是这些角色中的一个,那么将执行 Url 和 File Authoriation 检查。对于 XmlSiteMapProvider 而言,在一个 SiteMapNode 项中添加一个 roles="managers" 类型的属性将决定用户在站点地图中是否能够看到该节点。在编写您自己的站点地图提供程序时,这通过 IsAccessableToUser 方法进行处理,它根据用户的角色返回一个布尔值,指示该节点对用户是否可用。派生的提供程序能够使用基类 SiteMapProvider 中存在的默认实现。如果要支持安全性,那么站点地图必须提供某种方法来存储该信息。

返回页首

一个文件夹站点地图提供程序

本文中的示例将一个 web 站点内的子目录公开为实际的站点地图,这使 web 站点导航能够直接映射到文件夹结构,这样的 web 站点结构模型不少见。该示例的重点是说明如何设计和构造一个站点地图提供程序,在这种情况下,它的目的不是覆盖行业优点方面所有可能的“边缘条件”。这些权衡在本文内的适当位置都已强调。

示例提供程序通过 web 站点的子目录进行递归枚举,检查每个文件夹(除了 App_* 和 bin 目录,它们是 ASP.NET 2.0 使用的特殊目录)是否存在一个 default.aspx 文件。如果存在这个文件,示例提供程序则将其添加到站点地图中,并使用包含文件夹的名称作为菜单描述。扩展该示例,使每个目录不仅支持 default.aspx 项,或者必要时在目录内的一个文本文件中存储一个日期工具提示,这实现起来相对比较简单。

提供程序的核心代码如下所示。

[AspNetHostingPermission(SecurityAction.Demand, Level =
AspNetHostingPermissionLevel.Minimal)]
public class FolderSiteMapProvider : SiteMapProvider
{
private SiteMapNode rootNode = null;
// root of tree
private Hashtable urlHash = null;
// hash table based on URL
private Hashtable keyHash = null;
// hash table based on key
string defaultPageName = "Default.aspx";
// only look for this file in each subdirectory
string defaultTitle = "Home";
// description of root node
// override SiteMapProvider Initialize
public override void Initialize(string name,
NameValueCollection attributes)
{
// do base class initialization first
base.Initialize(name, attributes);
// our custom initialization
urlHash = new Hashtable();
keyHash = new Hashtable();
// get web site info
string startFolder = HttpRuntime.AppDomainAppPath;
string startUri =
Uri.EscapeUriString(HttpRuntime.AppDomainAppVirtualPath);
// want canonical format of URI
// Create root node
string key = startFolder;
string url = startUri + @"/" + defaultPageName;
rootNode = new SiteMapNode(this, key, url, defaultTitle);
RootNode.ParentNode = null;
urlHash.Add(url, rootNode);
keyHash.Add(key, rootNode);
// populate entire site
EnumerateFolders(rootNode);
}
// Retrieves a SiteMapNode that represents a page
public override SiteMapNode FindSiteMapNode(string rawUrl)
{
if (urlHash.ContainsKey(rawUrl))
{
SiteMapNode n = (SiteMapNode)urlHash[rawUrl];
return n;
}
else
{
return null;
}
}
// Retrieves the root node of all the nodes
//currently managed by the current provider.
// This method must return a non-null node
protected override SiteMapNode GetRootNodeCore()
{
return rootNode;
}
// Retrieves the child nodes of a specific SiteMapNode
public override SiteMapNodeCollection
GetChildNodes(SiteMapNode node)
{
SiteMapNode n = (SiteMapNode)keyHash[node.Key];
// look up our entry, based on key
return n.ChildNodes;
}
// Retrieves the parent node of a specific SiteMapNode.
public override SiteMapNode GetParentNode(SiteMapNode node)
{
SiteMapNode n = (SiteMapNode)keyHash[node.Key];
// look up our entry, based on key
return n.ParentNode;
}
// helper functions . . .
//  . . .
}

当提供程序通过其 Initialize 方法进行调用时,示例提供程序生成一个文件夹列表,但是不刷新该列表,因此它不检查随时添加的新文件夹,这对一个产品的 web 站点是不合理的。

它不实现安全剪裁,因此所有子目录都可见,但是,要实现安全剪裁是很简单的,只要在 FindSiteMapNodeGetChildNodesGetParentNode 方法内添加对基类 IsNodeAccessible 方法的调用就可以了,IsNodeAccessible 方法将自动获得为 web 站点配置的任何文件授权规则的优点。

提供程序在内部能够以任意种方法表示底层存储,但是,因为它通过 SiteMapNode 类与导航系统进行交互,特别是因为目录层次结构与节点层次结构如此匹配,所以在这种情况下,在内部使用这些方法才有意义。它还维护两个哈希表,其中一个以节点 URL 为关键字,另一个以节点关键字(文件夹名)为关键字,从而支持快速查询节点。对于本示例而言,在内存中保存所有这些信息是有意义的,因为它能够保持简单的编程模型和非常快的查询速度;但是,对于一个拥有成千上万个文件夹的大型站点而言,研究一个不在内存中保存全部信息的机制可能是值得的。

为了保持简单的代码,节点没有以只读的方式处理。在一个实际的具有行业优点的提供程序中,当应用程序不允许添加或修改站点地图节点的内部列表时,就将各个节点以及整个集合标识为只读。

私有的 helper 函数用于构造文件夹层次结构,如以下代码示例所示。

private void EnumerateFolders(SiteMapNode parentNode)
{
// create a node collection for this directory
SiteMapNodeCollection nodes = new SiteMapNodeCollection();
parentNode.ChildNodes = nodes;
// get list of subdirectories within this directory
string targetDirectory = parentNode.Key;
// we use the key to hold the file directory
string[] subdirectoryEntries =
Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
{
// search for any sub folders in this directory
string[] s = subdirectory.Split('\\');
string folder = s[s.Length-1];
string tmp = String.Copy(folder);
tmp = tmp.ToLower();
// avoid any case sensitive matching issues
// check for App_ and bin directories, and don't add them
if (tmp.StartsWith("app_"))
continue;
if (tmp == "bin")
continue;
string testFileName = subdirectory + @"\" + defaultPageName;
if (File.Exists(testFileName))
{
// create new node
string key = subdirectory;
string url = CreateChildUrl(parentNode.Url, folder);
string title = folder;
SiteMapNode n = new SiteMapNode(this, key, url, title);
n.ParentNode = parentNode;
// add it into node collection and table
nodes.Add(n);
urlHash.Add(url, n);
keyHash.Add(key, n);
// and enummerate through this folder now
EnumerateFolders(n);
}
}
}

当提供程序在子目录中枚举时,它为每一个合法子目录创建一个 SiteMapNode 类,并设置它的 keyurltitle 属性。它还为每一个子节点填充 ChildNodes 属性,这个属性是一个 SiteMapNodeCollection,而 ParentNode 属性则向上指回父节点。同时,它也将每个节点添加到哈希表中,以便进行快速查询。

一旦完成这些操作,提供程序需要使用 web.config 文件进行配置。以下项需要添加到 <system.web> 下。

<system.web>
. . .
<siteMap defaultProvider="SimpleProvider">
<providers>
<add name="SimpleProvider"
type="Test.SimpleProvider"/>
</providers>
</siteMap>
. . .
</system.web>
返回页首

小结

本文的目标是使您了解并正确评价 ASP.NET 2.0 站点导航系统,理解不同元素之间协作的原理。代码示例说明了如何通过构造您自己的站点地图提供程序来扩展体系结构,该提供程序使用任意数据源来定义站点层次结构。

关于作者

David Gristwood 在 Microsoft 位于 UK 的开发人员和平台组工作,他大部分时间用来与客户和合作伙伴一起工作,帮助他们设计和构建充分利用 Microsoft .NET 平台的解决方案。他也经常在会议和研讨会上发言。

转载于:https://www.cnblogs.com/min10/archive/2008/11/21/1338475.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java面试题32:Java网络程序设计中,下列正确的描述是()

java面试题32&#xff1a;Java网络程序设计中,下列正确的描述是&#xff08;&#xff09; A&#xff1a;Java网络编程API建立在Socket基础之上 B:Java网络接口只支持tcP以及其上层协议 C&#xff1a;Java网络接口只支持UDP以及其上层协议 D:Java网络接口支持IP以上的所有高…

【收藏】C# WinForm开发系列 - DataGridView 使用方法集锦 - 宁波.Net技术讨论区

1.DataGridView实现课程表 testcontrol.rar 2.DataGridView二维表头及单元格合并 DataGridView单元格合并和二维表头.rar myMultiColHeaderDgv.rar 3.DataGridView单元格显示GIF图片 gifanimationindatagrid.rar 4.自定义显示DataGridView列(行头显示行号与图标,同一单元格显示…

Java中Map, List, Set和Queue的区别和使用场景

转&#xff1a;https://blog.csdn.net/kingcat666/article/details/75579632 1. Java集合类基本概念 在编程中&#xff0c;常常需要集中存放多个数据。从传统意义上讲&#xff0c;数组是我们的一个很好的选择&#xff0c;前提是我们事先已经明确知道我们将要保存的对象的数量…

Proxy server 緩存 jsp html

如果服務器端使用Proxy server,jsp頁面會出現頁面混亂的問題.(不同用戶登陸,出現的是同一個用戶的資料),為了避免這種情況存在,可以有兩種方法解決. eg: menu 所在頁面為toppanel.jsp,鏈接就為:http://localhost:8080/q/toppanel.jsp. 這樣user登陸可能會出現manager的menu,man…

shiro学习(6):shiro连接数据库

首先我们先看一下数据库 再看看数据库的测试数据 在我们创建好的maven项目中看一下目录结构 在pom.xml引入 <dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency&g…

【js监听报错】页面监听js报错问题

<html> <head> <script type"text/javascript">// 页面监听js报错问题 οnerrοrhandleErrvar txt"" function handleErr(msg,url,l) { txt"本页中存在错误如下&#xff1a;\n\n" txt"错误&#xff1a;" msg &quo…

链表逆序(JAVA实现)

题目&#xff1a;将一个有链表头的单向单链表逆序 分析&#xff1a; 链表为空或只有一个元素直接返回&#xff1b;设置两个前后相邻的指针p,q&#xff0c;使得p指向的节点为q指向的节点的后继&#xff1b;重复步骤2&#xff0c;直到q为空&#xff1b;调整链表头和链表尾&…

【微信网页直接下载app】微信跳转-微信浏览器中直接唤起本地浏览器和App

文档传送门&#xff1a;https://github.com/EthanOrange/wechat-redirectdemo&#xff1a; http://wxredirect.jslab.fun/call-app 转载于:https://www.cnblogs.com/xiaohuizhang/p/11377553.html

单例模式的八种写法比较

转:https://www.cnblogs.com/zhaoyan001/p/6365064.html 单例模式是最常用到的设计模式之一&#xff0c;熟悉设计模式的朋友对单例模式都不会陌生。一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式。但是除了这两种方式&#xff0c;本文还会介绍其他几种实现…

java面试题37 关于对象成员占用内存的说法哪个正确?( )

java面试题37 关于对象成员占用内存的说法哪个正确&#xff1f;&#xff08; &#xff09; A 同一个类的对象共用同一段内存 B 同一个类的对象使用不同的内存段&#xff0c;但静态成员共享相同的内存空间 C 对象的方法不占用内存 D 以上都不对 蒙蔽树上蒙蔽果&#xff0c;…

.NET Framework学习笔记(十)

17.委托 .NET框架使用委托delegate来提供回调函数机制。 classSet{ private Object[] items; public Set(int numItems) { items new Object[numItems]; for (int i 0; i < numItems; i) { items[i] i; } }publicdel…

GridView强制不换行

前提是不能设置GridView的列宽(可以设置表头的宽度代替列宽) 把下面代码加到Me.objGv.DataBind()下面 GridView表头强制不换行objGv.HeaderRow.Style.Add("word-break", "keep-all")GridView内容强制不换行Fori AsInteger0ToobjGv.Rows.Count -1Forj AsInt…

Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较

转发:https://www.cnblogs.com/zx-bob-123/archive/2017/12/26/8118074.html 0. 前言 HashMap和HashTable的区别一种比较简单的回答是&#xff1a; &#xff08;1&#xff09;HashMap是非线程安全的&#xff0c;HashTable是线程安全的。 &#xff08;2&#xff09;HashMap的…

不用AJAX框架实现AJAX效果

AJAX( Asynchronous JavaScript and XML),即&#xff1a;javascript和XML; 是一种进行页面局部异步处理数据的技术&#xff0c;用AJAX向服务器发送请求和获取服务器返回的数据并且更新到界面中&#xff0c;不是整个页面的刷新&#xff0c;而是HTML页面中使用JAVASCRIPT创建XMLH…

Java 面试题及答案

JAVA基础 JAVA中的几种基本类型&#xff0c;各占用多少字节&#xff1f; 下图单位是bit,非字节 1B8bit String能被继承吗&#xff1f;为什么&#xff1f; 不可以&#xff0c;因为String类有final修饰符&#xff0c;而final修饰的类是不能被继承的&#xff0c;实现细节不允许…

asp.net如何生成图片验证码

新建一个页面image.aspx,添加命名空间&#xff1a; usingSystem.Drawing.Imaging;usingSystem.IO;然后在Page_load事件拷入如下代码&#xff1a; //生成4位的验证码stringtmp RndNum(4); HttpCookie a newHttpCookie("ImageV",tmp); Response.Cookies.Add(a…

Java中如何实现代理机制(JDK、CGLIB)

代理分为两种&#xff1a; 1.静态代理 2.动态代理 动态代理又分为两种&#xff1a;jdk 实现 &#xff1b;Cglib 实现 3.Java中如何实现代理机制(JDK、CGLIB) JDK动态代理&#xff1a;代理类和目标类实现了共同的接口&#xff0c;用到InvocationHandler接口。CGLIB动态代理…

java面试题43要使某个类能被同一个包中的其他类访问,但不能被这个包以外的类访问,可以( )

java面试题43要使某个类能被同一个包中的其他类访问&#xff0c;但不能被这个包以外的类访问&#xff0c;可以( ) A让该类不使用任何关键字 B使用private关键字 C 使用protected关键字 D 使用void关键字 答案为A 我是歌谣&#xff0c;如果有什么不合理之处指出。我是歌谣&…

在VB应用程序中调用Excel2000

Visual Basic简称(VB)是设计Windows应用程序强有力的开发工具&#xff0c;“全球绝大多数Windows应用程序都是用VB开发的”&#xff1b; Excel是目前使用最广泛的办公应用软件之一&#xff0c;它具有强大的数学分析与计算功能&#xff0c;包括很多VB没有的求值数学表达式的函数…

shiro学习(7):shiro连接数据库 方式二

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 我们先看一下目录结构 首先 jar包引入 pom.xml文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0&quo…