TCP開發為例-來說明Web開發不同url請求為何走不同方法

拿java的web開發為例子,相信有很多小夥伴是做j2EE開發的,htpp請求,json資料傳輸都是工作中經常用的,查詢請求,新增請求,修改請求前端配個url,例如https://localhost/intsmaze/user/add?name=intsmaze。然後後端建立一個controler類(類上配置url對映/user),然後建立一個addUser方法(在方法上配置對映/add)。然後啟動web應用,前端傳送的請求就會自動走到後端的addUser方法了。

但是你知道為什麼這個請求走對應的方法嗎?下面讓我拿我大三期間基於TCP寫的服務端程式做例子來看看背後的原理吧。這個程式是一個超市管理系統,客戶端使用javaSwing編寫,服務端使用javaSE編寫,雙方通訊使用TCP協議,資料儲存在mysql中。完整的專案上傳在github上https://github。com/intsmaze/Swing-TCP-mysql。

服務端啟動類,繫結埠。

public class LoginServer { private int port=1000; private ServerSocket serversocket; private ExecutorService executorservice; private final int POOL_SIZE=1;//一個CPU執行緒池中工作執行緒的數目 public LoginServer() throws Exception { serversocket=new ServerSocket(); serversocket。bind(new InetSocketAddress(“127。0。0。1”,port)); executorservice=Executors。newFixedThreadPool(Runtime。getRuntime()。availableProcessors()*POOL_SIZE); //當前CPU數*1就是匯流排程池數目 } public void service() { while(true) { Socket socket=null; try { socket=serversocket。accept(); executorservice。execute(new Handler(socket)); }catch(IOException e) { e。printStackTrace(); } } } public static void main(String[] args) throws Exception { new LoginServer()。service(); }}

路徑對映方法

localhost/intsmaze/後面不同的路徑就是擷取對應的字串然後呼叫對應的方法

public class Handler implements Runnable{ public static final int SOLDERCONNECTION=0;//售貨員登入 public static final int MANAGERADDSOLDER=7;//管理員新增售貨員 private Socket socket; private BufferedReader bufIn=null; private BufferedWriter bufOut=null; private Connection connection=null; private PreparedStatement preparedstatement=null; private ResultSet resultset=null; public Handler(Socket socket) throws IOException { this。socket=socket; bufIn=new BufferedReader(new InputStreamReader(socket。getInputStream())); bufOut=new BufferedWriter(new OutputStreamWriter(socket。getOutputStream())); } public void run() { try { String line=bufIn。readLine(); //讀取第一個選著功能 int i=Integer。valueOf(line); switch(i) { case SOLDERCONNECTION: solderConnection();//售貨員登入0 break; case MANAGERADDSOLDER: managerAddSolder();//管理員新增售貨員7 break; } }catch(Exception e) { socketUtil。close(socket); } } public void solderConnection() throws Exception { String sr=null; //讀取賬號和密碼 String arr[] =bufIn。readLine()。split(“#”);; connection=JdbcUtil。getConnection(); preparedstatement=connection。prepareStatement(“SELECT * FROM solder WHERE solder_number=? and solder_password=?”); preparedstatement。setString(1,arr[0]); preparedstatement。setString(2,arr[1]); resultset=preparedstatement。executeQuery(); if(resultset。next()){ bufOut。write(“ok\n”);//回饋查詢信心 bufOut。flush(); sr=resultset。getInt(1)+“#”+resultset。getString(2)+“#”+resultset。getString(3)+“\n”; bufOut。write(sr); bufOut。flush(); } else { bufOut。write(“no”);//回饋查詢信心 bufOut。flush(); } JdbcUtil。release(resultset, preparedstatement, connection); } public void managerAddSolder() throws Exception { connection=JdbcUtil。getConnection(); String name=bufIn。readLine(); System。out。println(name); preparedstatement=connection。prepareStatement(“insert into solder(solder_name) values(?) ”); preparedstatement。setString(1,name); preparedstatement。executeUpdate();//執行更新 preparedstatement=connection。prepareStatement(“select *from solder where solder_number=(select MAX(solder_number)from solder) ”); resultset=preparedstatement。executeQuery();//執行更新 if(resultset。next()) { bufOut。write(“ok\n”);//回饋查詢信心 bufOut。flush(); String str=resultset。getString(1)+“#”+resultset。getString(2)+“#”+resultset。getString(3); bufOut。write(str+“\n”);//回饋查詢信心 bufOut。flush(); } else { bufOut。write(“no\n”);//回饋查詢信心 bufOut。flush(); } JdbcUtil。release(resultset, preparedstatement, connection); } }

以localhost/intsmaze/user/add?name=intsmaze的url來反向剖析tcp服務端如何接收,並呼叫對應方法。localhost是與伺服器建立連線,然後傳送intsmaze/user/add?name=intsmaze為一個數據到伺服器,伺服器接收到該字串後,根據/擷取,然後判斷該請求是發給intsmaze的應用。然後透過user知道這個請求是user模組(使用者管理模組),然後透過add知道是呼叫新增使用者方法。?後面就是對於的引數獲取存入資料庫即可。

對上面的方法改進如下即可實現

String line=bufIn。readLine();//讀取第一個選著功能 line的值為intsmaze/user/add?name=intsmaze String arr[]=line。split(“/”);String model=arr[1];String method=arr[2]。split(“?”)[0];String param=arr[2]。split(“?”)[1];if(model。endsWith(“user”)){ if(method。equals(“add”)) { user。add(param); }}else if(model。equals(“goods”)){ 。。。}else if。。。