Java Web 应用程序转换为 ASP.NET

Java Web 应用程序转换为 ASP.NET

Brian Jimerson

 

本文讨论: 

· 资源定位 

· I/O 流 

· 日志记录和集合 

· 重构 

本文使用了以下技术: 
ASP.NET、JLCA 和 C#

下载本文中所用的代码: JLCA2007_05.exe (157 KB) 
浏览在线代码 

 目录 

关于 JLCA 
固定财富 
处理输入/输出 API 
日记记录 
集合 
筛选器和 HTTP 处理程序 
源树和命名约定 
曾几何时重构约定 
目录布局和命名空间 
属性 
帕斯Carl 大小写方法名称 
总结 

杰出的软件开发周期遵循简单的模型:收集需求、设计应用程序、编写代码、测试软件和布置软件。不过,有时新的支付项目是依据客户想用来布署应用程序的平台而运维的。在那种状态下,能够将长存应用程序的主干代码转换或移植到预期的平台。

在本文中,小编将通盘介绍怎么着将 Java Web 应用程序转换为以 C# 实现的 ASP.NET 应用程序。本文基于本身所参预的其实项目。在该项目中,大家有现成的基于 Java 的应用程序,而客户愿意采纳它的 ASP.NET 版本。作者第二介绍 Microsoft® Java Language Conversion Assistant (JLCA),并演示在多个平杜阿拉从不直接对应项的大规模开发范例,例如:

· 输入/输出 

· 财富解析 

· 源树布局和命名约定 

· 利用执行环境 

此应用程序作为符合 SOAP 的一项 Web 服务来达成,并采纳守旧的关全面据库永久性存款和储蓄。笔者不会谈谈实际的 Web 服务表示层和 SOAP 接口,而是介绍帮忙它的应用程序。本文的言传身教代码可供下载。

 

关于 JLCA

JLCA 工具用于将 Java 应用程序转换到 C# 应用程序。自 Visual Studio .NET 200叁 初阶,该工具随 Visual Studio® 一起提供。当前版本的 JLCA 三.0 包括在 Visual Studio 二零零五 中,也足以从 JLCA 主页免费下载。

三.0 版包罗对以下地点的转移的增高:诸如 Servlets 和 Java Server Pages (JSP) 那样的 Java 项目,以及利用 Swing 或抽象窗口工具包 (AWT) 的胖客户端应用程序。实际上,JLCA 是很好的用来运转转移的工具,但它不会成功完毕全套进程。因而,不要指望以此进程是完全自行的,使用该工具之后,依旧需求对被转移的品种展开部分手动解析。

若要在 Visual Studio 2005 中早先 JLCA 的入门学习,请单击“文件”|“打开”|“Convert”以运转向导。向导的荧屏可壹看就掌握。您需求输入的基本点音信部分(如图 一 所示)是现有 Java 项目标根目录。

 

图 1 在 JLCA 向导中输入 Java 根目录 (单击该图像获得较大视图)

然后,JLCA 开始将 Java 源代码转换为 C#。该进程所用时间不会太长。我们包涵大约 100 个类公事的骨干代码用了不到 十 分钟就完事了更换,正好够喝杯咖啡的光阴。当然,对于不一致门类和体系,此数字将持有差异。

更换进程一挥而就后,JLCA 将为错误和警示创设 HTML 报告。那么些项还将用作有毛病的分子的注释输入所生成的 C# 代码中。为给你提供赞助,每1项还蕴藏关于化解难题的详细音讯的超链接。

许多警告都得以高枕无忧忽略。它们只是为了记录 Java 和 C# 行为的差距,例如,警告内容:“基元类型之间的勒迫类型转换只怕有两样的行事”。但仍然应当查阅各类警告,以保险那一个差别的表现不会影响应用程序。

先是次查看转换报告时,所告诉的标题就如恐怕太多。在本例中,有 81陆 个谬误和 1陆 个警示。但多数错误都能够分类为两种档次,并且非常简单化解。它们所属的叁种类型是:

