Java http接口进阶——自我理解为接口框架形式
大龄青年初入Java,所以对有些专业术语的了解不是很深入,可能在写博文的时候,会有误解,望各大V能慷慨指出,感激不敬。
一、接口框架形式
接口框架如下:
形式比较简单,承接上篇的简单接口模式。
大概思路:以简单的servlet的形式做接口调用测试。
bean层以@XMLRootElement注释进行bean与xml的转化。
api层用来写具体需要实现的接口类,继承抽象接口类,进行数据库操作,并且返回对象。
servlet层用来写每一接口来调用的servlet类。
一个bean对应一个api类对应一个servlet类。
二、各类代码
AbstractApi类:此为抽象类,用来替后面各个接口继承,并且把数据库连接以ThreadLocal的形式写在此类中。
1 package com.mdf.api; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.SQLException; 6 7 import com.mdf.api.bean.TestBean; 8 9 public abstract class AbstractApi { 10 11 //数据库连接URL 12 private static final ThreadLocal<Connection> ConnectionHolder=new ThreadLocal<Connection>(); 13 private static String mysqlurl = "jdbc:mysql://localhost:3306/test?" 14 + "user=root&password=root&useUnicode=true&characterEncoding=UTF8"; 15 //数据库连接 16 public static void setConnection() throws Exception{ 17 Connection conn=null; 18 conn=DriverManager.getConnection(mysqlurl); 19 ConnectionHolder.set(conn); 20 } 21 22 //获取数据库连接 23 public static Connection getConnection() throws Exception{ 24 setConnection(); 25 return ConnectionHolder.get(); 26 } 27 //连接释放 28 public static void removeConnection(Connection conn){ 29 if(conn!=null){ 30 try { 31 conn.close(); 32 } catch (SQLException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 conn=null; 37 } 38 } 39 //接口抽象方法 40 public abstract Object resolve(Object object) throws Exception; 41 //获取接口类映射 42 public static AbstractApi getAPI(String apiname) throws Exception{ 43 AbstractApi abstractapi=null; 44 //System.out.println(String.format("com.mdf.api.api.%sAPI",apiname)); 45 abstractapi=(AbstractApi)Class.forName(String.format("com.mdf.api.api.%sAPI",apiname)).newInstance(); 46 47 return abstractapi; 48 } 49 50 }
Marshal类:对象转为string类型的xml类
1 package com.mdf.api; 2 3 import java.io.StringWriter; 4 5 import javax.xml.bind.JAXBContext; 6 import javax.xml.bind.Marshaller; 7 8 public class Marshal { 9 10 public static String objecttoxml(Object object) throws Exception{ 11 Class<?> clazz=null; 12 clazz=object.getClass(); 13 //反射机制 获取JAXBContext对象 14 JAXBContext context =JAXBContext.newInstance(clazz); 15 //创建Marshaller对象 16 Marshaller marshaller=context.createMarshaller(); 17 StringWriter writer=new StringWriter(); 18 //将object转为xml 19 marshaller.marshal(object, writer); 20 return writer.toString(); 21 } 22 23 }
Umarshal类:string类型转为对象类
package com.mdf.api; import java.io.StringReader; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; public class UnMarshal { public static Object xmltoobject(Object object,String xmlstr) throws Exception{ JAXBContext context=JAXBContext.newInstance(object.getClass()); Unmarshaller unmarsharller=context.createUnmarshaller(); StringReader sr=new StringReader(xmlstr); return unmarsharller.unmarshal(sr); } }
Toxmlfile:string类转为xml文件类
1 package com.mdf.api; 2 3 import java.io.StringReader; 4 5 import javax.xml.parsers.DocumentBuilder; 6 import javax.xml.parsers.DocumentBuilderFactory; 7 8 import org.w3c.dom.Document; 9 import org.xml.sax.InputSource; 10 11 public class Toxmlfile { 12 13 public static Document strtoxmlfile(String xmlstr) throws Exception { 14 Document returnValue = null; //返回文件类型 15 DocumentBuilder dbuilder = null; 16 DocumentBuilderFactory factory = null; //dom解析工厂 17 StringReader sr = null; //读取流 18 InputSource is = null; //sax的解析 将字符串转为inputsource 用来即系为xml 19 20 sr = new StringReader(xmlstr); 21 is = new InputSource(sr); 22 23 factory = DocumentBuilderFactory.newInstance(); 24 dbuilder = factory.newDocumentBuilder(); 25 returnValue = dbuilder.parse(is); 26 27 return returnValue; 28 29 } 30 31 }
TestBeanAPI:具体接口类
1 package com.mdf.api.api; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 import com.mdf.api.AbstractApi; 11 import com.mdf.api.bean.TestBean; 12 import com.mdf.api.bean.TestBeanList; 13 14 public class TestBeanAPI extends AbstractApi { 15 16 @Override 17 public Object resolve(Object object) throws Exception { 18 19 // 数据库连接获取数据对象 20 Connection conn = null; 21 PreparedStatement psmt = null; 22 ResultSet rs = null; 23 TestBean rtestbean=null; 24 rtestbean=(TestBean)object; 25 List<TestBean> testbeans = null; 26 TestBeanList tbl = null; 27 StringBuffer sqlstr = null; 28 29 try { 30 Class.forName("com.mysql.jdbc.Driver"); 31 conn = getConnection(); 32 testbeans = new ArrayList<TestBean>(); 33 tbl = new TestBeanList(); 34 sqlstr = new StringBuffer(); 35 sqlstr.append("SELECT ID,NAME FROM TEST"); 36 if (rtestbean.getId() != 0) { 37 sqlstr.append(" WHERE ID=?"); 38 psmt = conn.prepareStatement(sqlstr.toString()); 39 psmt.setInt(1, rtestbean.getId()); 40 } else { 41 psmt = conn.prepareStatement(sqlstr.toString()); 42 } 43 rs = psmt.executeQuery(); 44 while (rs.next()) { 45 TestBean testbean = new TestBean(); 46 testbean.setId(rs.getInt("ID")); 47 testbean.setName(rs.getString("NAME")); 48 testbeans.add(testbean); 49 } 50 tbl.setTestbeans(testbeans.toArray(new TestBean[testbeans.size()])); 51 } catch (Exception e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } finally { 55 if (rs != null) { 56 try { 57 rs.close(); 58 } catch (SQLException e) { 59 // TODO Auto-generated catch block 60 e.printStackTrace(); 61 } 62 rs = null; 63 } 64 if (psmt != null) { 65 try { 66 psmt.close(); 67 } catch (SQLException e) { 68 // TODO Auto-generated catch block 69 e.printStackTrace(); 70 } 71 psmt = null; 72 } 73 removeConnection(conn); 74 } 75 return tbl; 76 } 77 }
TestBean:bean类,以@xmlrootelement注释
1 package com.mdf.api.bean; 2 3 import javax.xml.bind.annotation.XmlElement; 4 import javax.xml.bind.annotation.XmlRootElement; 5 6 @XmlRootElement(name="TestBean") 7 public class TestBean { 8 private int id; 9 private String name; 10 public int getId() { 11 return id; 12 } 13 @XmlElement 14 public void setId(int id) { 15 this.id = id; 16 } 17 public String getName() { 18 return name; 19 } 20 @XmlElement 21 public void setName(String name) { 22 this.name = name; 23 } 24 25 }
TestBeanList:以上bean的list形式
1 package com.mdf.api.bean; 2 3 import javax.xml.bind.annotation.XmlElement; 4 import javax.xml.bind.annotation.XmlRootElement; 5 6 @XmlRootElement(name="TestBeanList") 7 public class TestBeanList { 8 9 private TestBean[] testbeans=null; 10 11 public TestBean[] getTestbeans() { 12 return testbeans; 13 } 14 @XmlElement 15 public void setTestbeans(TestBean[] testbeans) { 16 this.testbeans = testbeans; 17 } 18 19 }
TestBeanAPIServlet:调用的servlet类
1 package com.mdf.api.servlet; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.PrintWriter; 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.w3c.dom.Document; 14 15 import com.mdf.api.AbstractApi; 16 import com.mdf.api.Marshal; 17 import com.mdf.api.Toxmlfile; 18 import com.mdf.api.UnMarshal; 19 import com.mdf.api.api.TestBeanAPI; 20 import com.mdf.api.bean.TestBean; 21 import com.mdf.api.bean.TestBeanList; 22 23 /** 24 * Servlet implementation class TestBeanAPIservlet 25 */ 26 @WebServlet("/TestBeanAPIservlet") 27 public class TestBeanAPIservlet extends HttpServlet { 28 private static final long serialVersionUID = 1L; 29 30 /** 31 * @see HttpServlet#HttpServlet() 32 */ 33 public TestBeanAPIservlet() { 34 super(); 35 // TODO Auto-generated constructor stub 36 } 37 38 /** 39 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 40 */ 41 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 42 // TODO Auto-generated method stub 43 response.getWriter().append("Served at: ").append(request.getContextPath()); 44 } 45 46 /** 47 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 48 */ 49 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 50 51 InputStream is = null; //InputStream用来获取客户端请求 52 PrintWriter printwriter = null; //response输出 53 int i = -1; 54 TestBean rtestbean = null; 55 String requeststr = null; 56 TestBeanList tbl=null; 57 ByteArrayOutputStream bos = null; 58 String xmlstr=null; 59 Document xmlfile=null; 60 String apiname=null; 61 AbstractApi api=null; 62 63 // 获取客户端传来请求参数 64 is = request.getInputStream(); // 获取输入流 65 bos = new ByteArrayOutputStream(); 66 while ((i = is.read()) != -1) { 67 bos.write(i); 68 } 69 70 requeststr = bos.toString(); 71 //分解xml头获取apiname 72 try { 73 xmlfile=Toxmlfile.strtoxmlfile(requeststr); 74 } catch (Exception e1) { 75 // TODO Auto-generated catch block 76 e1.printStackTrace(); 77 } 78 apiname=xmlfile.getDocumentElement().getNodeName(); 79 //获取api类 80 try { 81 api=AbstractApi.getAPI(apiname); 82 } catch (Exception e1) { 83 // TODO Auto-generated catch block 84 e1.printStackTrace(); 85 } 86 // 将xml解析,转为bean 87 rtestbean = new TestBean(); 88 try { 89 rtestbean = (TestBean) UnMarshal.xmltoobject(rtestbean, requeststr); 90 } catch (Exception e) { 91 // TODO Auto-generated catch block 92 e.printStackTrace(); 93 } 94 95 //执行接口类 96 try { 97 tbl=(TestBeanList)api.resolve(rtestbean); 98 } catch (Exception e1) { 99 // TODO Auto-generated catch block 100 e1.printStackTrace(); 101 } 102 103 //解析对象为xml 104 try { 105 xmlstr=Marshal.objecttoxml(tbl); 106 } catch (Exception e) { 107 // TODO Auto-generated catch block 108 e.printStackTrace(); 109 } 110 111 // PrintWriter返回给客户端 112 response.setCharacterEncoding("utf-8"); 113 printwriter = response.getWriter(); 114 printwriter.println(xmlstr.toString()); 115 printwriter.flush(); 116 printwriter.close(); 117 } 118 119 }
三、感悟
本来想写个简单的接口方式来练习。写完后觉得每一个接口那就要重新重复写,觉得挺麻烦。后来想了想,用这个方式来完善,每次只要建立对应的bean和API类与servlet类,比较清楚。不过写完后发现代码量也没减少多少,只是结构上比较清楚了些。所以希望有大V看到,提出些建议。
由于本人入门较晚,所以在写代码过程中,还是遇到了不少困难。但是也由于这次经历,对代码没了以前那种惧怕感和厌恶感,反而慢慢觉得,静静地写代码,然后在写每一个功能的过程中,去发现自己需要的知识,然后去了解,去学习,最后慢慢地去摸索去尝试使用。这个工程其实是很享受的。也正因为如此,了解了接口的调用机制,数据库操作,流的处理,xml文件的处理等等,可能其中的知识还是一知半解,但是至少感觉慢慢地开始入门了。
接下去想多写一些能够节约自己平日实施和运维工作的小程序,由于咱们经理不给于技术上的转岗(美其名曰好的实施工程师难找,希望我能帮助公司顶上,可是我也是个俗人需要赚钱养家,转岗是最为直接的办法)。
继续加油吧!!