动态定制了一次webservice

自动生成WebService

终于有一个功能是自己的思路,自己解决每一个问题,然后最终调试成功了。

一、确定需求

回学校了,手有点生疏了,但是,还是非常想找师兄讨论一下接下来的项目需求。将近用了快一个小时的时间,确定下来,这次核心功能是这样的:根据不同的条件来选择性的生成并发布webservice。也就是说可以通过界面操作的方式来选择webservice的返回值有哪些。再说的具体一点就是:比如,有三个表,分别存放了学生的个人资料表,学院表,系别表,用户界面中要求有这三个表的列名,用户通过操作选择服务端发布哪几个列的webservice。

二、确定思路

思路的整理是一个比较难搞定的问题。最初的最初,想的是生成两个java文件,然后改一个配置文件,所以,最初的问题就放在了获取数据库表的列名,这个问题,可以通过java中的反射机制来做。因此,就写了一个程序来获取其中某个表的列名,但是,小叶说,写代码要负责,经过他的开导,我把这个类抽象成了一个抽象类,幸亏听了小叶的,要不后面还要重写。接下来的主要问题就是判断,用户提交后,到底是要哪个表的哪个列,难住了……毕竟是三个表,其实,三个表还好,要是n多个表可是咋整?于是,思路被打断,开始思考……突然想到,为什么不在数据库中建立一个视图呢?于是,联系了一下师兄,得到师兄的允许,改为先建立视图,然后用hibernate操作视图。

现在有点清楚了,摆在面前的有这么几个问题:

1、在数据库中建立视图后,怎样用hibernate映射,和普通的表一样吗?而且,视图中没有主键的。

2、新建文件,主要是对文件的内容写入问题。

3、配置文件的修改,也就是要发布webservice--------用流的方式还是用xml解析

思路定下来了,然后就是解决这些问题。其实,最难解决的我觉得是第一个问题。

三、解决问题

1、视图映射问题

我们都知道,hibernate映射表的时候,如果没有主键,就会生成两个实体类。网上有些人说要在生成后改两个实体类,有的说不用改,直接用。我觉得,没有必要。具体的完成过程:

首先,说一下我的表的结构:

users表:usersid(主键)、username、password、depart(外键)

college表:colid(主键)、colname

department表:deid(主键)、dename、colid(外键)

(1)新建一个视图:

Code:
  1. createviewusersinforasselectusers.usersidasusersid,users.usernameasusername,
  2. users.authorityasauthority,department.denameasdepartment,
  3. college.colnameascolnamefromusers,department,college
  4. whereusers.depart=department.deidanddepartment.colid=college.colid

(2)hibernate映射视图

就像普通的表那样,直接映射就可以了,但是,生成的内容是不一样的,因为视图中没有主键,不过不要紧,直接用就行了,唯一要注意的是写法有些不同,比如,要查询,应该这样写:

Code:
  1. "fromUsersinforUwhereU.id.usersid=?"

要获取这个类中属性内容的时候,写法也不一样:

Code:
  1. Stringusername=newString();
  2. Usersinforusers=newUsersinfor();
  3. username=users.getId().getUsername();

2、新建文件并写入

首先,文件名,我想的是用产生随机数的方法来对文件进行命名;读写的时候,要根据提交的checkboxlist的值生成相应内容,当然,要用流的方式。