· 没有 C# 或 Microsoft .NET Framework 等效项的成员。 

· 在 .NET Framework 中未有间接等效项(例如,Hibernate 和 log四j)的盛行的第三方 Java 库。 

· 处理类加载或能源解析的项。 

其它值得注意的是,JLCA 就像不会总括解析它找不到的导入包(或采取命名空间语句),而是径直将它们传递给生成的 C# 代码。假诺尝试编写翻译新的 C# 应用程序,则大概会博得比转换报告中更加多的编写翻译器错误。

可是,不用操心。前边提到过,那么些不当超越八分之四属于同一的再一次形式,很不难一起消除。小编将在以下几节中牵线这几个大规模错误的化解办法,并商讨为了使转换后的应用程序成为真正的 C# 应用程序而必要实施的其余职务。

 

一向能源

Java 中的财富一定进程(具体来说,是指找到并加载文件财富)与 C# 中的财富一定有十分大区别。Java 使用类加载程序在运作时加载和剖析类定义。类加载程序的一些权利是管理类的上下文,并为它加载的类提供条件有益。在 Java 中,类加载程序选用一种叫做 classpath 的特别类别的环境变量来恒定能源。classpath 与路径环境变量的相似之处在于:它定义了类加载程序应该在哪儿寻找其余类和能源。希望加载另三个类或财富的应用程序能够透过将相对于 classpath 的文本地点告诉类加载程序来落成加载。

Java 中国和北美洲平时见的能源解析方法是应用称为属性文件的分歧常常类别的文书来获得可配置新闻,例如,连接或主机音信、其余财富的门径、本地化字符串和用来身份验证的凭据。属性文件包罗 name=value 对,并以换行分隔。此格式万分接近于 INI 文件,但从没节。

除此以外,不管能源是不是实际位于文件系统中,都始终使用文件系统表示法执行能源一定。那将一挥而就开发职员必须领会应用程序怎么着安插的承负。其余类型的能源(例如,图像和2进制文件)以同样格局开始展览一定和加载。上边是在 Java 中稳定和利用质量文件的演示:

复制代码😉

InputStream is = this.getClass().getResourceAsStream(

    “/application.properties”);

Properties properties = new Properties();

properties.load(is);

String myValue = properties.getProperty(“myKey”);

相反,可以用三种分歧措施安顿和加载 .NET Framework 中的财富:作为二进制能源嵌入程序集中,或当作当麻芋果件系统中的文件。 

做客能源的适用技巧取决于财富的岗位。例如,尽管它是文件系统能源,则足以像下边那样做:

复制代码😉

string fileName = Path.Combine(Path.GetFullPath(

    @”..\config\”), “properties.xml”);

Stream fileStream = File.Open(fileName, FileMode.Open);

//Do something with the stream

但如果财富嵌入程序集中,则更有望那样做: 

复制代码😉

Assembly assembly = Assembly.GetExecutingAssembly();

Stream fileStream = assembly.GetManifestResourceStream(

    GetType(), “properties.xml”);

//Do something with the stream

本人的团组织编写的应用程序有1个只要,正是要拓展分析不必知道财富怎样布置。由于在全方位应用程序中要加载很多财富,因而分析各种加载的财富、明确财富怎样布署接下来修改代码以正确加载它会成本多量精力。由此,大家创设了名称为 ResourceLocator 的实用程序类。

陈设 ResourceLocator 是为着模仿 Java 类加载程序的依据 classpath 解析能源的能力。由于对加载财富的装有调用都是用此方式编写的,因而它犹如是侵入性最低的转换方法。编写 ResourceLocator 之后,我们须求做的只是将调用从 Class.getResourceAsStream 更改为 ResourceLocator.LocateResource。在 Visual Studio 中利用简便的搜索和替换,即可兑现。

