Java EE之Servlet、JSP学习

来源:互联网 发布:淘宝9.9元特价专区在哪 编辑:程序博客网 时间:2024/06/07 16:14

    这个学期开了Java EE的课程,借此机会好好的自学了下Java EE。写几篇博客记录下自己遇到的问题、学习过程。希望能帮到有需要的人,也能供自己日后查阅。文章中有错误之处,还请大家指正,共同进步。参考了很多大牛的博客文章,很是感谢。

使用的一些工具如下:

    开发工具:Eclipse neon

    服务器:Tomcat 8.5

    数据库:MySQL 5.6.17

    数据库可视化工具:phpMyAdmin

因为以前学习PHP的缘故,所以习惯了使用phpMyAdmin,在Tomcat服务器上安装phpMyAdmin可以参考我的另一篇文章:http://blog.csdn.net/yc_wj/article/details/69218738


Servlet、JSP简介:

    虽然现在Java EE的开发有各种各样的框架可以选择,但个人认为还是应该要先了解Servlet的由来和原理,这样可以更好的帮助我们理解和使用框架,毕竟框架也是在Servlet的基础上再各种封装。

 Servlet由来:

    在最初B/S模式刚兴起时,用户只能通过浏览器向服务器请求静态资源,但随着因特网发展,用户需要获取动态处理后的资源是必然的。为了满足动态处理的需求,通用网关接口(CGI,Common Gateway Interface)就出现了。CGI是为特定OS编写的,不可移植,对每个请求产生新进程进行处理。

    B/S模式的浪潮,Java也想追赶,于是就有了Applet和Servlet,这两者都属于Java EE。

    Applet(客户端小程序):一种纯客户端(浏览器)实现方案,Applet作为浏览器的一个Java插件,浏览器通过解释执行Web服务器发过来的Java代码,从而实现动态。但这种方案很不好,浏览器必须安装插件而且还受限于浏览器,同时Web服务器发送过来的Java代码也不能太复杂。(感兴趣的朋友可以自行搜索了解)

    Servlet:既然浏览器不方便执行Java代码,那还是交由服务器来执行的好,这也就是Servlet的来由,Servlet就是Server端的Applet的意思。使用Servlet类将Http请求和响应封装在Java类中来实现各种Web应用,Servlet类会被编译成体系结构中立的字节码,由基于Java的Web服务器动态加载和执行。

                         请求 ——> Servlet 引擎 ——> Servlet 模块

                        Servlet 模块 ——> Servlet 引擎 ——> 响应

    Servlet与CGI:Servlet性能更好、具有平台无关性、可信、可使用整个Java类库,不需要为每个请求创建一个进程来处理。

Servlet发展:

    早期的Servlet虽然有很多优点,但存在大量冗余代码,并且输出HTML语句依然是老的CGI方式,要一句一句用out输出,这对于界面设计显然是非常不友好的,难以实现各种页面效果。

    所以,Sun就借鉴了ASP,提出了JSP(Servlet1.1)。此时Java程序员可以将服务端代码添加到已经设计好的静态页面上,再由一个JSP容器对JSP文件进行自动解析并转换成Servlet类来交给服务器运行。这也就是Java EE中的Model 1 开发模式(JSP既负责创建HTML页面,又要负责业务逻辑)。

    Model 1模式显然也是存在问题的,前端开发者需要看JSP中大量懵逼的后端代码,而后端开发者也要在大量的前段代码中找到能写Servlet代码的地方!随着项目增大,功能越来越复杂,这种交叉的工作流让前后端都很不爽,难以开发啊。

    于是,Servlet1.2出现了,该版本开始倡导MVC模式:

             JSP(V):视图,用标签封装后端代码,让界面看上去跟清爽,负责显示数据

            Servlet(C):控制器,控制请求分发

            Model(M):模型,其实就是封装了数据或业务逻辑功能的JavaBean类

    这样的MVC模式也就是Java EE中的Model 2 开发模式,此时的Servlet和早期的相比有了极大的简化,应该说通过分层,将早期Servlet的功能分离从而达到了简化效果。

    至此,Servlet的大方向就基本固定了,一直到今天,虽然有各种各样优秀的框架出现,但也都是建立在这个Model 2 的基础上的。

Servlet含义:

    广义:基于Java技术的Web组件,被容器托管,用于生成动态内容。再详细的说,Servet是JavaEE组件中的Web组件中的一种(还有就是Java Server Faces和JavaServer Page)。

    狭义:是JavaEE API 的一个interface,javax.servlet.Servlet。

Servlet容器/引擎:

    Servlet容器也可以叫引擎,Container/Enginee,用于执行Servlet。

    容器以内嵌或附加组件形式存在Web服务器或应用服务器中。

    容器本身(不依赖Web服务器)就提供了基于请求/响应发送模型的网络服务,解码基于MIME的请求,格式化基于MIME的响应。

        web.xml = 部署描述符

请求编码:

    1、请求以什么编码发送给服务器,由浏览器决定。

    2、服务端,Servlet规范规定请求没有指定编码时,容器必须使用iso-8859-1解码,通过getCharacterEncoding返回null知道没有设置编码

    3、ServletRequest提供 setCharacterEncoding 修改请求编码

Servlet Context(Servlet 上下文):

    一个Web应用对应一个Servlet接口的实例。所有用户公用一个,可看作一个全局存储空间。

    ServletContext提供直接访问Web应用中的静态内容:getResource,getResourceAsStream

    这两个方法的String参数必须以 “/” 开头,相对于ServletContext Path 的路径

    还有几个重要的对象:ServletConfig、ServletRequest、ServletResponse

