tomcat是一个服务器程序
可以对webapp目录下的Servlet代码进行执行和操作
编写的Servlet代码的步骤一般是在本地的ide中编写和测试,然后打包工程为war格式的文件,部署在服务器tomcat路径的webapp目录下面,
重启服务器上的tomcat服务之后,会自动解析war包,监听响应端口的http请求,并执行响应的Servlet代码。
Servlet代码的编写方式:
编写一个继承HTTPServlet 的子类
override 其中的doGet和doPost方法
在相应的web配置文件中配置该Servlet的url接口
我们工程中用于数据同步的Servlet类如下:
package Servlet; import Db.*; import Json.*; import Json.dbJson.*; import Jwt.JavaWebToken; import Output.Output; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; @WebServlet(name = "Servlet.Sync") public class Sync extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String modelnum = request.getParameter("modelnum"); String token = request.getParameter("token"); String content = request.getParameter("content"); JavaWebToken.verifyToken(token, username, modelnum); DatabaseAdapter adapter = new DatabaseAdapter(); Json.Sync syncback = new Json.Sync(); Gson gson = new Gson(); //java.lang.reflect.Type classType = new TypeToken<Json.Sync>() {}.getType(); //Json.Sync sync = gson.fromJson(content, classType); Json.Sync sync = gson.fromJson(content, Json.Sync.class); try{ for(Field field : sync.getClass().getDeclaredFields()){ field.setAccessible(true); Object obj = field.get(sync); Type t = field.getGenericType(); if(t instanceof ParameterizedType){ ParameterizedType pt = (ParameterizedType) t; Class clz = (Class) pt.getActualTypeArguments()[0];//List里面的示例的类型 Class clazz = obj.getClass();//List这个类型 Field anchorField = clz.getField("anchor"); Field statusField = clz.getField("status"); Field idField = clz.getField("id"); Method sizeMethod = clazz.getDeclaredMethod("size"); Method getMethod = clazz.getDeclaredMethod("get", int.class); getMethod.setAccessible(true); Method addMethod = clazz.getDeclaredMethod("add", Object.class); addMethod.setAccessible(true); int size = (Integer) sizeMethod.invoke(obj); for(int i = 0; i < size; i++){ Object pattern = getMethod.invoke(obj, i); if(0 == statusField.getInt(pattern)){ //新增的 anchorField.set(pattern, (new Date()).getTime()); Insert.insert(adapter, pattern, username, false); statusField.set(pattern, 9); addMethod.invoke(field.get(syncback), pattern); } else { //不是新增的 Object patternInServer = Search.search(adapter, clz, username, idField.getInt(pattern), false); if(patternInServer == null){ //没找到,在垃圾箱中找找 patternInServer = Search.search(adapter, clz, username, idField.getInt(pattern), true); } if(patternInServer == null){ //在服务器数据库和垃圾箱中都没找到,一定是客户端的代码写错了 anchorField.set(pattern, (new Date()).getTime()); statusField.set(pattern, -1); addMethod.invoke(field.get(syncback), pattern); continue; } if(anchorField.get(pattern).equals(anchorField.get(patternInServer))) { //两个数据之前已经同步好了, 直接利用status进行更新不会发生冲突 if(statusField.getInt(pattern) == -1){ anchorField.set(pattern, (new Date()).getTime()); anchorField.set(patternInServer, anchorField.get(pattern)); Delete.delete(adapter, clz, username, idField.getInt(pattern), false); Insert.insert(adapter, patternInServer, username, true); statusField.set(pattern, -1); addMethod.invoke(field.get(syncback), pattern); } else if(statusField.getInt(pattern) == 1) { anchorField.set(pattern, (new Date()).getTime()); anchorField.set(patternInServer, anchorField.get(pattern)); Update.update(adapter, pattern, username, false); statusField.set(pattern, 9); addMethod.invoke(field.get(syncback), pattern); } else{ //不可能有这种情况,一定是客户端代码写错了 anchorField.set(pattern, (new Date()).getTime()); statusField.set(pattern, -1); addMethod.invoke(field.get(syncback), pattern); } } else { //表示之前本地就没有更新到最新的版本,下面的操作可能存在冲突,目前考虑冲突全部以服务器端优先 if(statusField.getInt(patternInServer) == -1){ //是在垃圾桶中找到这个记录的,证明之前在其他的客户端中对这一项进行了删除,这里对服务器进行更新,同时删除本地 anchorField.set(pattern, (new Date()).getTime()); anchorField.set(patternInServer, anchorField.get(pattern)); Update.update(adapter, pattern, username, true); statusField.set(pattern, -1); addMethod.invoke(field.get(syncback), pattern);//status -1 发回本地,然本地删除 } else { //仍然在服务器端的数据库中,可能出现的冲突时文本的修改,这里以服务器为主 anchorField.set(pattern, (new Date()).getTime()); anchorField.set(patternInServer, anchorField.get(pattern)); statusField.set(patternInServer, 9); addMethod.invoke(field.get(syncback), patternInServer); } } } } } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } Output.output(gson.toJson(syncback), response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String modelnum = request.getParameter("modelnum"); String token = request.getParameter("token"); Long maxanchor = Long.parseLong(request.getParameter("maxanchor")); JavaWebToken.verifyToken(token, username, modelnum); Json.Sync syncback = new Json.Sync(); DatabaseAdapter adapter = new DatabaseAdapter(); syncback.DiaryList = Search.searchForGet(adapter, Diary.class, maxanchor); syncback.DiarybookList = Search.searchForGet(adapter, Diarybook.class, maxanchor); syncback.DiaryLabelList = Search.searchForGet(adapter, DiaryLabel.class, maxanchor); syncback.LabelList = Search.searchForGet(adapter, Label.class, maxanchor); syncback.SentenceList = Search.searchForGet(adapter, Sentence.class, maxanchor); syncback.SentencebookList = Search.searchForGet(adapter, Sentencebook.class, maxanchor); syncback.SentenceLabelList = Search.searchForGet(adapter, SentenceLabel.class, maxanchor); Gson gson = new Gson(); Output.output(gson.toJson(syncback), response); adapter.Destroy(); } }
它的web配置为:
<servlet> <servlet-name>Sync</servlet-name> <servlet-class>Servlet.Sync</servlet-class> </servlet> <servlet-mapping> <servlet-name>Sync</servlet-name> <url-pattern>/Servlet.Sync</url-pattern> </servlet-mapping>
这表明这个功能的url接口为http://。。。。。/Servlet.Sync