从根本来讲便是,ResourceLocator 得到要摸索的能源的称谓和相对路径,然后尝试通过遍历可用程序集和当和姑件系统来找到该财富。还有可提供更加精致控制的重载方法,例如,钦点搜索区域的逐条,以及选用只搜索程序集或文件系统。MSDN® 杂志网址上的代码示例包罗 ResourceLocator 的源代码。

你恐怕觉得经过查找全部可用地点来找到能源的财力非常高,事实当真那样。但是,在应用程序中稳定和加载的富有能源随后将被缓存。这代表在应用程序执行时期各个财富只加载二次,由此会回落那一付出(但它实在会增多内存使用量,尽管要加载大批量财富,那会是个难题)。由此,思考到它使我们减弱了恒河沙数代码更改,大家认为那样的精选是可承受的。还是能够随着时间推移修改那个项指标改变,首先应用简易的消除方案使端口快捷运营,然后缓慢而保障地改变实施,以越来越好地契合基于 .NET 的应用程序的安顿和推行规则。

 

拍卖输入/输出 API

Java 中的 I/O API 与 .NET 中改换后必要处理的 I/O API 有几处距离。二个第二的反差是 .NET I/O 流是双向的,而 Java I/O 流是单向的。那表示在 .NET 编制程序中,理论上能够对同一个流执行读取和写入。但在 Java 中,只好对流执行读取或写入,但不可能对同一流同时施行那五个操作。此差距在转移期间不会促成相当的大的艰巨,因为它是扩展的距离,并且 .NET 流至少提供了与其 Java 对应项1样多的效劳。

设若急需有限协理单向流的安全性,那么可以使用 .NET I/O 读取器和写入器。它们会将基础流打包,以提供读取或写入功效。结果将使 I/O 操作在编制程序上好像于 Java I/O 操作。

对此我们的应用程序,直接待上访问流就已充足。JLCA 能够正确转换 I/O 操作,因而不用为履行编写翻译而开始展览任何变动。可是,大家小心检查了转移后的代码,因为在那一个低级别操作中很不难并发逻辑错误。

 

日志记录

日志记录所强调的是在代码中的特定执行点中将新闻(如,捕获的分外、大概须求运用调节和测试新闻的逻辑方面以及被加载的配置消息)写入指标的能力。Java 和 .NET Framework 都为记录消息提供了作用强大的框架,但其安插和贯彻有一点都不小差别。

在 Java 中,平日经过与新型版本的 Sun ASL翔升 Java 开发工具包 (JDK) 1起分发的 Apache Software Foundation (ASF) log四j 框架或 Java 日志 API 来成功应用程序日志记录功用。Java 日志 API 在实践上很是类似于 log4j,因而,出于此研商指标可以轮流使用那四个框架。对于基于 .NET 的应用程序,Microsoft Enterprise Library 为日志记录提供了有力的使用程序块,称为日志应用程序块(请参阅 Microsoft Logging Application Block homepage)。

Java 和 .NET 中的标准日志框架都提供了强压成效,并且支持陈设时安顿、日志目的宿主(例如,数据库、文件和电子邮件收件人)等等。但请小心,API 设计各不同,由此在转移时期需求您进行部分手动干预。

为了更加好精晓 API 的歧异,在此地以图 二 所示的八个代码段为例进行求证。它们演示了在 Java 和 C# 中执行的广大日志方案。使用 log4j 的代码段通过 getLog 工厂方法创立 Log 对象的静态实例,并将它赋给 MyClass 种类。然后,该代码在调节级别将一部分消息打字与印刷到 Log。C# 代码段(使用日志应用程序块)创造了1个 LogEntry 类的新实例。它象征指标日志中的多少个条目。然后,代码为日志条目分配优先级 二,并将品种设置为 Debug,然后提供了一条音信。最终,它被写入 Logger 类。

 Figure 2 Java 和 C# 中的日志记录 

使用 log4j 的 Java 

复制代码😉