Code:
  1. packagecom.usersope.IO;
  2. importjava.io.File;
  3. importjava.io.FileInputStream;
  4. importjava.io.FileNotFoundException;
  5. importjava.io.FileOutputStream;
  6. importjava.util.List;
  7. importjava.util.Random;
  8. importcom.opensymphony.xwork2.ActionSupport;
  9. importcom.usersope.IOUtil.FileOpe;
  10. importcom.usersope.IOUtil.UpString;
  11. importcom.usersope.IOUtil.XmlOpe;
  12. publicclassGetUrlextendsActionSupport{
  13. privateStringsql=newString();
  14. privateListuserslist;
  15. FilefileImpl;
  16. FileIfile;
  17. Randomrand;
  18. inti;
  19. StringfilenameImpl=newString();
  20. StringfilecontentImpl=newString();
  21. StringIfilename=newString();
  22. StringIfilecontent=newString();
  23. Stringservicename=newString();//配置文件中要用的
  24. Stringurl=newString();
  25. publicStringexecute(){
  26. //产生随机数
  27. rand=newRandom();
  28. i=rand.nextInt(100);
  29. //要写入的字符串
  30. //找到文件,如果文件不存在,则新建.这里是新建文件
  31. filenameImpl="Getmes"+i+"Impl";
  32. servicename="Getmes"+i;
  33. Ifilename="IGetmes"+i;
  34. fileImpl=newFile("F://myProject//userservice//src//com//service//"+filenameImpl+".java");
  35. Ifile=newFile("F://myProject//userservice//src//com//service//"+Ifilename+".java");
  36. while(fileImpl.exists()||Ifile.exists()){
  37. //产生随机数
  38. i=rand.nextInt(100);
  39. filenameImpl="Getmes"+i+"Impl";
  40. servicename="Getmes"+i;
  41. fileImpl=newFile("F://myProject//userservice//src//com//service//"+filenameImpl+".java");
  42. Ifile=newFile("F://myProject//userservice//src//com//service//"+Ifilename+".java");
  43. }
  44. FileOpe.createFiles(fileImpl);//用到了上面的静态方法
  45. FileOpe.createFiles(Ifile);
  46. //以上是建立两个文件
  47. //下面是写文件
  48. //接口里面的内容
  49. Ifilecontent="packagecom.service;";
  50. Ifilecontent=Ifilecontent+"publicinterface"+Ifilename;
  51. Ifilecontent=Ifilecontent+"{publicStringgetmes(intuserid);}";
  52. //接口实现里面的内容
  53. Filefilemedo1=newFile("F://myProject//userservice//src//com//service//ok1.txt");
  54. Filefilemedo2=newFile("F://myProject//userservice//src//com//service//ok2.txt");
  55. try{
  56. FileInputStreamfis1=newFileInputStream(filemedo1);
  57. Strings1=FileOpe.readFileInputStr(fis1);//读取数据,并将读取到的数据存储到数组中
  58. filecontentImpl=filecontentImpl+s1;
  59. filecontentImpl=filecontentImpl+""+filenameImpl+"implements"+Ifilename;
  60. FileInputStreamfis2=newFileInputStream(filemedo2);
  61. Strings2=FileOpe.readFileInputStr(fis2);//读取数据,并将读取到的数据存储到数组中
  62. filecontentImpl=filecontentImpl+s2;
  63. }catch(FileNotFoundExceptione1){
  64. //TODOAuto-generatedcatchblock
  65. e1.printStackTrace();
  66. }//创建流对象
  67. //将字符串的第一个字母变成大写
  68. for(inti=0;i<userslist.size();i++){
  69. Stringstr=(String)userslist.get(i);
  70. char[]aa=UpString.upcase(str);
  71. Stringbb=newString(aa);//字符数组转换为string类型
  72. filecontentImpl=filecontentImpl+"idmes=idmes+"+"/""+"<"+str+">"+"/"";
  73. filecontentImpl=filecontentImpl+"+users.getId().get";
  74. filecontentImpl=filecontentImpl+bb+"()+";
  75. filecontentImpl=filecontentImpl+"/""+"</"+str+">"+"/";"+"";
  76. }
  77. filecontentImpl=filecontentImpl+"idmes=idmes+"+"/""+"</user>"+"/""+";"+""+"returnidmes;}}";
  78. FileOutputStreamfos=null;
  79. try{
  80. fos=newFileOutputStream(fileImpl,true);//为true的时候是追加,默认是覆盖
  81. FileOpe.writeString(filecontentImpl,fos);
  82. fos=newFileOutputStream(Ifile,true);//为true的时候是追加,默认是覆盖
  83. FileOpe.writeString(Ifilecontent,fos);
  84. }catch(FileNotFoundExceptione){
  85. }finally{
  86. try{
  87. fos.close();
  88. }catch(Exceptione){
  89. e.printStackTrace();
  90. }
  91. }
  92. XmlOpe.add(servicename);
  93. //转到显示url的页面
  94. url="http://localhost:8080/userservice/services/"+servicename+"?wsdl";
  95. return"url";
  96. }
  97. publicStringgetUrl(){
  98. returnurl;
  99. }
  100. publicvoidsetUrl(Stringurl){
  101. this.url=url;
  102. }
  103. publicListgetUserslist(){
  104. returnuserslist;
  105. }
  106. publicvoidsetUserslist(Listuserslist){
  107. this.userslist=userslist;
  108. }
  109. }