请求路径元素:

    1、Context Path(项目根目录),例 /myApp

    2、Servlet Path(与web.xml中的<url-pattern>配置相关,“/”开头)

    3、PathInfo(要么为空,要么以“/”开头)

映射请求到Servlet的规则:

    http://hostname/myApp/Servlet?xxx,

    对于上述路径,需要映射的路径为 /Servlet

    匹配有四种次序:精确匹配<url-pattern>,再最长匹配,再扩展名匹配,再低保匹配。

        “/”开头,/*结尾,表示路径匹配

        *. 开头用于扩展名匹配

        只包含 “/” 表示应用default servlet,并不是匹配全部

    Tomacat的web.xml中也遵循上述规范:

    

    

    

    可以看到践行了上述Servlet的映射规范

    对于 .jsp文件:org.apache.jasper.servlet.JspServlet这个Servlet类最终会

  •  先将 .jsp 文件转换成 .java 文件
  •  然后将 .java 文件 complier成 .class 文件

    对于 default:org.apache.catalina.Servlets.DefaultServlet 这个Servlet最终会

  • 为所有没有被匹配到的URL做匹配,即“低保”匹配;
  • 如果找到了相应的资源了就返回,没有找到或者发生一些异常就返回400/404等状态码机器页面,长相如下

       

更多有关Servlet知识可以参考下面的博客:

Servlet历史与规范:

http://blog.csdn.net/u010297957/article/details/51498018

Java EE之Servlet技术:

http://blog.csdn.net/nicewuranran/article/details/51685821

Java Servlet完全教程:

http://www.importnew.com/14621.html

Servlet 工作原理解析:

https://www.ibm.com/developerworks/cn/java/j-lo-servlet/



JSP:

    JSP(Java Server Pages),和ASP、PHP类似,一种动态网页开发技术,通过使用JSP标签在HTML网页中插入Java代码。

    普通脚本标签:<%   %>

    声明标签:<%!   %>,用于声明全局变量和函数,并且声明的变量和函数可供本页面其它java代码调用。会被翻译成servle的成员变量或函数

    表达式标签:<%=   %>,用于直接在页面输出表达式的值,该标签中不能有分号。经服务器翻译后成 out.print();

JSP生命周期:

    1、第一次访问JAP,会验证是否第一次访问,然后将JSP文件转化成Servlet,再编译成class文件

    2、生成的class文件会自动生成几个方法:jspInit(),jspDestory(),jspService(),Tomcat仅在第一次请求时,调用jspInit()方法,然后调用jspService()进行处理。

    3、之后的每个请求,都会分配一个线程调用jspService()方法

    4、如果页面被销毁或关闭,都会调用jspDestory()方法。

    (如果项目直接部署在Tomcat服务器的WebApps,那就可以在Tomcat的workDir目录下生成的jsp文件对应的Servlet类,即.java 文件)

JSP指令元素和动作:

     <%@ 指令 属性>

     <jsp:动作   >  

    对于具体的指令元素、属性和动作,其它资料上已经有很多介绍了,这里就不再赘述。

易百 JSP教程:

http://www.yiibai.com/jsp/jsp_quick_guide.html



    jsp页面通过request对象得到的数据都是String类型,若想转换成int类型,需要使用Integer.parseInt(String xx)方法。不过转换语句必须放在try catch 块中,因为转换可能发生异常 NumberFormatException

JSP页面编码设置:

    1、pageEncoding="UTF-8"  的作用是设置JSP编译成Servlet时使用的编码。
    2、contentType="text/html;charset=UTF-8"  的作用是指定对服务器响应进行重新编码的编码。
    3、request.setCharacterEncoding("UTF-8")  的作用是设置对客户端请求进行重新编码的编码。
    4、response.setCharacterEncoding("UTF-8")  的作用是指定对服务器响应进行重新编码的编码。   
    对于发送数据,服务器按照 response.setCharacterEncoding—>contentType—>pageEncoding的优先顺序,对要发送的数据进行编码
    对于接收数据,要分三种情况。一种是浏览器直接用URL提交的数据,另外两种是用表单的GET和POST方式提交的数据。

    对于表单中POST方式提交的数据,只要在接收数据的JSP中正确 request.setCharacterEncoding 参数,即将对客户端请求进行重新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。
    那如何得到浏览器编码呢?上面我们提过了,在默认请情况下,浏览器编码就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。
    所以对于POST表单提交的数据,在获得数据的JSP页面中 request.setCharacterEncoding 要和生成提交该表单的JSP页面的 response.setCharacterEncoding设置成相同的值。

    对于URL提交的数据和表单中GET方式提交的数据,在接收数据的JSP中设置 request.setCharacterEncoding 参数是不行的,
    因为在Tomcat5.0中,默认情况下使用 ISO- 8859-1 对 URL 提交的数据和表单中 GET 方式提交的数据进行重新编码(解码),而不使用该参数对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码)。
    要解决该问题,应该在Tomcat的配置文件的 Connector 标签中设置 useBodyEncodingForURI 或者 URIEncoding 属性,
    其中useBodyEncodingForURI参数表示是否用 request.setCharacterEncoding 参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false(Tomcat4.0中该参数默认为true)
    URIEncoding 参数指定对所有 GET 方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编码。
    URIEncoding 和 useBodyEncodingForURI 区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新编码(解码),
    而 useBodyEncodingForURI 则是根据响应该请求的页面的 request.setCharacterEncoding 参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。
    所以对于URL提交的数据和表单中GET方式提交的数据,可以修改 URIEncoding 参数为浏览器编码或者修改u seBodyEncodingForURI 为true,并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码。



原创粉丝点击