一、问题描述

最近把做的一个项目,整体升级了下,加入了一些SEO优化,其中SEO比较重要的就是URL伪静态,在网上搜了下,可以用URLRewrite实现伪静态。。。参考了以下几篇文章。。。

【1】https://blog.csdn.net/panda_52panda/article/details/76354619

【2】https://www.cnblogs.com/huiy/p/7816060.html

【3】https://www.cnblogs.com/zt19994/p/9477569.html

在本地采用【1】实现了效果,但是。。。我用的是jeesite4开发的,他打成的是war包,很尴尬的是,上传到服务器。。完全无效。。花了几个小时,看了下URLRewrite的源码。其中最主要的就是。。在UrlRewriteFilter中的loadUrlRewriterLocal方法。。该方法在本地调试时能成功的加载到文件,但是打成war包之后,发布到服务器上。。通过java -jar xxx.war的方式启动项目。。根本就获取不到文件。。

    private void loadUrlRewriterLocal() {InputStream inputStream = context.getResourceAsStream(confPath);// attempt to retrieve from location other than local WEB-INFif ( inputStream == null ) {inputStream = ClassLoader.getSystemResourceAsStream(confPath);}URL confUrl = null;try {confUrl = context.getResource(confPath);} catch (MalformedURLException e) {log.debug(e);}String confUrlStr = null;if (confUrl != null) {confUrlStr = confUrl.toString();}if (inputStream == null) {log.error("unable to find urlrewrite conf file at " + confPath);// set the writer back to nullif (urlRewriter != null) {log.error("unloading existing conf");urlRewriter = null;}} else {Conf conf = new Conf(context, inputStream, confPath, confUrlStr, modRewriteStyleConf);checkConf(conf);}}

当看了其中的这个方法,就能理解【2】文章的做法。。我是spring boot开发的,所以本地用的是以下这种方式:

@Configuration
public class UrlRewriteFilterConfig{@Beanpublic FilterRegistrationBean urlRewrite(){UrlRewriteFilter rewriteFilter = new UrlRewriteFilter();FilterRegistrationBean registration = new FilterRegistrationBean(rewriteFilter);registration.setUrlPatterns(Arrays.asList("/*"));Map initParam = new HashMap();initParam.put("confPath","urlrewirte.xml");initParam.put("infoLevel","DEBUG");registration.setInitParameters(initParam);return  registration;}
}

原理:

在项目启动时,调用该方法初始化UrlRewriteFilter,UrlRewriteFilter是一个实现了Servlet的过滤器类。并传入一些参数,并将它注册到spring中,该方法执行完后,会调用UrlRewriteFilter中的init方法,在init方法中获取上面方面中传入的一些参数

    public void init(final FilterConfig filterConfig) throws ServletException {log.debug("filter init called");if (filterConfig == null) {log.error("unable to init filter as filter config is null");return;}log.debug("init: calling destroy just in case we are being re-inited uncleanly");destroyActual();context = filterConfig.getServletContext();if (context == null) {log.error("unable to init as servlet context is null");return;}// set the conf of the logger to make sure we get the messages in context logLog.setConfiguration(filterConfig);// get init paramerers from context web.xml fileString confReloadCheckIntervalStr = filterConfig.getInitParameter("confReloadCheckInterval");String confPathStr = filterConfig.getInitParameter("confPath");String statusPathConf = filterConfig.getInitParameter("statusPath");String statusEnabledConf = filterConfig.getInitParameter("statusEnabled");String statusEnabledOnHosts = filterConfig.getInitParameter("statusEnabledOnHosts");String allowConfSwapViaHttpStr = filterConfig.getInitParameter("allowConfSwapViaHttp");if (!StringUtils.isBlank(allowConfSwapViaHttpStr)) {allowConfSwapViaHttp = "true".equalsIgnoreCase(allowConfSwapViaHttpStr);}// confReloadCheckInterval (default to null)if (!StringUtils.isBlank(confReloadCheckIntervalStr)) {// convert to millisconfReloadCheckInterval = 1000 * NumberUtils.stringToInt(confReloadCheckIntervalStr);if (confReloadCheckInterval < 0) {confReloadCheckEnabled = false;log.info("conf reload check disabled");} else if (confReloadCheckInterval == 0) {confReloadCheckEnabled = true;log.info("conf reload check performed each request");} else {confReloadCheckEnabled = true;log.info("conf reload check set to " + confReloadCheckInterval / 1000 + "s");}} else {confReloadCheckEnabled = false;}String modRewriteConf = filterConfig.getInitParameter("modRewriteConf");if (!StringUtils.isBlank(modRewriteConf)) {modRewriteStyleConf = "true".equals(StringUtils.trim(modRewriteConf).toLowerCase());}if (!StringUtils.isBlank(confPathStr)) {confPath = StringUtils.trim(confPathStr);} else {confPath = modRewriteStyleConf ? DEFAULT_MOD_REWRITE_STYLE_CONF_PATH : DEFAULT_WEB_CONF_PATH;}log.debug("confPath set to " + confPath);// status enabled (default true)if (statusEnabledConf != null && !"".equals(statusEnabledConf)) {log.debug("statusEnabledConf set to " + statusEnabledConf);statusEnabled = "true".equals(statusEnabledConf.toLowerCase());}if (statusEnabled) {// status path (default /rewrite-status)if (statusPathConf != null && !"".equals(statusPathConf)) {statusPath = statusPathConf.trim();log.info("status display enabled, path set to " + statusPath);}} else {log.info("status display disabled");}if (StringUtils.isBlank(statusEnabledOnHosts)) {statusEnabledOnHosts = DEFAULT_STATUS_ENABLED_ON_HOSTS;} else {log.debug("statusEnabledOnHosts set to " + statusEnabledOnHosts);}statusServerNameMatcher = new ServerNameMatcher(statusEnabledOnHosts);// now load conf from snippet in web.xml if modRewriteStyleConf is setString modRewriteConfText = filterConfig.getInitParameter("modRewriteConfText");if (!StringUtils.isBlank(modRewriteConfText)) {ModRewriteConfLoader loader = new ModRewriteConfLoader();Conf conf = new Conf();loader.process(modRewriteConfText, conf);conf.initialise();checkConf(conf);confLoadedFromFile = false;}   else {loadUrlRewriter(filterConfig);}}

最终会调用loadUrlRewriter方法初始化文件。。

    protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {try {loadUrlRewriterLocal();} catch(Throwable e) {log.error(e);throw new ServletException(e);}}

最终会初始化Conf类

    private void loadUrlRewriterLocal() {InputStream inputStream = context.getResourceAsStream(confPath);// attempt to retrieve from location other than local WEB-INFif ( inputStream == null ) {inputStream = ClassLoader.getSystemResourceAsStream(confPath);}URL confUrl = null;try {confUrl = context.getResource(confPath);} catch (MalformedURLException e) {log.debug(e);}String confUrlStr = null;if (confUrl != null) {confUrlStr = confUrl.toString();}if (inputStream == null) {log.error("unable to find urlrewrite conf file at " + confPath);// set the writer back to nullif (urlRewriter != null) {log.error("unloading existing conf");urlRewriter = null;}} else {Conf conf = new Conf(context, inputStream, confPath, confUrlStr, modRewriteStyleConf);checkConf(conf);}}

Conf类就是【2】中用的一种方式初始化。。

@Configuration
public class UrlRewriteFilterConfig extends UrlRewriteFilter {private static final String URL_REWRITE = "classpath:/urlrewrite.xml";// Inject the Resource from the given location@Value(URL_REWRITE)private Resource resource;// Override the loadUrlRewriter method, and write your own implementationprotected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {try {// Create a UrlRewrite Conf object with the injected resourceConf conf = new Conf(filterConfig.getServletContext(), resource.getInputStream(), resource.getFilename(),"@@traceability@@");checkConf(conf);} catch (IOException ex) {throw new ServletException("Unable to load URL rewrite configuration file from " + URL_REWRITE, ex);}}
}

第【2】中方式,在我这边在使用的过程中,一直报错。。。resource一直获取不到,报空指针异常。。

二、解决方法

上面讲了一些,文件的初始过程,基本上能解决我遇到的问题,我这里最终的解决方法就是,将war包放到tomcat中运行,启动tomcat时会解压war,用于用的是web项目了。。所以改成了如下方式:

@Configuration
public class UrlWebRewriteFilterConfig extends UrlRewriteFilter {@Overrideprotected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {try {Resource res = new ClassPathResource("urlrewirte.xml");Conf conf = new Conf(filterConfig.getServletContext(), res.getInputStream(), res.getFilename(),null);checkConf(conf);System.out.println("ok");} catch (Exception ex) {throw new ServletException("Unable to load URL rewrite configuration file from " + URL_REWRITE, ex);}}
}

通过spring-core核心包中的ClassPathResource来加载xml,因为我这边测试了几种常用的方式都获取为null。。。很尴尬

new ClassPathResource("urlrewirte.xml");

通过使用ClassPathResource成功的获取到了xml,然后就解决了这个问题。

urlrewirte.xml放在项目的resources目录下:

war包解压之后,urlrewirte.xml文件放在如下目录:

注意我这边针对的是jeesite4打包出来的war包,别的没有测试。

JAVA UrlRewrite 使用教程与注意点,JAVA 实现伪静态,URLRewrite实现url地址伪静态化,springboot中url地址重写(urlwrite),jeesite4伪静态相关推荐

  1. Java NIO系列教程(十) Java NIO DatagramChannel

    转载自  Java NIO系列教程(十) Java NIO DatagramChannel 译文链接    作者:Jakob Jenkov    译者:郑玉婷     校对:丁一 Java NIO中的 ...

  2. B站百万播放量Java零基础教程视频(适合Java 0基础,Java初学入门),史上最细Java零基础教学视频

    是否还在为学习Java如何入门而烦恼? 是否还在为Java软件如何安装而烦恼? 是否还在找寻着适合零基础的Java视频教程? 动力节点教学总监老杜159集课堂实录Java零基础视频教程,从初学者角度出 ...

  3. 【Java基础系列教程】第二章 Java语言概述、配置环境变量

    一.计算机编程语言概述 1.1 语言 语言(英文:Language)是人类进行沟通交流的表达方式.例如:中国人与中国人用普通话沟通.而中国人要和英国人交流,就要学习英语.              语 ...

  4. java oauth2.0_教程:如何实现Java OAuth 2.0以使用GitHub和Google登录

    java oauth2.0 将Google和GitHub OAuth登录添加到Java应用程序的指南 我们添加到Takipi的最新功能之一是3rd party登录. 如果您像我一样懒惰,那么我想您也希 ...

  5. 【Java基础系列教程】第八章 Java面向对象详解(三)_抽象类、接口、内部类、深拷贝与浅拷贝

    一.JavaBean规范 1.1 什么是JavaBean JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中.特点是可序列化,提供无参构造器,提供getter方法和 ...

  6. Java NIO系列教程(一) Java NIO 概述

    一.阻塞IO与非阻塞IO 阻塞IO: 通常在进行同步I/O操作时,如果读取数据,代码会阻塞直至有 可供读取的数据.同样,写入调用将会阻塞直至数据能够写入.传统的Server/Client模式会基于TP ...

  7. Java EE入门教程系列第一章Java EE的概述(一)——初识Java EE

    题外话:这个系列是为了记录学习Java EE的轨迹,也算是读书笔记,是我先看完了一遍教程对相关概念有了一个大体印象以后准备再重头细看一遍时同步写的博客.感想就是其实以前课堂上老师教的课都是很有作用的, ...

  8. Java开发入门教程!韩顺平java数据结构课堂笔记

    摘要 Apache Kafka是一个分布式消息发布订阅系统.它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Ap ...

  9. java编译器安装教程_如何安装java语言编译器

    如何安装java语言编译器 导语:您有没有想过计算机程序是怎样工作的?您是否曾经想学习编写自己的计算机程序?那么我们应该如何安装编译器呢?下面让我们了解一下java语言编译器的安装方法吧! 为了在您的 ...

  10. Java NIO系列教程(十二) Java NIO与IO

    原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov   译者:郭蕾    校对:方腾飞 当学习了Java ...

最新文章

  1. Django博客系统(详情页面展示)
  2. LeetCode---------Longest Substring Without Repeating Characters解法
  3. python如何调用图片-用python简单处理图片(4):图像中的像素访问
  4. 4.弹性网络( Elastic Net)
  5. 关于流水线中剪裁的疑问
  6. android 调出键盘表情_Android 软键盘和emoji表情切换方案,和微信几乎一样的体验...
  7. 《精通Spring4.X企业应用开发实战》读后感第二章
  8. css flexbox模型_代码简介:CSS Flexbox有点像旅行
  9. htop进程管理工具
  10. oracle 等待原因查找,查询引起锁等待的SQL语句
  11. Hadoop的安装配置
  12. bzoj 3110: [Zjoi2013]K大数查询(树套树)
  13. viper4android hifi,体验HiFi级音质 蝰蛇音效进阶使用教程
  14. 谷粒学院day9关于章节小节修改后无法添加的bug记录
  15. IOS 世界标准时间UTC /GMT 转为当前系统时区对应的时间
  16. Canvas 绘制方法过一遍
  17. Spring、Struts2+Spring+Hibernate整合步骤
  18. DFS算法之无序列表转换为平衡二叉搜索树
  19. 软件自动化测试可行性分析,基于 AI 的软件自动化测试思考与实践—kylinTOP 测试与监控平台...
  20. Android ijk视频播放器使用TextureView问题

热门文章

  1. 最新版计算机知识超全题库,超全的计算机基础知识题库.doc
  2. mapguide 2011
  3. BS7799系列讲座:HTP模型图及构建(转载)
  4. 备战数学建模22-数学建模论文写作规范总结
  5. 视频教程 | 3D 跑酷小游戏实战开发(上)
  6. 计算图的可达矩阵MATLAB程序
  7. Android mc怎么和win10联机,大更新!我的世界手机版/win10版联机完美互通
  8. 2018年计算机数据结构试题答案,2018年数据结构期末考试题及答案.pdf
  9. 哪个Linux可以运行国服lol,Linux wine国服LOL英雄联盟,完美运行!!
  10. Acer EC-471G BIOS升级注意事项