创建一个小的 web 应用, mvc, 麻雀虽小, 五脏俱全

补1: servlet没有main()方法, 他们受控与另外一个Java应用, 这个Java应用称为 容器, tomcat就是这么一个容器, web服务器(如apache)得到一个指向servlet的请求时, 服务器不是把这个请求给servlet本身, 而是交给部署该servlet的容器, 要由容器向servlet提供http请求和响应,而且由容器调用servlet的方法(doGet()和doPost()), 容器运行多个servlet线程来处理对同一servlet的多个请求(对每个请求分配一个线程,而不是每个用户)

补2: 容器的作用

通信支持,利用容器提供的方法, web服务器能轻松的与servlet进行通信

生命周期管理,容器控制着servlet的生与死

多线程支持, 容器会自动的接收每个servlet的请求,创建一个新的java线程

jsp 支持,负责将jsp翻译成真正的java

补3:容器处理请求的process ( 这个为准, 这个是正确的流程 )

a. 用户点击一个链接, 指向一个servlet而不是一个静态网页.

b. web 服务器接到这个请求后转发给容器, 容器接着创建两个对象, HttpServletRequest 和 HttpServletReponse

c. 容器根据请求中的URL找到相应的servlet, 为这个请求创建线程, 并把请求对象HttpServletRequest和响应对象HttpServletResponse传递给这个servlet线程. 此处要利用 web.xml 部署文件

d. 线程接下来调用service()方法, 根据请求的不同, service()方法调用 doGet() 和 doPost()方法

e. doGet()或doPost()生成动态网页, 并把这个网页塞到响应对象里

f. service()方法结束, 随之线程结束, 容器把响应对象装换为一个http响应,返回给web服务器, 然后删除请求和响应对象, web服务器发给客户.

补4: 流程图

progress

1. 请求初始页面

2. 提交表单

创建 开发环境

开发环境的目录结构, 等到部署WEB应用的时候, 要把这个目录结构适当地复制到特定容器所希望的位置上.

这个目录结构适用于 小中型项目

创建部署环境( 部署时, 只需要编译后的文件, 所以只需要classes文件 )

构建应用的路线图

1. 分析web应用的用户视图( 例如表单 等等 )

2. 分析体系结构

3. 建立创建和部署应用的开发环境和部署环境

4. 创建应用

开发WEB process

1. 创建 form.html 并分别放置在开发环境( projec->web->form.html) 和部署环境(tomcat->webApps->Project->form.html)

form.html 是一个静态网页

   1:  <html>
   2:      <head>
   3:          <title>Beer Room</title>
   4:      </head>
   5:      <body>
   6:          <h1 align=""center>Beer Selection Page</h1>
   7:          
   8:          <form method="POST" action="SelectBeer.do">
   9:              Select beer characteristics<p>
  10:              Color:
  11:              <select name="color" size="1">
  12:                  <option>light
  13:                  <option>amber
  14:                  <option>brown
  15:                  <option>dark
  16:              </select>
  17:              <br />
  18:              <center>
  19:                  <input type="submit">
  20:              </center>
  21:          </form>
  22:      </body>
  23:      
  24:  </html>
2. 以上代码中, SelectBeer.do 只是一个逻辑名, 只是用来作为中间变量的作用, 所以需要确认XML配置文件, 将 SelectBeer.do 请求与指针的servlet 绑定, 所以编辑 web.xml文件, 并分别放置开发环境(Project->etc->web.xml) 和部署环境(tomcat->webApps->Project->WEB-INF->web.xml) 这个 web.xml 被叫做 部署描述文件(DD)
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://ww.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"> <servlet>
<servlet-name>Ch3 Beer</servlet-name>
<servlet-class>com.example.web.BeerSelect</select-class>
</servlet>
<servlet-mapping>
<servlet-name>Ch3 Beer</servlet-name>
<url-pattern>/SelectBeer.do</url-pattern>
</servlet-mapping>
</web-app>

其中, <url-pattern>/SelectBeer.do</url-pattern> 这里的 "/" 是一个规定.

这个web.xml 在容器启动时就会加载进内存, 当客户点击表单提交时, 容器会搜索web.xml文件, 根据用户提交的逻辑名找到真正对应的servlet名. 注意此处的 servlet-class 的路径就是 classes 里的路径, 而 url-pattern 是web 页面的路径, 因为我们的页面就放在 project 的目录下(即根目录下, /SelectBeer.do 表示在根目录下查找(虽然这个SelectBeer只是个逻辑名, 但是也要指定路径))

1) 根据表单, 请求的是 SelectBeer.do, 但是实际请求的是 /Project/SelectBeer.do 即 带上了webApps直接下边的目录就是根目录.

2) 容器搜索DD, 找到 <url-pattern> 与 /SelectBeer.do 匹配的一个<servlet-mapping>, 这里的/ 表示web应用上下文根.