其中,涉及到的问题有:将一个字符串的首写字母变为大写:

Code:
  1. publicclassUpString{
  2. publicstaticchar[]upcase(Stringstr){
  3. char[]aa=str.toCharArray();
  4. if(aa[0]>96&&aa[0]<123)
  5. aa[0]=(char)(aa[0]-32);//小写换大写
  6. //System.out.print(aa);
  7. returnaa;
  8. }
  9. }

文件的操作等。

3、配置文件的修改,即services.xml文件的修改

征求了小叶的意见,用解析的方式进行,这样也明了。只不过其中只要传递一个参数就ok了。

Code:
  1. importjavax.xml.parsers.DocumentBuilderFactory;
  2. importjava.io.File;
  3. importjava.io.FileNotFoundException;
  4. importjava.io.FileOutputStream;
  5. importjava.io.IOException;
  6. importorg.w3c.dom.*;
  7. importorg.xml.sax.SAXException;
  8. importjavax.xml.parsers.*;
  9. importjavax.xml.transform.*;
  10. importjavax.xml.transform.dom.DOMSource;
  11. importjavax.xml.transform.stream.*;
  12. importjavax.xml.xpath.*;
  13. publicclassXmlOpe{
  14. //参数就是生成的文件名
  15. publicstaticvoidadd(Stringservicename){
  16. DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
  17. Elementservice=null;
  18. ElementtheElem=null;
  19. Elementroot=null;
  20. try{
  21. factory.setIgnoringElementContentWhitespace(true);
  22. DocumentBuilderdb=factory.newDocumentBuilder();
  23. Documentxmldoc=db.parse(newFile("F://myProject//userservice//WebServices//services.xml"));
  24. root=xmldoc.getDocumentElement();
  25. //---新发布一个webservice----
  26. service=xmldoc.createElement("service");
  27. theElem=xmldoc.createElement("name");
  28. theElem.setTextContent(servicename);
  29. service.appendChild(theElem);
  30. theElem=xmldoc.createElement("serviceClass");
  31. theElem.setTextContent("com.service."+"I"+servicename);
  32. service.appendChild(theElem);
  33. theElem=xmldoc.createElement("implementationClass");
  34. theElem.setTextContent("com.service."+servicename+"Impl");
  35. service.appendChild(theElem);
  36. theElem=xmldoc.createElement("style");
  37. theElem.setTextContent("wrapped");
  38. service.appendChild(theElem);
  39. theElem=xmldoc.createElement("use");
  40. theElem.setTextContent("literal");
  41. service.appendChild(theElem);
  42. theElem=xmldoc.createElement("scope");
  43. theElem.setTextContent("application");
  44. service.appendChild(theElem);
  45. System.out.print(1);
  46. root.appendChild(service);
  47. saveXml("F://myProject//userservice//WebServices//services.xml",xmldoc);
  48. }catch(ParserConfigurationExceptione){
  49. e.printStackTrace();
  50. }catch(SAXExceptione){
  51. //TODOAuto-generatedcatchblock
  52. e.printStackTrace();
  53. }catch(IOExceptione){
  54. //TODOAuto-generatedcatchblock
  55. e.printStackTrace();
  56. }
  57. }
  58. //将Document输出到文件
  59. publicstaticvoidsaveXml(StringfileName,Documentdoc){
  60. TransformerFactorytransFactory=TransformerFactory.newInstance();
  61. try{
  62. Transformertransformer=transFactory.newTransformer();
  63. transformer.setOutputProperty("indent","yes");
  64. DOMSourcesource=newDOMSource();
  65. source.setNode(doc);
  66. StreamResultresult=newStreamResult();
  67. result.setOutputStream(newFileOutputStream(fileName));
  68. transformer.transform(source,result);
  69. }catch(TransformerConfigurationExceptione){
  70. e.printStackTrace();
  71. }catch(TransformerExceptione){
  72. e.printStackTrace();
  73. }catch(FileNotFoundExceptione){
  74. e.printStackTrace();
  75. }
  76. }
  77. }

四、调试并发现问题

调试也花了一些时间,最终还是调试成功了,但是,其中有一个问题又出现了:每次生成webservice,都必须要求服务器重新启动才能生效。小叶曾经说过可以用监听器,不过,我没有试过,不知道行不行。暂时这个先做到这吧。

大家见笑了……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值