菜鸟搭建web服务笔记-1

笔者最近看了Spring,MyBatis,Maven和Git等技术的相关资料,想自己试着从头搭建一个web服务,以巩固并加深学到的知识,于是便有了这一系列文章。这一系列文章将主要记录整个搭建过程,碰到的问题以及解决方案。注意本系列文章并不是各类技术的入门使用教程,需要读者对技术本身有一定的了解。

开发环境

  • Tomcat:9.0.16
  • Maven:3.6.0
  • Git:2.20
  • 操作系统:windows10

项目需求

因为暂时没想好要做什么服务,那么就以最简单的登录功能开始吧。

创建项目

  • 首先在github上创建了一个dizzydwarf项目
  • 然后在eclipse中创建了一个Maven项目,并将两者关联起来
    git remote add origin https://github.com/xuben/dizzydwarf.git

问题1:Maven中创建web项目

这里笔者在创建Maven项目的目录结构时没有选择web项目的模板,因此需要自己将其改造成一个web项目。

  • 首先需要告诉Maven这是一个web项目,最后需要打包成war包,因此修改pom.xml
<packaging>war</packaging>
  • 然后在src/main目录下新建如下目录结构
src
    main
        webapp
            WEB-INF
                web.xml

设计并实现

一开始的设计思路是这样的,用Tomcat作为web容器,写一个servlet,将所有的url请求都交给这个servlet处理,由servlet决定不同的url应该调用哪个类的哪个方法。

  • 写了个DispatchServlet,继承HttpServlet,重写doGetdoPost,根据getRequestURI判断请求的url,并把/login请求交给LoginAction处理
  • 在web.xml中配置servlet
  • 写了个index.html页面,里面只有一个表单,提交的action为/login
  • mvn package生成一个war包
  • 将这个war包放到Tomcat安装目录的webapps子目录下并启动Tomcat

问题2:Invalid <url-pattern>

Tomcat启动时提示Invalid <url-pattern>,笔者在web.xml中是这样配置servlet-mapping的

<servlet-mapping>
    <servlet-name>Dispatcher</servlet-name>
    <url-pattern>*</url-pattern>
</servlet-mapping>

到底什么样的url-pattern是合法的,具体规则可以参见servlet specification的Mapping Requests to Servlets部分。如果我们只是想要匹配所有url,可以把*改成/*

<servlet-mapping>
    <servlet-name>Dispatcher</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

问题3:Tomcat在命令行输出中文乱码

  • 找到注册表项HKEY_CURRENT_USER\Console\Tomcat,如果没有则新建。
  • 新建CodePage,类型为DWORD(32位)值,值为fde9,也就是65001

问题4:web项目的地址

笔者在浏览器中输入的访问地址是http://localhost:8080/index.html,结果跳到了Tomcat自带的web项目。原来要访问这个新添加的web项目需要输入相对于host的路径。
这里webapps是host的根目录,而新添加的war包被解压到了webapps/dizzydwarf-0.0.1-SNAPSHOT目录,因此访问的时候需要输入http://localhost:8080/dizzydwarf-0.0.1-SNAPSHOT/index.html,虽然有够麻烦的,不过暂时不是什么大问题,毕竟我们可以在必要的时候将其部署到host根目录。

问题5:url-pattern匹配

输入正确的地址,还是没有看到表单。原来是笔者将servlet的url-pattern配置为了/*,因此就算是请求静态的html页面,也会被匹配到然后交给servlet处理。查了下网上的资料,似乎并没有什么简单的方法可以在url-pattern中排除指定类型的文件,无奈之下把url-pattern改回了/login

问题5:表单action的绝对路径和相对路径问题

再次输入正确的地址,终于看到表单了。点击登录按钮,返回404错误,怎么回事?仔细一看浏览器的地址栏,发现地址栏变成了http://localhost:8080/login
原来表单的action属性的值为/login,而这个url地址也是相对于host根目录,而不是当前web应用根目录的地址,正确的值应该是login

问题6:getRequestURI获得的路径

把action改成login,重新打包部署后提交表单还是一片空白,在servlet中输出getRequestURI结果一看,发现url是/dizzydwarf-0.0.1-SNAPSHOT/login,而不是预期的/login。因为在servlet配置中已经有url映射了,所以这里删除这部分的代码,改成直接处理请求。
至此,用一个servlet处理所有url请求,然后在servlet内部分发的想法算是彻底破灭。但是事实上,关于url的映射通过web.xml方式配置也有其灵活性,只不过需要写多个servlet类处理。

JSP中的解决方案

对于前端请求使用绝对路径的问题,在jsp中可以用${pageContext.request.contextPath}表示web根目录的路径

struts2的解决方案

简单看了下struts2的StrutsPrepareAndExecuteFilter类,关于uri的处理调用了RequestUtils.getUri方法。大致的思路是用到了getServletPath方法,这个方法返回的是与url-pattern匹配的部分,不包括通过*匹配的部分。结合getServletPathgetRequestURIgetPathInfo方法最终得到相对于web服务根目录的uri路径。
另外struts2中的请求都以.do结尾,因此可以很好的排除对静态html文件的匹配。

结论

  • 前端url请求的绝对路径是相对于host根目录,后端url-pattern则是相对于web服务的根目录
  • url-pattern无法简单排除所有的静态html文件,同时servlet中也无法简单获得相对于web服务根目录的url请求路径,因此用单个servlet处理所有请求并在内部进行分发的想法实现起来并不简单。解决办法可以参考struts2。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容

  • 我们把富裕的客人叫做“猪仔”,一点点把他们胃口养大的过程叫“喂猪”。科长是我养过最肥的“猪仔”,二十天里,他刷完了...
    真实故事计划阅读 477评论 0 2
  • 今天的上午我上了第一节英语课,英语老师很厉害也很棒,老师让我们做了个自我介绍并带我们学习了加拿大和中国的不同,午餐...
    张瀚心阅读 310评论 1 1
  • 时间过去了什么都不能留下,有些茫然,怕过的太快惘费了大好时光,只留遗憾;怕过的太慢消遣了无聊虚度光阴,无所长进。 ...
    大婶冷不丁阅读 126评论 0 2