private static final Log log = Logger.getLog(MyClass.class);

//Somewhere else in the class

log.debug(“Printing some debug information.”);

选择日志应用程序块的 C# 

复制代码😉

Logger.Write(”Printing some debug information.”, “Debug”);

不能够不注意,八个阳埃德蒙顿的日志记录都以由外部配置实行控制的。诸如日志记录目的、选拔性日志消息筛选和日志条目格式设置等消息都饱含在此布置中。笔者故目的在于此示例中删去了安顿,因为它与大家的商讨非亲非故。

查看那七个示范就会看到,它们执行10分相像的效应,但以差异方法完结。log4j 示例使用项目来分明音讯是还是不是已记录(基于它的级别)以及它所记录到的对象地点,而日志应用程序块则动用优先级和花色的筛选器的构成来规定要记录的始末。

Logger 类提供了多少个重载的 Write 方法,每一个方法具有分化的左右逢原级别(在那之中囊括多个重载,它同意你提供1个 LogEntry 实例,个中有着多量用来调整怎么着记录消息的操纵装置)。可是,若是是图 二 中运用的简约重载,大家就能与正则表明式结合,用搜索和替换成成功批量转换进度。

日志记录是不行成本财富的长河,须求如临深渊运用,以担保它不会影响应用程序的性质。最终,在应用程序中找寻和替换日志调用只必要曾几何时辰。

 

集合

.NET Framework 和 Java 都提供了强大的集合 API。贰者都有那么些好的可增加性,并且包涵了应用集合时或然碰到的大部动静。上面详细介绍三个常用的汇集类型:列表和词典。

列表是能够按索引访问的成团。它们是有各样的集纳,能够被视作壹种一维数组。另1方面,词典则是称呼与值对的聚合。名称是用来访问集合中的值的键。注意,在词典中无法担保内容是有各种的。

图 三 列出了列表和词典的等效 C# 和 Java 达成。JLCA 能够很好地将这么些 Java 集合类转换到其 .NET 等效项,并且转换后要拓展的拍卖很少。在此地将生成警告,注明这一个大规模集合的表今后五个阳台上差异,由此应当对转移举办表达。可是,转换进程的多方面相应是马到功成和实用的。

 Figure 3 在 .NET 和 Java 中的等价集合类 

 

 

.NET

Java

列表接口

IList, IList<T>

List

常见列表类

ArrayList, List<T>

ArrayList, Vector

词典接口

IDictionary, IDictionary<TKey,TValue>

Map

常见词典类

Hashtable, Dictionary<TKey,TValue>

HashMap, HashTable

骨子里,我们在转换集合时,在原始 Java 应用程序中使用越发集合的地点境遇了难题。例如,使用 Java LinkedHashSet 类时就会遭逢那种题材。依据 Java API 文书档案,LinkedHashSet 类可确定保证 HashSet(它是一种词典类型)中的条目具有相同的逐1,同时防止了别的排序词典产生的支出。就算 LinkedHashSet 的定义简单易懂,但它在应用程序中的使用意义并不明朗。(编写代码的人手已经离开了公司,并且有关为啥采取它从不留下任何文书档案记录。)别的,使用它的上下文不能为我们提供任何音讯,由此不知底使用此类的指标是意在修复难题,照旧处于其余原因。

在通查代码时,大家发现未有选取它的正当理由,因此我们有二种选用:假如在原有应用程序中其实不必要它、为 .NET 应用程序编写大家团结的贯彻、在 .NET Framework 中挑选最周围的恰到好处的聚众。大家只要专门的 LinkedHashSet 实现是不需求的,因为从没迹象声明在其余任哪个地方方使用了排序名称值对。同样,大家轮换了主导 .NET Hashtable 类,并且大家应用现有单位和购并测试注解了科学的表现。不过,尽管大家发现了质量或效益难点,则大概早就替换了 .NET Framework 2.0 中的 SortedDictionary<TKey, 电视机alue> 类,该类表示按键实行排序的键/值对的集结;在个中,它的兑现利用基于红 — 黑树数据结构的聚众。

