JavaWeb 多个Servlet整合优化
由于一个Servlet只能接收一个地址的http请求,如果系统复杂度提高,就会有很多Servlet类。例如,对销售系统来说,可能会有OederInsertServlet, OrderUpdateServlet, OrderDeleteSerlvet, OrderQueryServlet等多个OrderServlet来处理订单这一种业务。看着就会很杂。如下图。同时如果请求前或请求后有一些处理的话,对应的方法就需要写很多次,维护难度也会提升
优化-同一个模块多个操作
可以只用一个Servlet接收Order这一种业务所有的接口,通过在接口添加类似operate的标志参数对不同的操作进行区分。
代码示例
测试
本地访问 http://localhost:8080/mvc/ver1?operate=insert
服务器日志输出如下
优化-使用反射
目前,对业务的操作是通过switch-case进行匹配处理的,如果操作数量增多则需要多增加case语句,代码就会显得臃肿。可以考虑通过反射调用具体的执行方法
示例代码
下面展示的是核心代码- String operate = req.getParameter("operate");
- System.out.println("获取到的操作名为:" + operate);
- // 通过反射获取对应的方法
- // 假定方法名均为do+${operate}+operate,驼峰,如operate为insert时,要调用的方法就是doInsertOperate
- // Method[] methods = this.getClass().getMethods();
- char[] chars = operate.toCharArray();
- chars[0] -= 32;
- String methodName = "do" + String.valueOf(chars) + "Operate";
- // Optional<Method> targetMethod = Arrays.stream(methods).filter(m -> m.getName().equals(methodName)).findFirst();
- try {
- Method taragetMethod = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
- taragetMethod.setAccessible(true);
- taragetMethod.invoke(this, req, resp);
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- throw new RuntimeException(e);
- }
复制代码 优化-多个业务模块引入配置文件
当业务增多时,需要在每个业务里面单独写反射调用方法较为复杂,可以也通过反射来调用业务模块,再执行对应的方法,同时可以引入xml配置文件,来匹配对应的业务模块
代码示例
- @WebServlet("/mvc/ver3/*")
- public class Ver3Servlet extends HttpServlet {
- private Map<String, Object> beanControllerMap = new HashMap<>();
- // 初始化,读取xml文件配置controller
- @Override
- public void init() throws ServletException {
- // super.init();
- System.out.println("aaa");
- try (InputStream beanConfigs = this.getClass().getClassLoader().getResourceAsStream("MvcVer3Config.xml")) {
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
- Document beanDocument = documentBuilder.parse(beanConfigs);
- Element documentElement = beanDocument.getDocumentElement();
- NodeList nodeList = beanDocument.getDocumentElement().getElementsByTagName("bean");
- for (int i = 0; i < nodeList.getLength(); i++) {
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans>if (Node.ELEMENT_NODE == nodeList.item(i).getNodeType()){
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> Element item = (Element) nodeList.item(i);
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> String beanName = item.getAttribute("id");
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> String className = item.getAttribute("class");
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> Class<?> beanClass = Class.forName(className);
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> Object bean = beanClass.getDeclaredConstructors()[0].newInstance();
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> beanControllerMap.put(beanName, bean);
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans>}
- }
- // documentElement.get
- } catch (IOException | ParserConfigurationException | SAXException | ClassNotFoundException |
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans> InvocationTargetException | InstantiationException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- System.out.println("aaa");
- }
- // 读取路径值,获取对应的controller对象,反射调用对应方法
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String servletPath = req.getPathInfo();
- System.out.println(servletPath);
- String controllerName = servletPath.split("/")[1];
- String operateName = servletPath.split("/")[2];
- operateName = "do" + getFirstUpper(operateName) + "Operate";
- Object targetController = beanControllerMap.get(getFirstUpper(controllerName));
- Method targetMethod;
- try {
- targetMethod = targetController.getClass().getDeclaredMethod(operateName, HttpServletRequest.class, HttpServletResponse.class);
- } catch (NoSuchMethodException e) {
- ErrorResponse(req, resp, e.getMessage());
- e.printStackTrace();
- return;
- }
- try {
- targetMethod.invoke(targetController, req, resp);
- } catch (IllegalAccessException | InvocationTargetException e) {
- ErrorResponse(req, resp, e.getMessage());
- e.printStackTrace();
- return;
- }
- System.out.println("调用结束");
- }
- private void ErrorResponse(HttpServletRequest req, HttpServletResponse resp, String errorString) throws IOException {
- req.setCharacterEncoding("utf-8");
- resp.setCharacterEncoding("utf-8");
- resp.setContentType("text/html;charset=utf-8");
- PrintWriter out = resp.getWriter();
- out.println("<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n");
- out.println("<HTML lang="ch">");
- out.println(" <HEAD><TITLE>delete Servlet</TITLE></HEAD>");
- out.println(" <BODY>");
- out.print("所访问的模块不存在
- ");
- out.print(errorString);
- out.println(" </BODY>");
- out.println("</HTML>");
- out.flush();
- out.close();
- System.out.println("所访问的模块不存在");
- }
- private String getFirstUpper(String s){
- char[] chars = s.toCharArray();
- chars[0] -= 32;
- return String.valueOf(chars);
- }
- }
复制代码解决多个业务配置问题,通过读取配置文件初始化Servlet,在收到请求时,取到对应的Servlet进行处理
配置文件示例
- <?xml version="1.0" encoding="utf-8" ?>
- <beans>
- <bean id="A" />
- <bean id="B" />
- <bean id="C" />
- <bean id="D" />
- </beans>
复制代码 测试
启动项目,访问对应路径
http://localhost:8080/mvc/ver3/a/query
页面响应
调用成功
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |