如何撤销网站上信息,asp sqlite网站空间,海安网站优化,成都网站建设今明互联目录 1. 背景2. 实现2.1 pom.xml2.2 FruitController.java2.3 DispatcherServlet.java2.4 applicationContext.xml 3. 测试 1. 背景
前面我们做了Servlet的一个案例。但是存在很多问题#xff0c;现在我们要做优化#xff0c;优化的步骤如下#xff1a;
每个Fruit请求都需… 目录 1. 背景2. 实现2.1 pom.xml2.2 FruitController.java2.3 DispatcherServlet.java2.4 applicationContext.xml 3. 测试 1. 背景
前面我们做了Servlet的一个案例。但是存在很多问题现在我们要做优化优化的步骤如下
每个Fruit请求都需要一个Servlet来处理这样就会产生大量的Servlet。我们可以只用一个FruitServlet来处理然后通过一个operate变量来区分请求FruitServlet的哪个方法除了有Fruit的请求可能还有很多其它类型的请求。可以用一个DispatcherServlet来处理所有的请求然后定义一个applicationContext.xml来让一个请求和其处理的类对应不在FruitController中做重定向FruitController只返回要重定向的路径统一由DispatcherServlet来做重定向不在FruitController的方法中获取参数。由DispatcherServlet统一获取参数然后传递给FruitController的方法
2. 实现
2.1 pom.xml
编译的时候保留方法的参数名而不是擦除。注意删除target不然不会生效 !-- 编译的时候保留方法的参数名而不是擦除。注意删除target不然不会生效 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.10.1/versionconfigurationsource11/sourcetarget11/targetcompilerArgument-parameters/compilerArgument/configuration/plugin2.2 FruitController.java
只负责具体的业务逻辑处理。重定向、参数获取全部由DispatcherServlet处理
package com.hh.javaWebTest.servlet;import com.hh.javaWebTest.bean.Fruit;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;// 只负责具体的业务逻辑处理。重定向、参数获取全部由DispatcherServlet处理
public class FruitController {protected String index(Integer paramId, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 不通过req.getParameter(paramName)获取参数值而是通过在dispatcher统一获取再传入进来// 测试是否能获取到参数System.out.println(paramId: paramId);System.out.println(req.getRequestURI()); // /javaWebTest/fruit.doSystem.out.println(req.getQueryString()); // paramId1ListFruit fruitList new ArrayListFruit();fruitList.add(new Fruit(苹果, 5));fruitList.add(new Fruit(香蕉, 3));HttpSession session req.getSession();session.setAttribute(fruitList, fruitList);// 由DispatcherServlet调用super.processTemplate(index, request, response);return index;}}2.3 DispatcherServlet.java
接受所有的请求然后进行分发
package com.hh.javaWebTest.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;// 接受所有的请求然后进行分发
WebServlet(*.do)
public class DispatcherServlet extends ViewBaseServlet {private MapString, Object beanMap new HashMap();Overridepublic void init() throws ServletException {// 手动进行ViewBaseServlet的初始化super.init();// 解析applicationContext.xml形成id:class形式的beanMaptry {InputStream inputStream getClass().getClassLoader().getResourceAsStream(applicationContext.xml);DocumentBuilderFactory documentBuilderFactory DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder documentBuilderFactory.newDocumentBuilder();Document document documentBuilder.parse(inputStream);NodeList beanNodeList document.getElementsByTagName(bean);for (int i 0; i beanNodeList.getLength(); i) {Node beanNode beanNodeList.item(i);if (beanNode.getNodeType() Node.ELEMENT_NODE) {Element beanElement (Element) beanNode;String beanId beanElement.getAttribute(id);String className beanElement.getAttribute(class);Class controllerBeanClass Class.forName(className);Object beanObj controllerBeanClass.getDeclaredConstructor().newInstance();beanMap.put(beanId, beanObj);}}} catch (Exception e) {e.printStackTrace();}}Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// servletPath: /fruit.do fruitString servletPath request.getServletPath();servletPath servletPath.substring(1);int lastDotIndex servletPath.lastIndexOf(.do);servletPath servletPath.substring(0, lastDotIndex);// 获取fruit对应的classObject controllerBeanObj beanMap.get(servletPath);// 获取operateString operate request.getParameter(operate);if (StringUtils.isEmpty(operate)) {operate index;}try {Method[] methods controllerBeanObj.getClass().getDeclaredMethods();for (Method method : methods) {// 匹配operate对应的类方法if (operate.equals(method.getName())) {Parameter[] parameters method.getParameters();// 将类方法的值保存到parameterValuesObject[] parameterValues new Object[parameters.length];for (int i 0; i parameters.length; i) {Parameter parameter parameters[i];String parameterName parameter.getName();if (req.equals(parameterName)) {parameterValues[i] request;} else if (resp.equals(parameterName)) {parameterValues[i] response;} else if (session.equals(parameterName)) {parameterValues[i] request.getSession();} else {// 从请求中获取参数值String parameterValue request.getParameter(parameterName);String typeName parameter.getType().getName();Object parameterObj parameterValue;if (parameterObj ! null) {if (java.lang.Integer.equals(typeName)) {parameterObj Integer.parseInt(parameterValue);}}parameterValues[i] parameterObj;}}// 调用方法返回值。根据返回值判断是否需要做重定向method.setAccessible(true);Object returnObj method.invoke(controllerBeanObj, parameterValues);// 视图处理(重定向处理)String methodReturnStr (String) returnObj;if (methodReturnStr.startsWith(redirect:)) { // 比如: redirect:fruit.doString redirectStr methodReturnStr.substring(redirect:.length());response.sendRedirect(redirectStr);} else if (methodReturnStr ! ) { // 比如: indexsuper.processTemplate(methodReturnStr, request, response);return;} else {return;}}}} catch (Exception e) {e.printStackTrace();}throw new RuntimeException(operate值非法!);}
}
2.4 applicationContext.xml
定义java bean的id和其对应的处理类
?xml version1.0 encodingutf-8?!--
XML包含三个部分
1. XML声明 而且声明这一行代码必须在XML文件的第一行
2. DTD: 文档类型定义
3. XML正文--!-- 该标签告知XML文档所使用的XML beans规范 --
!DOCTYPE beans [!ELEMENT beans (bean*)!ELEMENT bean (property*)!ELEMENT property (#PCDATA)!ATTLIST bean id ID #REQUIRED!ATTLIST bean class CDATA #IMPLIED!ATTLIST property name CDATA #IMPLIED!ATTLIST property ref IDREF #IMPLIED]beans!-- 说明这是一个java bean。id是fruit其对应的处理类是FruitController --bean idfruit classcom.hh.javaWebTest.servlet.FruitController/
/beans
3. 测试
请求http://localhost:8080/javaWebTest/fruit.do?paramId1web页面显示和之前的一样 控制台输出如下
paramId: 1