提高生产性工具 - 各种工具的集成(三)
这周学习了一下Struts2的一些知识,按照网络上各种博文的指点,跌跌撞撞,捣鼓出了一个Struts2的Demo了。
原来一直是学习NET的,一下子开始玩Java的东西,还需要一点时间来适应Eclapse。
Struts的Jar包导入都是依靠Maven进行的,据说Maven可以直接生成Struts的工程,尝试了一下,公司网络不给力,没有成功。
Struts的Helloworld环境配置,网络上有很多文章了,这里也不多唠叨了。有一点请注意,
如果你使用Maven的话,在百度上检索 Maven Struts,第一个检索结果是 Spring-Struts-PlugIn,这个是Spring结合Struts用的,
正确的Maven,应该是 struts2-core
groupId | artifactId | version | scope | 説明 | ||||||||||||||||||||||||||||
org.apache.struts | struts2-core | 2.3.20 | compile | |||||||||||||||||||||||||||||
javassist | javassist | 3.12.1.GA | compile |
本着一切工具化的目标,将Struts的路由做成了工具。
按照老规矩,还是从Excel读取数据,然后用NET写XML
非必须项目 | |||||
Action名称 | 类名称 | 结果字符(Result) | 迁移目标 | Model | 备注 |
SearchUser | searchAction | ||||
listResult | /listResult.jsp | ||||
listData | /more.jsp | ||||
wordPre | /officePre.jsp | ||||
manager | /manager.jsp | ||||
success | /success.jsp | ||||
SearchPerson | RunAction | ||||
listResult2 | /listResult.aspx | ||||
listData2 | /more.aspx | ||||
wordPre2 | /officePre.aspx | ||||
manager2 | /manager.aspx | ||||
success2 | /success.aspx |
自动生成的XML如下:
<struts> <package name="com.chuwa.route" extends="struts-default"> <action name="success" class="searchAction"> <result>/listResult.jsp</result> <result>/more.jsp</result> <result>/officePre.jsp</result> <result>/manager.jsp</result> <result>/success.jsp</result> </action> <action name="success2" class="RunAction"> <result>/listResult.aspx</result> <result>/more.aspx</result> <result>/officePre.aspx</result> <result>/manager.aspx</result> <result>/success.aspx</result> </action> </package> </struts>
生成的代码也不是很复杂,这里就是XML的一些操作,熟悉了,基本上什么样子的XML文档都能代码自动生成了。
下面是Excel数据转XML数据的一个很好的例子,
using Microsoft.VisualBasic; using System; using System.Xml; namespace DevKit.MVCTool { /// <summary> /// Route (Struts2) /// </summary> internal static class Struts2RouteRule { internal static void GenerateRouteXml(string ExcelFilename, string XMLfilename, string PackageName) { if (String.IsNullOrEmpty(ExcelFilename)) { ExcelFilename = Common.Utility.PickFile(Common.Utility.FileDialogMode.Open, Common.Utility.XlsxFilter); } dynamic excelObj = Interaction.CreateObject("Excel.Application"); excelObj.Visible = true; dynamic workbook = excelObj.Workbooks.Open(ExcelFilename); dynamic worksheet = workbook.Sheets(1); int seekrow = 8; XmlDocument struts = new XmlDocument(); XmlNode strutsRoot = struts.CreateElement("struts"); XmlNode package = struts.CreateElement("package"); ((XmlElement)package).SetAttribute("name", PackageName); ((XmlElement)package).SetAttribute("extends", "struts-default"); XmlNode action = null; while (!String.IsNullOrEmpty(worksheet.Cells(seekrow, 3).Text) || !String.IsNullOrEmpty(worksheet.Cells(seekrow, 5).Text)) { //ActionName或者Result不为空 if (!String.IsNullOrEmpty(worksheet.Cells(seekrow, 3).Text)) { if (action != null) { package.AppendChild(action); } action = struts.CreateElement("action"); ((XmlElement)action).SetAttribute("name", (worksheet.Cells(seekrow, 3).Text)); ((XmlElement)action).SetAttribute("class", (worksheet.Cells(seekrow, 4).Text)); } else { XmlNode result = struts.CreateElement("result"); ((XmlElement)action).SetAttribute("name", (worksheet.Cells(seekrow, 5).Text)); result.InnerText = worksheet.Cells(seekrow, 6).Text; action.AppendChild(result); } seekrow++; } package.AppendChild(action); strutsRoot.AppendChild(package); struts.AppendChild(strutsRoot); struts.Save(XMLfilename); workbook.Close(); excelObj.Quit(); excelObj = null; } } }
Native转ASCII
Java的世界,不知道为什么,对于多语言支持不是很好,很多时候需要将Native转为ASCII
例如将错误信息放在资源文件里面的时候,那个文件需要将文字进行转码。
下面这个工具就是做转码用的,可以临时看一个字符的转码内容,当然,老规矩,可以批量将Excel表格里面的东西都转码。
Native2ASCII的逻辑是从Java源代码里面直接复制过来的。
Java代码复制到VS里面,大部分代码都可以通过简单修改,变成C#的代码。。。
注意:Java的 Substring 函数,和C#的,功能有些不一样。带2个参数的版本,Java是从第几位到第几位,C#是从第几位,取多少位。
Java的方法大都首字母小写,骆驼命名,C#的是Pascal命名。。。
using Microsoft.VisualBasic; using System; using System.Text; namespace DevKit.Common { public class Native2AsciiUtils { /// <summary> /// /// </summary> private static String PREFIX = "\\u"; /// <summary> /// /// </summary> /// <param name="str"></param> /// <returns></returns> public static String native2Ascii(String str) { char[] chars = str.ToCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < chars.Length; i++) { sb.Append(char2Ascii(chars[i])); } return sb.ToString(); } /// <summary> /// /// </summary> /// <param name="c"></param> /// <returns></returns> private static String char2Ascii(char c) { if (c > 255) { StringBuilder sb = new StringBuilder(); sb.Append(PREFIX); int code = (c >> 8); String tmp = Convert.ToString(code, 16); if (tmp.Length == 1) { sb.Append("0"); } sb.Append(tmp); code = (c & 0xFF); tmp = Convert.ToString(code, 16); if (tmp.Length == 1) { sb.Append("0"); } sb.Append(tmp); return sb.ToString(); } else { return Char.ToString(c); } } /// <summary> /// /// </summary> /// <param name="str"></param> /// <returns></returns> public static String ascii2Native(String str) { StringBuilder sb = new StringBuilder(); int begin = 0; int index = str.IndexOf(PREFIX); while (index != -1) { sb.Append(str.Substring(begin, index - begin)); sb.Append(ascii2Char(str.Substring(index, 6))); begin = index + 6; index = str.IndexOf(PREFIX, begin); } sb.Append(str.Substring(begin)); return sb.ToString(); } /// <summary> /// /// </summary> /// <param name="str"></param> /// <returns></returns> private static char ascii2Char(String str) { if (str.Length != 6) { throw new ArgumentException( "Ascii string of a native character must be 6 character."); } if (!PREFIX.Equals(str.Substring(0, 2))) { throw new ArgumentException( "Ascii string of a native character must start with \"\\u\"."); } String tmp = str.Substring(2, 2); int code = Convert.ToInt16(tmp, 16) << 8; tmp = str.Substring(4, 2); code += Convert.ToInt16(tmp, 16); return (char)code; } /// <summary> /// /// </summary> /// <param name="p"></param> public static void BatchConvert(string ExcelFilename) { dynamic excelObj = Interaction.CreateObject("Excel.Application"); excelObj.Visible = true; dynamic workbook; workbook = excelObj.Workbooks.Open(ExcelFilename); dynamic worksheet = workbook.Sheets(1); int row = 5; while (!String.IsNullOrEmpty(worksheet.Cells(row,2).Text)) { if (!String.IsNullOrEmpty(worksheet.Cells(row, 3).Text)) { worksheet.Cells(row, 4).Value = Common.Native2AsciiUtils.native2Ascii(worksheet.Cells(row, 3).Text); } else { worksheet.Cells(row, 3).Value = Common.Native2AsciiUtils.ascii2Native(worksheet.Cells(row, 4).Text); } row++; } workbook.Save(); workbook.Close(); excelObj.Quit(); excelObj = null; } } }
最后,花了些时间,做了一个根据Model自动生成CreateTable的功能。
对于EF不是很熟悉,然后发现EF貌似不能自动为MySql建表,所以,就自己写了一个CreateTable自动生成功能。
结合以前的工具,Model设计书,一键生成MVC的Model类(CodeFirst??),然后生成Mysql的建表CreateTable的SQL文。
DROP TABLE IF EXISTS `test`.`Candidate`; CREATE TABLE `test`.`Candidate` ( `No` int(0) NOT NULL AUTO_INCREMENT, `Position` varchar(20) NOT NULL, `Name` varchar(20) NOT NULL, `Contact` varchar(20) NOT NULL, `Language` smallint(2) NOT NULL, `University` varchar(50) NOT NULL, `Major` varchar(20) NOT NULL, `MarketBackground` tinyint(1) DEFAULT NULL, `ITBackground` tinyint(1) DEFAULT NULL, `Comments` varchar(100) DEFAULT NULL, PRIMARY KEY (`No`) ) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
这些工具,其实就是给设计人员使用的,我们这些万能的程序员们一切都可以手工完成的。
但是如果项目很庞大,对方一直改数据定义,那么直接将工具仍给设计人员,然他们自己动手,生成Model和CreateTable文,我想生产性应该可以提高很多了吧。
程序员应该多学习领域知识,那个地方才是最值钱的,学习的好,可以转做咨询,职业生涯上一个档次。
不要把时间花在CreateTable,Model类这些地方。如果在工作中,觉得有很多重复劳动,一定要做工具。保证正确性,节约时间。