菜鸟搭建web服务笔记-1

2019-03-13  本文已影响0人  DizzyDwarf

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

开发环境

项目需求

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

创建项目

问题1:Maven中创建web项目

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

<packaging>war</packaging>
src
    main
        webapp
            WEB-INF
                web.xml

设计并实现

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

问题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在命令行输出中文乱码

问题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文件的匹配。

结论

上一篇 下一篇

猜你喜欢

热点阅读