3) 容器看到对应这个<url-pattern>的<servlet-name>是 “Ch3 Beer”, 但是这并不是实际servlet类文件的名字, "Ch3 Beer"是servlet名, 但不是servlet类的名字. 对容器来说, servlet名只是在DD中得一个标记作用. 用来做映射的.

4) 容器根据 "Ch3 Beer" 找到真正的servlet类.

5) 容器知道由哪个servlet 类来处理这个请求以后, 如果这个servlet还没有被初始化, 就会加载类, 并初始化该servlet.

6) 容器开启一个新的线程来处理这个请求, 并把请求传递给线程( 调用servlet的service()方法)

7) 容器把响应( 当然是通过web服务器) 发回给客户.

3. 容器找到匹配的servlet后, 开启一个新线程来处理这个请求, 并把请求传递给(servlet 的 service()方法 )

a 简单的 servlet

编译: javac –classpath D:\apache-tomcat-7.0.42\lib\servlet-api.jar –d classes src/com/example/web/BeerSelect.java

注意: 编译 BeerSelect 时由于用到了 BeerExpert类, 因为在 BeerSelect中有 import com.example.model;, 这也就引出了如何 import 自己的类的问题:

首先, 如果自己的需要引用的类和被引用的类在一个包中, 那么不需要 import 语句引用,

另外, 如果不在一个包中, 我们要在引用的类中添加 import 自己的类, 同时, 需要让 java 在编译时能够找到我们自己写的类, 有两种办法:

1. 将我们写的类的路径写入环境变量 classpath

2. 或者在编译时增加 classpath 参数, 将我们自己写的类的根目录包括其中, 例如:

javac –classpath D:\apache-tomcat-7.0.42\lib\servlet-api.jar;d:\web_homework\BeerProject\classes –d classes src/com/example/web/BeerSelect.java

注意, classpath 有两个参数, 分隔符使用分号; 并且中间不能有空格.

首先要进入 project 这个根目录下编译, 因为只有这样, 才能确认懂爱 classes 这个目录, ( 以及后边要编译的java文件 )

- sourcepath 源路径, 注意这个源路径类似根路径, 因为 java 会根据 package 来查找类, 所以当提供源路径时, 只需提供到package的根部

注:程序到这卡住了, 查看资料, 补充如下:

form 中的 action 是处理表单内容的程序的地址, url-pattern是servlet的url映射, 要在外部访问一个servlet, 需要一个访问地址, url-pattern 就是干这个的, 为一个servlet指定了访问名称(逻辑名, 不是servlet名),action就通过这个名字访问这个servlet

model 层用来完成复杂的商业逻辑

改进版本的 servlet

4. 容器把响应( 当然是通过web服务器) 发回给客户

这部是隐藏的, 由容器完成

利用JSP的 Process

注意上图:model : BeerExpert 这里边有商业逻辑

control : servlet 是用来控制的

view : jsp 用来显示的

那么, view 与 model 之间没有任何联系, 从图上也可以看出, 只有通过控制器 servlet 来建立联系

view: (jsp)

   1:  <%@ page import="java.util.*" %>
   2:   
   3:  <html>
   4:      <body>
   5:          <h1 align="center">Beer Recommendations Jsp</h1>
   6:          <p>
   7:              <%
   8:                  // servlet 传过来的从model获得的内容
   9:                  // 虽然没有用上 response, 但是还是很有用的
  10:                  List styles = (List)request.getAttribute("styles");
  11:                  Iterator it = styles.iterator();
  12:                  while (it.hasNext()) {
  13:                      out.print("<br>try: " + it.next());
  14:                  }
  15:                  
  16:              %>
  17:              
  18:          </p>
  19:   
  20:      </body>
  21:  </html>



control: (servlet)

/*
* BeerSelect2.java
* -----------------------------------------
* The second version about servlet.
*/ package com.example.web; import com.example.model.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*; public class BeerSelect extends HttpServlet { public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// 不需要定义 printwriter 等一系列流操作
String c = request.getParameter("color");
BeerExpert be = new BeerExpert();
List result = be.getBrands(c); // 为请求对象增加一个属性,供JSP使用,注意JSP要寻找styles
request.setAttribute("styles", result); // 为JSP请求一个分派器
RequestDispatcher view =
request.getRequesetDispatcher("result.jsp"); view.forward(request, response);
}
}

package com.example.web;

import com.example.model.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*; public class BeerSelect extends HttpServlet { public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
String c = request.getParameter("color"); // from client BeerExpert be = new BeerExpert(); // model instance
List result = be.getBrands(c); request.setAttribute("styles", result); // 为请求对象增加一个属性,styles这个属性值是result
// 供JSP使用, JSP要寻找"styles"
// 为jsp实例化一个分派器
RequestDispatcher view = request.getRequestDispatcher("result.jsp");
// 由这个jsp处理请求request, 并负责返回给客户 reponse
view.forward(request, response); }
}