在大家的档次中,唯有八个地点采纳了尤其的 Java 集合类,并且它们整个表现相似的条件。它们提供的其他功用是平昔不用的,而且使用较为相似的 .NET 对应项完成了手边的义务。

本人应该注意到,我们的 Java 应用程序是接纳 1.4 版的 Java 编写的。直到 1.伍 版,泛型集合才被引进 Java,泛型集合提供对聚集成员强大的键入功效。因而,大家不必深究泛型集合的变换。由于不仅需求转移集合,而且要更换其键入的条款,由此估算在 Java 一.5 版中改换集合将使转换进程特别扑朔迷离。

 

筛选器和 HTTP 处理程序

筛选器是 J2EE Web 应用程序中使用的宽广范例,用于有采用地截获请求和响应,以实践拍卖前和拍卖后操作。筛选器的局地广大用途是日记记录、使用状态审查和安全性。

Java 筛选器完毕了筛选器接口,后者用于定义特定生命周期事件。通过利用 UPAJEROL 映射将 Filter 类映射到一体化或部分 UXC90L,筛选器被应用程序服务器调用。建立相配后,应用程序服务器将完毕所映射的筛选器的生命周期事件,从而将句柄传递给请求和响应。

ASP.NET 通过 IHttpHandler 接口的样式提供了近似的意义。筛选器和 HTTP 处理程序都有分外简单的接口,但它们的法力尤其功能强大。在我们的应用程序中,大家有二种不相同档次的筛选器:壹种选择 GZip 压缩来减弱响应,另①种截获请求以分明请求是不是来自已知的用户代理。

在 Java 应用程序中得以实现减弱筛选器是为着一字不苟品质。它获得每一种响应流,并检查客户端是或不是扶助 GZip 压缩,假如协助,则对响应举行削减。平时,这不是供给的,因为多数现代 HTTP 服务器都提供此意义,而不必要自定义的代码。不过,大家的应用程序是用作 Servlet 应用程序包罗在里头的,它并不须要肯定使用 HTTP 服务器,由此,压缩成效是增值模块。

其次个筛选器基于用户代理标头的值拒绝请求,更值得关切。我们的多如牛毛客户都指望完成某些级别的身份验证,即能够将 HTTP 用户代理标头与允许的代理列表举办比较。要是传入请求的用户代理值不是同意的用户代理,则应当拒绝该请求(日常重回 HTTP 未授权再次回到值)。

能够经过广大措施成功那体系型的央浼/响应筛选器。但超越5八%解决方案都亟待大批量注入代码或品质。幸运的是,J二EE 和 .NET 提供了万分不难的体制,完毕了在应用程序级别截获、修改和调动请求和响应。此外,类似那样的 HTTP 侦听器不是代码普及的,正是说,它们并不是各种类中的代码行。相反,它们是经过应用程序服务器托管和注入的单身的类,因而修改成效绝对于履行全局搜索和替换将进一步简单。

JLCA 3.0 还提供了协助器类,用于扶持将筛选器从 Java 迁移到 ASP.NET 应用程序。图 4 呈现了用 Java 落成的言传身教筛选器(它用来对服务器处理进展计时),还呈现了 JLCA 如何总计将本着 ASP.NET 转换此筛选器。固然在美艳图景下,在移植到 .NET 完成时,可能要求早先重新编写筛选器作为2个 HTTP 处理程序,但 JLCA 提供的支持类 SupportClass.ServetFilter 通过重复落成帮您做到了绝大部分做事。ServletFilter 能够照猫画虎 Java 提供的生命周期。即便它未有缓解所十分,但它能够使移植实现变得很简单。

 Figure 4 使用 ServletFilter 进行 JLCA 转换 

Java 

复制代码😉

import javax.servlet.*;

import java.io.*;

 

