how2j.cn

下载区
文件名 文件大小
请先登录 11m
增值内容 11m
11m

2分47秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器。 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)。 chrome 的 视频下载插件会影响播放,如 IDM 等,请关闭或者切换其他浏览器

步骤 1 : 拓扑图点亮   
步骤 2 : Filter 的加载和初始化   
步骤 3 : StandardFilterConfig   
步骤 4 : Context   
步骤 5 : Context 继续讲解   
步骤 6 : 重启 TestTomcat   
步骤 7 : 比较可运行项目,快速定位问题   

增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
拓扑图点亮
步骤 2 :

Filter 的加载和初始化

edit
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
步骤 3 :

StandardFilterConfig

edit
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package cn.how2j.diytomcat.catalina; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; public class StandardFilterConfig implements FilterConfig { private ServletContext servletContext; private Map<String, String> initParameters; private String filterName; public StandardFilterConfig(ServletContext servletContext, String filterName, Map<String, String> initParameters) { this.servletContext = servletContext; this.filterName = filterName; this.initParameters = initParameters; if (null == this.initParameters) this.initParameters = new HashMap<>(); } @Override public String getInitParameter(String name) { return initParameters.get(name); } @Override public Enumeration<String> getInitParameterNames() { return Collections.enumeration(initParameters.keySet()); } @Override public ServletContext getServletContext() { return servletContext; } @Override public String getFilterName() { return filterName; } }
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package cn.how2j.diytomcat.catalina; import cn.how2j.diytomcat.classloader.WebappClassLoader; import cn.how2j.diytomcat.exception.WebConfigDuplicatedException; import cn.how2j.diytomcat.http.ApplicationContext; import cn.how2j.diytomcat.http.StandardServletConfig; import cn.how2j.diytomcat.util.ContextXMLUtil; import cn.how2j.diytomcat.watcher.ContextFileChangeWatcher; import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TimeInterval; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.log.LogFactory; import org.apache.jasper.compiler.JspRuntimeContext; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import javax.servlet.*; import javax.servlet.http.HttpServlet; import java.io.File; import java.util.*; import org.apache.jasper.JspC; public class Context { private String path; private String docBase; private File contextWebXmlFile; private Map<String, String> url_servletClassName; private Map<String, String> url_ServletName; private Map<String, String> servletName_className; private Map<String, String> className_servletName; private Map<String, Map<String, String>> servlet_className_init_params; private Map<String, List<String>> url_filterClassName; private Map<String, List<String>> url_FilterNames; private Map<String, String> filterName_className; private Map<String, String> className_filterName; private Map<String, Map<String, String>> filter_className_init_params; private List<String> loadOnStartupServletClassNames; private WebappClassLoader webappClassLoader; private Host host; private boolean reloadable; private ContextFileChangeWatcher contextFileChangeWatcher; private ServletContext servletContext; private Map<Class<?>, HttpServlet> servletPool; private Map<String, Filter> filterPool; public Context(String path, String docBase, Host host, boolean reloadable) { TimeInterval timeInterval = DateUtil.timer(); this.host = host; this.reloadable = reloadable; this.path = path; this.docBase = docBase; this.contextWebXmlFile = new File(docBase, ContextXMLUtil.getWatchedResource()); this.url_servletClassName = new HashMap<>(); this.url_ServletName = new HashMap<>(); this.servletName_className = new HashMap<>(); this.className_servletName = new HashMap<>(); this.servlet_className_init_params = new HashMap<>(); this.url_filterClassName = new HashMap<>(); this.url_FilterNames = new HashMap<>(); this.filterName_className = new HashMap<>(); this.className_filterName = new HashMap<>(); this.filter_className_init_params = new HashMap<>(); this.loadOnStartupServletClassNames = new ArrayList<>(); this.servletContext = new ApplicationContext(this); ClassLoader commonClassLoader = Thread.currentThread().getContextClassLoader(); this.webappClassLoader = new WebappClassLoader(docBase, commonClassLoader); this.servletPool = new HashMap<>(); this.filterPool = new HashMap<>(); LogFactory.get().info("Deploying web application directory {}", this.docBase); deploy(); LogFactory.get().info("Deployment of web application directory {} has finished in {} ms", this.docBase,timeInterval.intervalMs()); } public void reload() { host.reload(this); } private void deploy() { init(); if(reloadable){ contextFileChangeWatcher = new ContextFileChangeWatcher(this); contextFileChangeWatcher.start(); } JspC c = new JspC(); new JspRuntimeContext(servletContext, c); } private void init() { if (!contextWebXmlFile.exists()) return; try { checkDuplicated(); } catch (WebConfigDuplicatedException e) { // TODO Auto-generated catch block e.printStackTrace(); return; } String xml = FileUtil.readUtf8String(contextWebXmlFile); Document d = Jsoup.parse(xml); parseServletMapping(d); parseFilterMapping(d); parseServletInitParams(d); parseFilterInitParams(d); initFilter(); parseLoadOnStartup(d); handleLoadOnStartup(); } private void parseServletMapping(Document d) { // url_ServletName Elements mappingurlElements = d.select("servlet-mapping url-pattern"); for (Element mappingurlElement : mappingurlElements) { String urlPattern = mappingurlElement.text(); String servletName = mappingurlElement.parent().select("servlet-name").first().text(); url_ServletName.put(urlPattern, servletName); } // servletName_className / className_servletName Elements servletNameElements = d.select("servlet servlet-name"); for (Element servletNameElement : servletNameElements) { String servletName = servletNameElement.text(); String servletClass = servletNameElement.parent().select("servlet-class").first().text(); servletName_className.put(servletName, servletClass); className_servletName.put(servletClass, servletName); } // url_servletClassName Set<String> urls = url_ServletName.keySet(); for (String url : urls) { String servletName = url_ServletName.get(url); String servletClassName = servletName_className.get(servletName); url_servletClassName.put(url, servletClassName); } } private void checkDuplicated(Document d, String mapping, String desc) throws WebConfigDuplicatedException { Elements elements = d.select(mapping); // 判断逻辑是放入一个集合,然后把集合排序之后看两临两个元素是否相同 List<String> contents = new ArrayList<>(); for (Element e : elements) { contents.add(e.text()); } Collections.sort(contents); for (int i = 0; i < contents.size() - 1; i++) { String contentPre = contents.get(i); String contentNext = contents.get(i + 1); if (contentPre.equals(contentNext)) { throw new WebConfigDuplicatedException(StrUtil.format(desc, contentPre)); } } } private void checkDuplicated() throws WebConfigDuplicatedException { String xml = FileUtil.readUtf8String(contextWebXmlFile); Document d = Jsoup.parse(xml); checkDuplicated(d, "servlet-mapping url-pattern", "servlet url 重复,请保持其唯一性:{} "); checkDuplicated(d, "servlet servlet-name", "servlet 名称重复,请保持其唯一性:{} "); checkDuplicated(d, "servlet servlet-class", "servlet 类名重复,请保持其唯一性:{} "); } public String getServletClassName(String uri) { return url_servletClassName.get(uri); } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getDocBase() { return docBase; } public void setDocBase(String docBase) { this.docBase = docBase; } public WebappClassLoader getWebappClassLoader() { return webappClassLoader; } public void stop() { webappClassLoader.stop(); contextFileChangeWatcher.stop(); destroyServlets(); } public boolean isReloadable() { return reloadable; } public void setReloadable(boolean reloadable) { this.reloadable = reloadable; } public ServletContext getServletContext() { return servletContext; } public synchronized HttpServlet getServlet(Class<?> clazz) throws InstantiationException, IllegalAccessException, ServletException { HttpServlet servlet = servletPool.get(clazz); if (null == servlet) { servlet = (HttpServlet) clazz.newInstance(); ServletContext servletContext = this.getServletContext(); String className = clazz.getName(); String servletName = className_servletName.get(className); Map<String, String> initParameters = servlet_className_init_params.get(className); ServletConfig servletConfig = new StandardServletConfig(servletContext, servletName, initParameters); servlet.init(servletConfig); servletPool.put(clazz, servlet); } return servlet; } private void parseServletInitParams(Document d) { Elements servletClassNameElements = d.select("servlet-class"); for (Element servletClassNameElement : servletClassNameElements) { String servletClassName = servletClassNameElement.text(); Elements initElements = servletClassNameElement.parent().select("init-param"); if (initElements.isEmpty()) continue; Map<String, String> initParams = new HashMap<>(); for (Element element : initElements) { String name = element.select("param-name").get(0).text(); String value = element.select("param-value").get(0).text(); initParams.put(name, value); } servlet_className_init_params.put(servletClassName, initParams); } // System.out.println("class_name_init_params:" + servlet_className_init_params); } private void destroyServlets() { Collection<HttpServlet> servlets = servletPool.values(); for (HttpServlet servlet : servlets) { servlet.destroy(); } } public void parseLoadOnStartup(Document d) { Elements es = d.select("load-on-startup"); for (Element e : es) { String loadOnStartupServletClassName = e.parent().select("servlet-class").text(); loadOnStartupServletClassNames.add(loadOnStartupServletClassName); } } public void handleLoadOnStartup() { for (String loadOnStartupServletClassName : loadOnStartupServletClassNames) { try { Class<?> clazz = webappClassLoader.loadClass(loadOnStartupServletClassName); getServlet(clazz); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ServletException e) { e.printStackTrace(); } } } public WebappClassLoader getWebClassLoader() { return webappClassLoader; } public void parseFilterMapping(Document d) { // filter_url_name Elements mappingurlElements = d.select("filter-mapping url-pattern"); for (Element mappingurlElement : mappingurlElements) { String urlPattern = mappingurlElement.text(); String filterName = mappingurlElement.parent().select("filter-name").first().text(); List<String> filterNames= url_FilterNames.get(urlPattern); if(null==filterNames) { filterNames = new ArrayList<>(); url_FilterNames.put(urlPattern, filterNames); } filterNames.add(filterName); } // class_name_filter_name Elements filterNameElements = d.select("filter filter-name"); for (Element filterNameElement : filterNameElements) { String filterName = filterNameElement.text(); String filterClass = filterNameElement.parent().select("filter-class").first().text(); filterName_className.put(filterName, filterClass); className_filterName.put(filterClass, filterName); } // url_filterClassName Set<String> urls = url_FilterNames.keySet(); for (String url : urls) { List<String> filterNames = url_FilterNames.get(url); if(null == filterNames) { filterNames = new ArrayList<>(); url_FilterNames.put(url, filterNames); } for (String filterName : filterNames) { String filterClassName = filterName_className.get(filterName); List<String> filterClassNames = url_filterClassName.get(url); if(null==filterClassNames) { filterClassNames = new ArrayList<>(); url_filterClassName.put(url, filterClassNames); } filterClassNames.add(filterClassName); } } } private void parseFilterInitParams(Document d) { Elements filterClassNameElements = d.select("filter-class"); for (Element filterClassNameElement : filterClassNameElements) { String filterClassName = filterClassNameElement.text(); Elements initElements = filterClassNameElement.parent().select("init-param"); if (initElements.isEmpty()) continue; Map<String, String> initParams = new HashMap<>(); for (Element element : initElements) { String name = element.select("param-name").get(0).text(); String value = element.select("param-value").get(0).text(); initParams.put(name, value); } filter_className_init_params.put(filterClassName, initParams); } } private void initFilter() { Set<String> classNames = className_filterName.keySet(); for (String className : classNames) { try { Class clazz = this.getWebClassLoader().loadClass(className); Map<String,String> initParameters = filter_className_init_params.get(className); String filterName = className_filterName.get(className); FilterConfig filterConfig = new StandardFilterConfig(servletContext, filterName, initParameters); Filter filter = filterPool.get(clazz); if(null==filter) { filter = (Filter) ReflectUtil.newInstance(clazz); filter.init(filterConfig); filterPool.put(className, filter); } } catch (Exception e) { throw new RuntimeException(e); } } } }
步骤 5 :

Context 继续讲解

edit
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
步骤 6 :

重启 TestTomcat

edit
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
重启 TestTomcat
步骤 7 :

比较可运行项目,快速定位问题

edit
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2021-07-18 总是报null pointer的错误,然后发现是类之间的继承关系导致的
chuancey

Servlet --> BaseRequest --> httpServletRequest-->ServletRequest ServletRequest 无getRequestURI方法 httpServletRequest 有getRequestURI方法




1 个答案

chuancey
答案时间:2021-07-18
没问题了,可以check一下,request类中是否有重新写getRequestURI方法 public String getRequestURI() { return this.uri; }



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到








提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 实践项目-DiyTomcat-Filter 的加载和初始化 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图