S&J经典模式MVC
本次打算从整体上再认识servlet编程,企图做一个清算。最开始接触servlet时,学得还可以主要是好用,但是servlet和jsp的搭配使用,此次重温才算真正理解了。
- 程序结构
- form.html
首先给用于提供在浏览器的可视化操作,即Html代码,该代码由用户发起第一次请求时服务器返回给浏览器端:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>the form</title>
</head>
<body>
<h1 align="center">Beer Selection Page</h1>
<form method="POST" action="SelectBeer.do" >
Select beer characteritics></p>
Color:
<select name="color" size="1">
<option value="light">light</option>
<option value="amber">amber</option>
<option value="brown">brown</option>
<option value="dark">dark</option>
</select>
<br><br>
<center>
<input type="SUBMIT">
</center>
</form>
</body>
</html>
- web.xml
根据以上的脚本,请求为POST方式,action为SelectBeer.do,因此根据规范填写描述符,让部署器有依可据:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.4">
<servlet>
<servlet-name>Ch3 Beer</servlet-name>
<servlet-class>com.example.web.BeerSelect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Ch3 Beer</servlet-name>
<url-pattern>/SelectBeer.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>welcomeTest.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>
- BeerSelect.java
程序员要编写的servlet,该servlet充当控制器,处理并根据业务逻辑填充要抽象出来的数据模型
package com.example.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.example.model.BeerExpert;
public class BeerSelect extends HttpServlet{
//该servlet充当了控制器角色,容器就可以直接解析jsp渲染出响应数据,程序员当然还需要关注业务处理,但是对响应的关注,转变为模型要渲染的jsp
/**
* 其父类实现了序列化
*/
private static final long serialVersionUID = -5212877687087164982L;
private BeerExpert beer= new BeerExpert();//实体模型
public void doPost(HttpServletRequest req,HttpServletResponse res) throws IOException, ServletException{
String c = req.getParameter("color");
List result = beer.getBrands(c);
req.setAttribute("styles", result);
RequestDispatcher view = req.getRequestDispatcher("result.jsp");
view.forward(req, res);//根据请求参数,进行处理,填充模型,传递模型到jsp
-------------------------------------------------------------------------------------------------------------------------------------------------
// 不使用jsp则需要程序员填充响应对象的相关数据 |
// res.setContentType("nijianguo zheuang de ma"); |
// PrintWriter out = res.getWriter(); |
// out.println("Beer Selection Advice<br>");//响应体和响应行、头服务器内部进行了解耦,但最终会整合并输出 |
// out.println("<br>Got beer color"+beer.getBrands(c));//打印请求参数验证 |
------------------------------------------------------------------------------------------------------------------------------------------------|
}
}
- BeerExpert.java
承载数据,作为抽象数据模型使用,被填充进req对象,传递给JSP。
package com.example.model;
import java.util.ArrayList;
import java.util.List;
//该类承载了数据库有关的操作信息
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;//返回数组,该数组自描述:【x1,x2】
}
}
- result.jsp
数据模型伴随res/req被传递到jsp,之后服务器会自行填充响应对象,该JSP可以看作是响应输出的jsp化,只要程序员遵循规范。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>the result</title>
</head>
<body>
<h1 align="center">the zhuanfa‘s JSP</h1>
<p>
<%
List styles = (List)request.getAttribute("styles");
Iterator it = styles.iterator();
while(it.hasNext()){
out.print("<br>try:"+ it.next());
}
%>
</body>
</html>
结论:纯粹的servlet,需要程序员在响应体中填充符合用户需要的html代码以达到动态效果,劣势就是需要程序员编写html,且会因为一些符号而容易报错,html虽然复制可以达到复用,可脚本和java代码的转换未免让程序员思考方式切换频繁;纯粹的jsp会产生太多的重复java代码,而且在jsp中有大量的java代码也未免臃肿;采用逻辑、模型和视图相分离的模式就解决了jsp代码臃肿,响应数据繁杂的缺点。个人认为这就是servlet或者jsp(不确定那个在先了)后来产生的原因,别无其他。简单直接!
后面的内容,则是分条缕析的去试验,限定前提条件验证、设计过程程序、验证程序结果。