public final class TimerFilter implements Filter 

{

 

    public void doFilter(ServletRequest request, 

                         ServletResponse response,

                         FilterChain chain)

        throws IOException, ServletException 

    {

 

        long startTime = System.currentTimeMillis();

        chain.doFilter(request, response);

        long stopTime = System.currentTimeMillis();

        System.out.println(“Time to execute request: “ + 

            (stopTime – startTime) + “ milliseconds”);

    }

 

    public void destroy() {}

 

    public void init(FilterConfig fc) {}

}

C# 

复制代码😉

using System;

using System.Web;

 

// UPGRADE_TODO: Verify list of registered servlet filters. 

public sealed class TimerFilter : SupportClass.ServletFilter

{

    public override void DoFilter(HttpRequest request, 

        HttpResponse response, SupportClass.ServletFilterChain chain)

    {

            

        long startTime = 

            (System.DateTime.Now.Ticks – 621355968000000000) / 10000;

        chain.doFilter(request, response);

        long stopTime = 

            (System.DateTime.Now.Ticks – 621355968000000000) / 10000;

        Console.Out.WriteLine(“Time to execute request: “ + 

            (stopTime – startTime) + “ milliseconds”);

      }

 

      public void  destroy() {}

 

      // UPGRADE_ISSUE: Interface ‘javax.servlet.FilterConfig’ 

      // was not converted.

      public void  init() {}

}

实在,大家的集体选择了将 Java 筛选器功效手动转换为 HTTP 处理程序的点子。为了带领你成就此过程,作者应该比较五个接口。J二EE 筛选器有四个点子:init、destroy 和 doFilter。init 和 destroy 方法是享有自然主要性的生命周期方法,但那高于了本文的座谈范围。而 doFilter 方法在筛选器中进行绝半数以上办事。

在大家的方案中,doFilter 方法从传出请求得到用户代理标头变量,并对照可配置的已知用户代理列表对该变量进行自小编批评。在转移中,最困难的方面是当做参数字传送递给可操作方法的目标存在差距。

在 Java Filter.doFilter 方法中传递了五个参数:请求对象、响应对象和筛选器链对象。相反,IHttpHandler 类的 ProcessRequest 方法唯有一个参数:HttpContext 变量。HttpContext 变量引用 HttpRequest 和 HttpResponse 对象,而且,通过拜访 HttpContext 的积极分子,能够形成超过四分之二1模1样效果。

Java FilterChain 对象很风趣。它代表 HTTP 请求中的筛选器链。筛选器或者将呼吁传递给该链中的下二个筛选器,从而达成以一连方式委派义务。FilterChain 不常使用,但如果要时不时应用,则足以用 IHttpModule 达成来博取相似的行事。

有了 FilterChain,将 Java 筛选器转换为 .NET IHttpHandler 会变得格外不难。首先,要求创设 IHttpHandler 的落成。然后,必要将筛选器的 doFilter 方法中的逻辑重新营造到该兑现的 ProcessRequest 方法中,以便利用 HttpContext 的积极分子,而不是所传递的恳求和响应对象。最终,必要在促成人中学定义 IsReusable 方法;为简易起见,它能够只回去 false(那是另壹种景况,稍后您能够编写更加多代码,以分明同1处理程序实例实际上是还是不是足以被随后的伏乞复用,以一字不苟质量)。

 

源树和命名约定

虽然 Java 和 C# 语言相似,但在词典、源树布局和命名约定方面有异样。在此地,小编想详细表达这几个出入中的一局地。