model: (java)

/*
* BeerExpert.java
* ---------------------------------
* 处理商业逻辑,连接数据库等。
*/ package com.example.model;
import java.util.*; public class BeerExpert { public List getBrands(String color) {
List brands = new ArrayList();
if (color.equals("amber")) {
brands.add("Jack Amber");
brands.add("Red Moose");
} else {
brands.add("Jail Pale Ale");
brands.add("Gout Stout");
}
return(brands);
}
}

HeadFirst jsp 03 (MVC)的更多相关文章

  1. jsp+servlet+mvc模式图

    在我们的开发中,最常用的开发模式莫过于MVC模式,即M--MODEL.V--View.C--Controller,这样不仅可以方便开发人员分工协作,提高开发效率,增强程序的可维护性和拓展性,而且利用C ...

  2. JavaWeb -- Servlet+JSP+JavaBean(MVC)模式

    Servlet+JSP+JavaBean(MVC)模式适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据. Servlet+JSP ...

  3. JavaWeb核心篇(3)——JSP,MVC,三层架构

    JavaWeb核心篇(3)--JSP,MVC,三层架构 在本篇文章中我们会学习到JSP,MVC,三层架构 虽然JSP已经快被时代所淘汰,但是在一些老旧的工作场所还是有在使用,所以了解一下也不为过 至于 ...

  4. jsp学习---mvc模式介绍和el表达式,jstl标签库的使用入门

    一.mvc模式介绍 下图是常用的mvc分层模式: 项目中的包命名规则,一般如下: com.amos.domain 封装JavaBean,一般我喜欢用model命名这个包com.amos.dao 封装d ...

  5. HeadFirst jsp 02 (体系结构)

    当请求到来时, 必须有人实例化 servlet, 或者至少建立一个新的线程来处理这个请求. 必须有人调用 servlet 的 doPost()或 doGet()方法. 另外还的有人管理 servlet ...

  6. 13 JSP、MVC开发模式、EL表达式和JSPL标签+软件设计架构---学习笔记

    1.JSP (1)JSP概念:Java Server Pages 即java服务器端页面可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码用于简化书写!!! (2)原理 ...

  7. HeadFirst Jsp 14 (Structs)

    大的web程序可能很复杂, 分很多”层” 有关 RMI 的部分, 可以参考 headfirst java 中的 RMI 的部分. struts 是一个框架, 框架是一些接口和类的集合, 这些接口和类设 ...

  8. HeadFirst Jsp 07 (使用 jsp)

    Jsp 变成 Servlet, 容器会查看你的JSP, 把它转换成java源代码, 再编译成完整的Java servlet类. Jsp 不需要你的编译, 容器会自动替换成servlet. 在 jsp中 ...

  9. HeadFirst Jsp 05 (属性和监听)

    活用DD, 比如, 我想设置一个email地址, 但是不像在servlet中硬编码, 如果能再web.xml中设置一个参数, 直接拿到这个参数就更好一点. 容器建立一个servlet时, 它会读DD( ...

随机推荐

  1. c++取小数整数部分

    #include<math.h> double ceil(double x) //向上取整 double floor(double x) //向下取整 向上取整,取比x大的第一个整数值向下 ...

  2. [百度空间] [转] 在 Visual C++ 中控制全局对象的初始化顺序

    from: http://blog.csdn.net/classfactory/archive/2004/08/07/68202.aspx 在 C++ 中,同一个翻译单位(.cpp文件)里的全局对象的 ...

  3. 引擎设计跟踪(九.8) Gizmo helper实现与多国语言

    最近把gizmo helper的绘制做好了. 1.为了复用代码,写了utility来创建sphere, cube, cylinder, plane, ring(line), circle(solid) ...

  4. 研究AVCaptureDevice

    一.Apple Resource 1. wwdc 2014: Camera Caputre: Manual Controls 2. Exaple code: AVCam&AVCamManul ...

  5. org.eclipse.wst.common.project.facet.core.xml文件模板,解决eclipse编译报错。

    <?xml version="1.0" encoding="UTF-8"?> <faceted-project> <fixed f ...

  6. 还是说Memory Model,gcc的__sync_synchronize真是太坑爹了

    还是说Memory Model,gcc的__sync_synchronize真是太坑爹了! 时间 2012-01-29 03:18:35  IT牛人博客聚合网站 原文  http://www.udpw ...

  7. 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 3(Sorting/Searching)

    第一题:340 - Master-Mind Hints UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Item ...

  8. Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

    题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...

  9. OpenGL程序运行提示glut32.dll丢失问题

    转: http://blog.csdn.net/liufeng520/article/details/8064170 今天调试OpenGl的源程序,编译通过,但一运行就提示,计算机丢失 glut32. ...

  10. Hadoop基础教程-运行环境搭建

    一.Hadoop是什么 一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个分布式 ...