`
mingzizhi
  • 浏览: 2540 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

初学 Java Web 开发,请远离各种框架,从 Servlet 开发

    博客分类:
  • Java
阅读更多
Web框架是开发者在使用某种语言编写Web应用服务端时关于架构的最佳实践。很多Web框架是从实际的Web项目抽取出来的,仅和Web的请求和响应处理有关,形成一个基础,在开发别的应用项目的时候则可以从这个剥离出来的基础做起,让开发者更关注更具体的业务问题,而不是Web的请求和响应的控制。

框架很多,但套路基本类似,帮你隐藏很多关于 HTTP 协议细节内容,专注功能开发。

但对一个初学者来说,过早的接触框架往往是事倍功半!同样一个问题,换一种框架你可能需要从头开始研究。

下面是针对初学 Java 开发 Web 过程一些个人见解和思路,高手可略过。

1. 基本要求:Java 编程基础

有良好的 Java 语言编程基础,这是必须的,在讨论 Web 开发技术时提了一个 Java 编程基础的问题会被鄙视的。

2. 环境准备 (Eclipse + Tomcat)

选择一个你喜爱的Servlet容器,或者说大一点就是应用服务器,推荐 Tomcat 、Resin 或者 Jetty 这些轻量级的产品。这三个产品下载 zip 包解压后就可以用了。如果你不熟悉 Tomcat 的话请不要使用 exe 版本的 Tomcat,那会徒增很多烦恼。也不建议在 Eclipse 等一些开发环境中集成 Tomcat 的做法,也会徒增烦恼。

把应用服务器启动起来并能访问到其默认的页面为准。

关于开发工具

不推荐使用 MyEclipse 和 Eclipse 的 JEE 版本,徒增烦恼、运行缓慢而且还让你无法了解 Web 项目的结构。普通的 Eclipse 或者你喜欢的开发工具就足够了,能支持普通 Java 项目开发即可。

为了方便,我做了一个最基本的Java 项目 —— ServletDemo.zip ,你可将它导入到 Eclipse 里就是一个完整的、最简单的 Web 项目。

然后将下面 XML 内容替换 Tomcat 下的 conf/server.xml 文件:

01
<?xml version='1.0' encoding='utf-8'?>
02
<Server port="8005" shutdown="SHUTDOWN">
03
  <Service name="Catalina">
04
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
05
    <Engine name="Catalina" defaultHost="localhost">
06
      <Host name="localhost">
07
    <Context path="" docBase="D:\WORKDIR\ServletDemo\webapp" reloadable="true"/>
08
      </Host>
09
    </Engine>
10
  </Service>
11
</Server>
其中 D:\WORKDIR\ServletDemo 替换为你导入的项目路径,再次启动 Tomcat 后在浏览器打开 http://localhost:8080/hello 便可看到 Hello World 的输出信息。

3. 了解 Servlet 和 Filter

好了,我已经把环境搭起来了,接下来该干嘛呢?

前面的步骤为的是搭建一个测试的环境,然后让你了解一个最基本的 Java Web 项目的结构。

一个最基本的 Java Web 项目所需的 jar 包只需要一个 servlet-api.jar ,这个 jar 包中的类大部分都是接口,还有一些工具类,共有 2 个包,分别是 javax.servlet 和 javax.servlet.http。我把这个jar包放到了 webapp 目录外的一个独立 packages 文件夹里,这是因为所有的 Servlet 容器都带有这个包,你无需再放到Web项目里,我们放到这里只不过是编译的需要,运行是不需要的。如果你硬是把 servlet-api.jar 放到 webapp/WEB-INF/lib 目录下,那么 Tomcat 启动时还会报一个警告信息。

Java Web 项目还需要一个非常重要的配置文件 web.xml ,在这个项目中已经被我最小化了,只保留有用的信息:

01
<?xml version="1.0" encoding="UTF-8"?>
02
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
03
    "http://java.sun.com/dtd/web-app_2_3.dtd">
04
<web-app>
05

06
    <servlet>
07
        <servlet-name>hello_world</servlet-name>
08
        <servlet-class>demo.HelloServlet</servlet-class>
09
        <load-on-startup>1</load-on-startup>
10
    </servlet>
11

12
    <servlet-mapping>
13
        <servlet-name>hello_world</servlet-name>
14
        <url-pattern>/hello</url-pattern>
15
    </servlet-mapping>
16

17
</web-app>
每个 servlet 都必须在 web.xml 中定义并进行 URL 映射配置,早期 Java 开发 Web 在没有框架满天飞的时候,这个文件会定义了大量的 servlet,或者有人为了省事干脆来一个 /servlet/* 来通过类名直接调用 Servlet。

Servlet 规范里还有另外一个非常重要而且非常有用的接口那就是 Filter 过滤器。

下面是一个最简单的 Filter 类以及相应的定义方法:

01
package demo;
02

03
import java.io.IOException;
04

05
import javax.servlet.Filter;
06
import javax.servlet.FilterChain;
07
import javax.servlet.FilterConfig;
08
import javax.servlet.ServletException;
09
import javax.servlet.ServletRequest;
10
import javax.servlet.ServletResponse;
11
import javax.servlet.http.HttpServletRequest;
12

13
public class HelloFilter implements Filter {
14

15
    @Override
16
    public void init(FilterConfig arg0) throws ServletException {
17
        System.out.println("Filter 初始化");
18
    }
19

20
    @Override
21
    public void doFilter(ServletRequest req, ServletResponse res,
22
            FilterChain chain) throws IOException, ServletException {
23
        HttpServletRequest request = (HttpServletRequest)req;
24
        System.out.println("拦截 URI="+request.getRequestURI());
25
        chain.doFilter(req, res);
26
    }
27

28
    @Override
29
    public void destroy() {
30
        System.out.println("Filter 结束");
31
    }
32
}
在 web.xml 中的配置必须放在 Servlet 的前面:

01
<?xml version="1.0" encoding="UTF-8"?>
02
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
03
                         "http://java.sun.com/dtd/web-app_2_3.dtd">
04
<web-app>
05

06
    <filter>
07
        <filter-name>helloFilter</filter-name>
08
        <filter-class>demo.HelloFilter</filter-class>
09
    </filter>
10

11
    <filter-mapping>
12
        <filter-name>helloFilter</filter-name>
13
        <url-pattern>/*</url-pattern>
14
    </filter-mapping>
15
    
16
    <servlet>
17
        <servlet-name>hello_world</servlet-name>
18
        <servlet-class>demo.HelloServlet</servlet-class>
19
        <load-on-startup>1</load-on-startup>
20
    </servlet>
21

22
    <servlet-mapping>
23
        <servlet-name>hello_world</servlet-name>
24
        <url-pattern>/hello</url-pattern>
25
    </servlet-mapping>
26

27
</web-app>
访问 http://localhost:8080/hello 时看看 Tomcat 控制台有何输出信息。

4. Servlet 和 HTTP 的对应关系

Servlet 是 J2EE 最重要的一部分,有了 Servlet 你就是 J2EE 了,J2EE 的其他方面的内容择需采用。而 Servlet 规范你需要掌握的就是 servlet 和 filter 这两项技术。绝大多数框架不是基于 servlet 就是基于 filter,如果它要在 Servlet 容器上运行,就永远也脱离不开这个模型。

为什么 Servlet 规范会有两个包,javax.servlet 和 javax.servlet.http ,早先设计该规范的人认为 Servlet 是一种服务模型,不一定是依赖某种网络协议之上,因此就抽象出了一个 javax.servlet ,同时在提供一个基于 HTTP 协议上的接口扩展。但是从实际运行这么多年来看,似乎没有发现有在其他协议上实现的 Servlet 技术。

javax.servlet 和 javax.servlet.http 这两个包总共加起来也不过是三十四个接口和类。你需要通过 J2EE 的 JavaDoc 文档 熟知每个类和接口的具体意思。特别是下面几个接口必须熟知每个方法的意思和用途:

HttpServlet
ServetConfig
ServletContext
Filter
FilterConfig
FilterChain
RequestDispatcher
HttpServletRequest
HttpServletResponse
HttpSession
一些 Listenser 类
再次强调 HttpServletRequest 和 HttpServletResponse 这两个接口更应该是烂熟于心。

如果你从字面上无法理解某个方法的意思,你可以在前面那个项目的基础上做实验看看其输出,再不行你可以到讨论区提问,这样的提问非常明确,很多人都可以帮到你。

为什么我这么强调 HttpServletRequest 和 HttpServletResponse 这两个接口,因为 Web 开发是离不开 HTTP 协议的,而 Servlet 规范其实就是对 HTTP 协议做面向对象的封装,HTTP协议中的请求和响应就是对应了 HttpServletRequest 和 HttpServletResponse 这两个接口。

你可以通过 HttpServletRequest 来获取所有请求相关的信息,包括 URI、Cookie、Header、请求参数等等,别无它路。因此当你使用某个框架时,你想获取HTTP请求的相关信息,只要拿到 HttpServletRequest 实例即可。

而 HttpServletResponse接口是用来生产 HTTP 回应,包含 Cookie、Header 以及回应的内容等等。

5. 再谈谈 Session

HTTP 协议里是没有关于 Session 会话的定义,Session 是各种编程语言根据 HTTP 协议的无状态这种特点而产生的。其实现无非就是服务器端的一个哈希表,哈希表的Key就是传递给浏览器的名为 jsessionid 的 Cookie 值。

当需要将某个值保存到 session 时,容器会执行如下几步:

a. 获取 jsessionid 值,没有的话就生成一个,也就是 request.getSession() 这个方法
b. 拿到的 HttpSession 对象实例就相当于一个哈希表,你可以往哈希表里存放数据(setAttribute)
c. 你也可以通过 getAttribute 来获取某个值

而这个名为 jsessionid 的 Cookie 在浏览器关闭时会自动删除。把 Cookie 的 MaxAge 值设为 -1 就能达到浏览器关闭自动删除的效果。

6. 关于 JSP

首先我已经不用 JSP 很多年了,现在一直是使用 Velocity 模板引擎。

任何一个 JSP 页面在执行的时候都会编译成一个 Servlet 类文件,如果是 Tomcat 的话,这些生成的 java 文件会放置在 {TOMCAT}/work 目录下对应项目的子目录中,例如 Tomcat 生成的类文件如下:

01
package org.apache.jsp;
02

03
import javax.servlet.*;
04
import javax.servlet.http.*;
05
import javax.servlet.jsp.*;
06
import java.util.*;
07

08
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
09
    implements org.apache.jasper.runtime.JspSourceDependent {
10

11
  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
12

13
  private static java.util.List<String> _jspx_dependants;
14

15
  private javax.el.ExpressionFactory _el_expressionfactory;
16
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;
17

18
  public java.util.List<String> getDependants() {
19
    return _jspx_dependants;
20
  }
21

22
  public void _jspInit() {
23
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
24
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
25
  }
26

27
  public void _jspDestroy() {
28
  }
29

30
  public void _jspService(final HttpServletRequest request, final HttpServletResponse response)
31
        throws java.io.IOException, ServletException {
32

33
    final PageContext pageContext;
34
    HttpSession session = null;
35
    final ServletContext application;
36
    final ServletConfig config;
37
    JspWriter out = null;
38
    final Object page = this;
39
    JspWriter _jspx_out = null;
40
    PageContext _jspx_page_context = null;
41

42

43
    try {
44
      response.setContentType("text/html;charset=utf-8");
45
      pageContext = _jspxFactory.getPageContext(this, request, response,
46
                null, true, 8192, true);
47
      _jspx_page_context = pageContext;
48
      application = pageContext.getServletContext();
49
      config = pageContext.getServletConfig();
50
      session = pageContext.getSession();
51
      out = pageContext.getOut();
52
      _jspx_out = out;
53

54
      out.write("\r\n");
55
      out.write("<html>\r\n");
56
      out.write("    <title>Test</title>\r\n");
57
      out.write("    <style>\r\n");
58
      out.write("    </style> \r\n");
59
      out.write("  <body>\r\n");
60
      out.write("<h1>Test Demo (oschina)</h1>\r\n");
61
      out.write("<table cellspacing=\"1\" cellpadding=\"5\">\r\n");
62

63
Enumeration Names=request.getHeaderNames();
64
while(Names.hasMoreElements())
65
{String name=(String)Names.nextElement();
66
String value=request.getHeader(name);
67
 
68
      out.write("\r\n");
69
      out.write(" <tr>\r\n");
70
      out.write(" <td>");
71
      out.print(name);
72
      out.write("</td>\r\n");
73
      out.write("  <td>");
74
      out.print(value);
75
      out.write("</td>\r\n");
76
      out.write(" \r\n");
77
      out.write(" </tr>\r\n");
78
      out.write(" ");
79

80
}
81
  
82
      out.write("\r\n");
83
      out.write("</table>\r\n");
84
      out.write("  </body>\r\n");
85
      out.write("</html>");
86
    } catch (Throwable t) {
87
      if (!(t instanceof SkipPageException)){
88
        out = _jspx_out;
89
        if (out != null && out.getBufferSize() != 0)
90
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
91
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
92
      }
93
    } finally {
94
      _jspxFactory.releasePageContext(_jspx_page_context);
95
    }
96
  }
97
}
在 servlet 中有一个包 javax.servlet.jsp 是跟 JSP 相关的一些接口规范定义。JSP 比 Servlet 方便的地方在于可直接修改立即生效,不像 Servlet 修改后必须重启容器才能生效。

因此 JSP 适合用来做视图,而 Servlet 则适合做控制层。

7. 总结

罗哩罗嗦一大堆,归纳一下就是下面几点:

熟知 Servlet 规范之前,请不要学习任何框架
使用最简单的工具,不要任何向导和可视化
熟知 HTTP 协议
等你真的掌握了 Servlet 规范再去看框架,便会觉得一些都小菜。总之一点:不要被框架牵着鼻子走,框架是你的工具,它应该听你的!
分享到:
评论

相关推荐

    Java Web开发从初学到精通随书光盘源码

    《Java Web开发从初学到精通》开始主要介绍Servlet、JSP、JavaBean、EL、JSTL、JDBC等Web开发基础知识,然后学习Struts、Hibernate、Spring、Ajax、JSF等开源框架,并最终学习如何整合这些开源框架进行J2EE开发,...

    MLDN Java Web 开发实战经典源码李兴华源代码

    《MLDN Java Web 开发实战经典源码李兴华》是一部深入探讨Java Web开发的实践教程,由知名讲师李兴华编著。该资源包含了完整的源代码,供学习者研究和参考,无需解压密码即可使用,对于Java Web开发者来说是一份宝贵...

    Java Web开发实例大全

    Java Web开发实例大全(提高卷)筛选、汇集了Java Web开发从基础知识到高级应用各个层面的大量实例及源代码,共有600个左右,每个实例及源代码按实例说明、关键技术、设计过程、详尽注释、秘笈心法的顺序进行了分析...

    Java Web开发实践教程——从设计到实现(第2版)PPT

    《Java Web开发实践教程——从设计到实现(第2版)》是一本深入探讨Java Web技术的权威指南,尤其适合初学者和有一定基础的开发者。本教程通过PPT的形式,以直观、易懂的方式讲解了从项目规划到实际开发的全过程。在...

    Tomcat与java web 开发技术详解-孙卫琴-第二版

    1. **Java Web基础**:首先,书籍介绍了Java Web开发的基本概念,包括Servlet、JSP(JavaServer Pages)和MVC(Model-View-Controller)设计模式。读者会学习到如何创建动态网页,以及如何通过Servlet处理HTTP请求和...

    Java Web开发(PDF版)

    6. **Struts、Hibernate**:这两个是早期流行的Java Web开发框架,Struts主要用于MVC架构,而Hibernate是一个ORM框架,它们在现代开发中可能被Spring框架所替代,但了解其工作原理仍对理解Web开发有帮助。...

    java web开发实战1200例第i卷

    《Java Web开发实战1200例第I卷》是一本深入浅出的Java Web编程教程,涵盖了丰富的实例,旨在帮助读者从实践中掌握这门技术。这个压缩包包含的"1-12源码"是书中的前12个示例项目的完整源代码,为学习者提供了实际...

    JAVA WEB开发源码

    16. **第十六章:Spring Boot** - 学习Spring Boot快速开发框架,了解其自动配置和起步依赖特性。 17. **第十七章:Spring Security** - 安全管理框架,包括身份验证、授权和安全配置。 18. **第十八章:WebSocket...

    Java Web开发实践教程源码ch10

    这是一份丰富的学习资源,适用于初学者和有一定经验的开发者,旨在通过实例代码来深化理解Java Web开发的核心概念和技术。 1. **Servlet与JSP** 第10章可能涵盖了Servlet和JSP(JavaServer Pages)的基本概念。...

    Java Web整合开发王者归来

    《Java Web整合开发王者归来》是一本全面深入探讨Java Web开发技术的专著,涵盖了从基础知识到高级应用的广泛内容。书中的章节设置系统而全面,旨在帮助读者逐步掌握Java Web开发的核心技能。 1. 入门篇:这部分...

    Java Web 整合开发 完全自学手册 源代码

    这本书旨在帮助读者全面掌握Java Web应用程序的开发技能,从基础到高级,涵盖了一系列核心概念和技术。通过源代码的学习,读者可以更直观地理解并实践这些知识点。 1. **Servlet与JSP**:Java Web开发中的两大基石...

    Java+Web开发从初学到精通

    Java+Web开发从初学到精通

    Tomcat与Java Web开发技术详解(第2版).pdf

    本书主要围绕Apache Tomcat服务器展开,涵盖了从基础概念到高级特性的全方位讲解,旨在帮助读者掌握Java Web开发的核心技术。 在Java Web开发中,Tomcat是一个至关重要的组件。它是一个开源的、轻量级的应用服务器...

    零点起飞学Java Web开发资料

    Spring Framework是Java Web开发的首选,它提供了依赖注入(Dependency Injection)和面向切面编程(AOP)等特性,还有Spring MVC作为Web应用的开发框架。Struts2和JSF也是常见的选择,它们提供了一种基于MVC的结构...

    《Java Web开发从初学到精通源代码》代码

    《Java Web开发从初学到精通源代码》是一本旨在引导读者逐步掌握Java Web技术的教材。这本书涵盖了从基础到高级的各个层面,旨在帮助初学者和有经验的开发者提升技能,实现从入门到精通的转变。源代码是学习过程中...

    java Web系统开发

    首先,我们从基础开始,第二章 "Java开发环境及开发工具" 是学习Java Web开发的起点。这一章会介绍如何设置Java开发环境,包括安装Java Development Kit (JDK) 和集成开发环境(IDE),如Eclipse或IntelliJ IDEA。...

    非常实用的 java web (servlet, jsp) 例子 (非常适合java web初学者)

    非常实用的java web (servlet, jsp) 例子 (非常适合java web初学者)。 该例子麻雀虽小,五庄俱全,非常适合初学java web的初学者,通过该例子的学习可以很快地入门。 积分给得可能高了一下,但是,绝对物有所值,

    java web开发实战1200例 第二卷 源码

    介绍了应用Java Web进行程序开发的各个方面的知识和技巧,主要内容包括流行组件应用、数据库应用、图表统计、Ajax框架应用、流行框架、网站安全与架构模式、综合应用等。全书分为7篇23章,共计600个实例,并附带600...

    JAVA_Web开发教程.ppt

    通过本教程的学习,学员将能够搭建完整的Java Web开发环境,编写Servlet和JSP,理解MVC设计模式,并能运用相关工具和框架进行实际项目开发。这不仅是理论知识的积累,更是实践技能的提升,有助于学员在未来的职业...

Global site tag (gtag.js) - Google Analytics