Java 包(等同于 C# 中的命名空间)服从反向域名约定,后跟应用程序或模块名称,然后是法力。这么些包常常嵌套得很深(常常深度为4或5级)。相反,C# 命名空间平日按效益上的表明性名称举行分组,并且普通嵌套很浅(平常1到四级)。别的,Java 包常常接纳小写或 Camel 大小写,而 C# 命名空间常常使用 帕斯Carl 大小写。同样,Java 方法一般选取 Camel 大小写,而 C# 方法和性质平日选取 帕斯Carl 大小写。

C# 接口平时以大写的 I 初叶,表示接口(这统统是预定,并非正确效能所不可或缺)。按依旧的 Java 约定,接口名称应当以“able”结尾,以表示能够做某事。此预订已大致不再利用,今后,接口的名号与类的名号平日未有别的差异。

C# 使用性质来兑现对个人成员的拜会和多变。属性是元数据包装器,用于获取和装置访问器方法。但 Java 没有质量。平时,私有成员的访问器和变异器是用作艺术 getter 或 setter 来实现的。换句话说,名称为“name”的私家字段的访问器将是 getName。

最后,Java 类必须放在与它注脚的包相相称的目录中(相对于源文件(即 classpath)的根)。C# 未有此限制。

 

何时重构约定

即使并非化解这么些差距被转换的 C# 应用程序就足以编写翻译并运维,但遵循约定始终是最好做法。接纳哪天重构被撤换的代码以服从约定是个劳累的操纵。可是,有多个元素使完毕那件工作应该宜早不宜迟。

是因为重构代码以服从约定对于应用程序正常办事并不是纯属首要的(更不要说有时候它很平淡),因而,人们大概认为随后在档次中不须求这一手续。有那三个业务会使它成为低优先级的职责,由此有望永远不去做这项工作。不过,假如有1个费用团队担当该品种,则透过重构代码使它看起来很熟识,将会扶助协会进步功效和生产力。不要低估那一个职务的第二。这种重构与在转移进度中为了确定保证得到成功结果所提到的别样职分壹样首要。

 

目录布局和命名空间

取名和目录约定是主观性过程,但如故有一般性准则。对于大家的门类,假诺有多少个用以自定义 XML 分析的类,并且它置身 com.mycompany.myapplication.xml.util 命名空间(和目录,转换之后)中。C# 约定建议该类应当放在 Xml.Util 命名空间中。在重构在此之前,大家的目录树外观相仿图 5 所示。Visual Studio 中的文件拖放功效允许完成文件的大体位移,从而使目录树像图 陆 一样。

 

图 5 Java 源树 

 

图 6 C# 源树 

但是,C# 并未有规定文件的目录地方要与其证明的命名空间格外。因而,系统不会更新类的命名空间,以极度文件系统地点。在 Visual Studio 中,要将八个类活动到差异的命名空间中绝非自动化的门路,笔者发觉完结那一点的一流方法是在全部解决方案中推行查找和替换,如图 7 所示。当然,有五个前提就算,便是要将2个命名空间中的全部类都活动到同样目的中。

 

图 7 查找和替换命名空间阐明 (单击该图像获得较大视图)

 

属性

C# 中的属性的协会与 Java 有非常的大不相同。能够将质量视为存款和储蓄类意况(或在 UML 术语中,类的属性)的大规模字段。但 Java 没有品质构造,而是用称为 getter 和 setter 的格局来表示属性。

壹旦有1个类,它有一个誉为“name”的实例变量。您不指望将此变量设置为公用变量,因为如此会丢掉修改此变量的具有控制权。在 Java 中,访问此变量的业内方法是使用 getter 和 setter,如此命名是因为依据预定,为变量名添加前缀“get”或“set”可获得方法名称。由此,假若 name 变量是字符串,则 Java getter 和 setter 恐怕像上边这样:

复制代码😉

public String getName() {

    return this.name;

}

 

protected void setName(String name) {

    this.name = name;

}

C# 提供属性构造以成就同样的效应。就算能够将它们用于应用程序逻辑,但其早先时代目的是为着对个体完毕的细节提供受保险的造访,如前方所述。由此,相同访问的 C# 实现会像下边那样:

复制代码😉

public String Name

{

    get {return this.name;}

    protected set {this.name = value;}

}

当 C# 属性实现同样指标时,小编意识它们进一步清晰 — 在 Java 中,不修改类的情景的方法大概以 get 或 set 早先,那会导致混淆。因而,小编建议重构 Java getter 和 setter,使其变成 C# 属性。

实际上,将 Java getter 和 setter 转换为 C# 属性并从未简单的艺术。正则表达式搜索和替换将会很是复杂,并且 JLCA 只是按原样迁移 Java getter 和 setter 方法,因为无法分辨方法是在修改类的状态,照旧在履行有个别其他职能。大家缓解此难题的法子是使用更有血有肉的消除方案。Visual Studio 为以属性封装私有成员提供了引导。那将转移期望的属性,而不用删除被撤换的 Java getter 和 setter。

作者们的团体在出于其余原因处理代码时,在 Visual Studio 中还生成了 C# 属性,并删除了相应的 getter 和 setter 方法。此步骤之后,开发人士会使用 Visual Studio 200五 查找引用功能来提供一定措施的持有调用站点的列表。那使他们能够引用旧的 getter 和 setter 方法,因而,能够方便地改变对新属性的引用。那不是最好的消除方案,但它的功用尤其得好。

相应强调,那是移植进度中十二分关键的手续,因为属性是 C# 和 .NET 固有的大旨天性,而大家的指标是要创制 C# 应用程序。(请记住,此应用程序最终会由另2个团伙提供支撑,而她们期望获得贰个 C# 应用程序。)

 

帕斯Carl 大小写方法名称

如今提到过,根据约定 Java 方法名称利用 Camel 大小写。换句话说,那个名称开首是小写字母,而种种后续单词边界接纳大写。C# 约定则须要方法和其余成员使用 Pascal 大小写。帕斯Carl 大小写类似于 Camel 大小写,只是名称中的第二个字母也是大写。

那对你表示如何?您也许应当将装有办法重命名,使其以大写字母而不是小写字母初阶。例如,Java 方法

复制代码😉

public void getResponseCode()

有道是重构为 C# 方法: 

复制代码😉

public String GetResponseCode()

与将 getter 和 setter 转换来属性一样,要遍历全部被转移的代码并更新成员以服从 C# 命名约定,未有简单的格局。不过,大家觉得那是格外首要的职分,因为被转换的成员分歧于 C# 成员,而且再也强调,大家的团组织和大家的客户愿意取得不错的 C# 应用程序。

理论上讲,能够编写制定代码转换器以推行此任务,并且大家着想自个儿做那件事。不过,大家决定运用与处理属性相同的路径,即更新成员名称部分。选用手动情势有多少个原因。

对此初学者而言,大家的开发人士已分析过具有代码,以更新任何因素,例如 getter 和 setter。该进度或许是日益扩大的,因为若是不改变成员的名号,就不会潜移默化编译能力或效益。而且,要是出于某个原由此丢掉了3个或三个成员,应用程序也不会搁浅。那么些历程所占有的年华未有你想象的那么长 — 首要难点是该使命很干燥。

Visual Studio 二零零六 有内置的重构援救。重构协理的一有个别工作蕴含:安全重命名成员、显著怎么样才能重命名成员、以及立异对该成员的有着引用。遍历要翻新的装有成员占用了有个别时光,但那是立竿见影的缓解方案。

 

总结

本文介绍了1个将 Java Web 应用程序转换成 ASP.NET 的忠实案例。就我们的话,多数劳苦的工作是由 JLCA 达成的,但有几项使命急需手动干预。可是,JLCA 是功用强大的工具,它使大家的应用程序可以快速移植到实在 .NET 应用程序。

本文意在演示将 Java 应用程序转换到 .NET 的趋势,并提议常常须要消除而高于 JLCA 能力的一点难点。当然,每趟具体的应用程序移植都会遇上特有的题材,本文无法化解全数那些标题。但是,本文提供的部分技术和章程应该能够援助您消除或许碰着的别样难题。