Struts 的MVC
1.Model 1 和Model 2简介
我们在开发Web应用时经常提到的一个概念是Model 1/Model 2,那么到底它是什么意思呢?其实它是对采用JSP技术构成Web应用的不同模型的描述。下面对这个概念做一个简单的介绍。
Model 1
在使用JAVA技术建立Web应用的实例中,由于JSP技术的发展,很快这种便于掌握和可实现快速开发的技术就成了创建Web应用的主要技术。JSP页面中可以非常容易地结合业务逻辑(jsp:useBean)、服务端处理过程(jsp:scriplet)和HTML(<html>),在JSP页面中同时实现显示,业务逻辑和流程控制,从而可以快速地完成应用开发。现在很多的Web应用就是由一组JSP页面构成的。这种以JSP为中心的开发模型我们可以称之为Model 1。
当然这种开发模式在进行快速和小规模的应用开发时,是有非常大的优势,但是从工程化的角度考虑,它也有一些不足之处:
1. 应用的实现一般是基于过程的,一组JSP页面实现一个业务流程,如果要进行改动,必须在多个地方进行修改。这样非常不利于应用扩展和更新。
2. 由于应用不是建立在模块上的, 业务逻辑和表示逻辑混合在JSP页面中没有进行抽象和分离。所以非常不利于应用系统业务的重用和改动。
考虑到这些问题在开发大型的Web应用时必须采用不同的设计模式――这就是Model2
Model 2
Model 2 表示的是基于MVC模式的框架。MVC是Model-View-Controller的简写。"Model" 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), "View" 是应用的表示面(由JSP页面产生),"Controller" 是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。从而弥补了Model 1的不足。
Model 2具有组件化的优点从而更易于实现对大规模系统的开发和管理,但是开发MVC系统比简单的JSP开发要复杂许多,它需要更多的时间学习和掌握。
1. 必须基于MVC组件的方式重新思考和设计应用结构。原来通过建立一个简单的JSP页面就能实现的应用现在变成了多个步骤的设计和实现过程。
2. 所有的页面和组件必须在MVC框架中实现,所以必须进行附加地开发工作。
在开始讲struts 前,我们先了解一下servlet 为什么要看servlet 看到最后就知道了
1、 环境的搭建就pass了
2、 open eclipse and follow me
create new project
新建一个Dynamic Web Project named servlet_Test_project
我用的是jdk1.6
接着next ….next完成
转到PackageExplor 我们看一下project 的目录结构
两个jar的环境
源文件目录
输出目录,也就是class的目录了(不多说了,不知道class是什么,学j2se吧)
Web目录
其中jsp等文件放在WebContent目录内(下面两个Web-INF、META-INF除外)
Lib目录为我们工程中用到的jar包的目录
下面为Projct explor下看到的目录结构,我们可以看看他的不同
好,少来费话,新建一个servlet 先
下面看图
包名为sakrua ,lass名为ServletHelloWorld,Superclass 为javax.servlet.http.HttpServlet
只有javax.servlet.http.HttpServlet这个父类吧,到下面再说
接着 你可以点完成,我们next看看有什么
呵呵 ,好像没有什么,我们点完成(是finish 不要告诉我找不到完成,
)
好,eclipse 为我们已经完成了大部分的代码了,不过我们先不看代码先(习惯先在后了)
我们再看看 Projct explor 有什么不同,不要让我说了,自己能看到的
其实这是web.xml文件中的内容,我们去 see see
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>servlet_Test_project</display-name>
<!--servlet 的-->
<servlet>
<description>sakrua 的第一个servlet</description>
<display-name>ServletHelloWorld</display-name>
<!-- servlet的名字 -->
<servlet-name>ServletHelloWorld</servlet-name>
<!-- servlet 类 -->
<servlet-class>sakrua.ServletHelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<!-- 跟上面对应的 -->
<servlet-name>ServletHelloWorld</servlet-name>
<!-- ie中输入的访问路径 -->
<url-pattern>/ServletHelloWorld</url-pattern>
</servlet-mapping>
<!-- servlet 的 -->
<!-- 其它的先不理 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
应该中国人都看得明
下面我们去看看Servlet 的代码
package sakrua;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletHelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;
public ServletHelloWorld() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
好我们加点东西上去看看
package sakrua;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletHelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;
public ServletHelloWorld() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html><head><title>servlet Example by sakrua </title></head><body>");
out.println("<h3><font color=red>servlet is here</font></h3>");
out.println("</body></html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
public void destroy() {
System.out.println("It is destroy");
super.destroy();
}
public void init() throws ServletException {
System.out.println("It is started");
super.init();
}
}
右键选择
在ie看到
Ok !
下面我们具体说一下
Servlet是一个接口,位于 javax.servlet.Servlet,它规定了每个Servlet所必须实现的方法。实际应用时我们需要从 javax.servlet.GenericServlet 和 javax.servlet.http.HttpServlet 两个抽象类继承出自己的Servlet类,并实现所需的功能。这几个类的关系如下(绿色斜体字为抽象类):
上图中,Servlet依赖于ServletRequest和ServletResponse接口,这两个接口负责为Servlet接受和发送信息。 HttpServlet也类似。
Servlet接口
javax.servlet.Servlet接口包含以下的方法:
init()
void init(ServletConfig config) throws ServletException
init方法用于初始化,在Servlet启动时调用。
service()
void service(ServletRequest req, ServiceResponse res) throws ServletException, IOException
Servlet通过这个方法,从req获得客户端请求,处理并生成结果,再通过res发送给客户端。
destroy()
void destroy()
Servlet销毁时执行的方法。
getServletInfo()
String getServletInfo()
将Servlet的信息通过字符串返回。
getServletConfig()
ServletConfig getServletConfig()
获取包含Servlet各种信息的ServletConfig对象。
当某个Servlet第一次被请求时,服务器(Servlet容器)会生成该Servlet并调用它的init()方法,再调用其service()方法处理请求。处理结束后该Servlet会常驻于容器中,下一个请求则不再重新生成Servlet,而是直接调用常驻的Servlet对象的service()方法。服务器停止时,会调用该Servlet的destroy()方法。
因此,在Servlet的一个生命周期中,init()和destroy()仅会被调用一次,而service()则会被调用多次。
―――
好我们又看看这样
package sakrua;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletHelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;
public ServletHelloWorld() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html><head><title>servlet Example by sakrua </title></head><body>");
out.println("<h3><font color=red>这就是Servlet 呵呵!</font></h3>");
out.println("</body></html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
public void destroy() {
System.out.println("It is destroy");
super.destroy();
}
public void init() throws ServletException {
System.out.println("It is started");
super.init();
}
}
看看控制台,所有都ok(close 后才会看到 Is is Destroy)
再看看ie,乱码了!晕
―――
GenericServlet抽象类
javax.servlet.GenericServlet为我们实现了Servlet接口的大部分方法,除了service()方法之外。因此,我们在制作自己的Servlet时,只需要继承GenericServlet并重载service()方法即可。
HttpServlet类
HttpServlet继承了GenericServlet,不过它也是一个抽象类,不能直接使用,只能继承它。
HttpServlet中常用的方法有两个:
doGet
void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
当浏览器用GET方式访问时,该方法被调用。
doPost
void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
当浏览器用POST方式访问时,该方法被调用。
这两个函数内部的处理方法基本上与上一节介绍的GenericServlet.service()函数相同。
另外其他的HTTP请求也都有相应的方法:
HTTP请求类别
HttpServlet的方法
GET
doGet()
POST
doPost()
HEAD
doHead()
PUT
doPut()
DELETE
doDelete()
HttpServletRequest
doGet()和doPost()函数的两个参数为 HttpServletRequest和HttpServletResponse对象。
HttpServletRequest接口表示浏览器请求,你可以通过这个类获取浏览器发送到服务器的任何信息。
getParameter
String getParameter(String name)
获取指定变量名name所对应的参数值。该方法实际上为父接口 javax.servlet.ServletRequest的方法。如果是GET请求则获取查询字符串后的参数,POST请求则获取<form>表单中的参数。类似于PHP的$_GET和$_POST数组。
getParameterValues
String[] getParameterValues(String name)
这个方法与getParameter()类似。当你要获取<input type="check">这类会返回多个值的表单属性时,就应当用这个方法。
getMethod
String getMethod()
返回字符串"GET"或"POST"。
getRequestURI
String getRequestURI()
获取请求的URI(不包括查询字符串)。相当于PHP的$_SERVER['REQUEST_URI']。
getServletPath
String getServletPath()
获取Servlet的路径。相当于PHP的$_SERVER['PHP_SELF']。
getPathInfo
String getPathInfo()
获取PathInfo。相当于PHP的$_SERVER['PATH_INFO']。
setCharacterEncoding
void setCharacterEncoding(String new)
设置请求的编码。需要处理汉字时务必要通过该方法设置正确的字符编码,否则将无法正确读取浏览器发过来的文字。
还有好多有用的方法大家可以自己去参考接口文档。
HttpServletResponse
HttpServletResponse接口则用于控制服务器发送给客户端的内容,相当于PHP的echo、header等函数。
setContentType
void setContentType(String type)
设置返回值的类型。通常的HTML内容可设置为"text/html; charset=UTF-8"等,而动态生成的图片则可以设置为"image/gif"等。输出汉字之前,务必要通过该方法指定输出的字符编码。相当于在PHP中写 header("Content-Type: image/gif")。
ServletOutputStream
ServletOutputStream getOutputStream() throws IOException
向客户端发送二进制数据时,需要通过此方法获取输出流。
getWriter
PrintWriter getWriter() throws IOException
向客户端发送文本数据时,需要通过此方法获取输出流。
看到这里应该知道为什么乱码了吧
加上这两句
response.setCharacterEncoding("GBK");
response.setContentType("text/html; charset=GBK");
几乎所有的Web开发语言都支持Session功能,Servlet也不例外。 Servlet/JSP中的Session功能是通过作用域(scope)这个概念来实现的。
作用域分为四种,分别为:
page
在当前页面有效(仅用于JSP中)
request
在当前请求中有效
session
在当前会话中有效
application
在所有应用程序中有效
好,servlet 讲完了,为什么要讲这个呢,我们在以后才会体会到
会到Struts 中,现在,struts 有两个版本 struts 1.x 和struts 2.x , 2 .x 是webwork 的化身,我们现在讲的是1.x .现在来一个struts 的hello world
新建一个同样的工程(如果用myeclipse 有点不一样)
把struts 的这些包copy到lib目录中
下面是step by step
1、修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts_HelloWorld by sakrua</display-name>
<!-- the struts config -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- end struts config -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
看不了没,跟servlet 是不是有点相似昵,以后我们会看到更加清楚(struts 的本质,你可以自己想想)
看到这里我们要有一个struts-config.xml文件, Now 我们来写一个
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean name="helloWorldForm" type="org.helloWorld.struts.form.HelloWorldForm"></form-bean>
</form-beans>
<action-mappings>
<action path="/hello" name="helloWorldForm" type="org.helloWorld.struts.action.HelloWorldAction">
<forward name="success" path="/helloworld/success.jsp"></forward>
<forward name="fail" path="/helloworld/fail.jsp"></forward>
</action>
</action-mappings>
<message-resources parameter="org.helloWorld.struts.resource.ApplicationResources"></message-resources>
</struts-config>
好,我们来看看这个XML文件,我们发现有<form-bean>和<action>现在我们先不理what is this
我们看到type中都有一个类,我们先来完成这个类
从ActionForm 类中继成
package org.helloWorld.struts.form;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
/**
* struts helloworld 的action form
* @author sakrua
* email :winds8@gmail.com msn:wind_s8@hotmail.com
* 2007年11月5日
*/
public class HelloWorldForm extends ActionForm {
private static final long serialVersionUID = -3372095237053639793L;
//一个javabean 从ActionForm继成
//用户名
private String userName;
//想说的话
private String worldToSay;
/*
//validate
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
//暂时我们不理这个,以后再说
if(userName.equals("")){
}
if(worldToSay.equals("")){
}
return super.validate(mapping, request);
}
*/
//下面为set get function
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getWorldToSay() {
return worldToSay;
}
public void setWorldToSay(String worldToSay) {
this.worldToSay = worldToSay;
}
}
下面是action
package org.helloWorld.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.helloWorld.struts.form.HelloWorldForm;
/**
* struts helloworld 的action form
* @author sakrua
* email :winds8@gmail.com msn:wind_s8@hotmail.com
* 2007年11月5日
*/
public class HelloWorldAction extends Action {
private static final String FAIL ="fail";
private static final String SUCCESS ="success";
//action中所有的请求都会由这个函数处理
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//从actionForm 中取数据
HelloWorldForm helloWorldForm =(HelloWorldForm)form;
String userName = helloWorldForm.getUserName();
String worldToSay = helloWorldForm.getWorldToSay();
//如果没有协作输入转到错误页面
if(userName.equals("")||worldToSay.equals("")){
return mapping.findForward(FAIL);
}
//转到成功页面
return mapping.findForward(SUCCESS);
}
}
还有两个jsp
Index.jsp
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Welcome you to use this demo</title>
</head>
<body>
<html:form action="/hello">
请输入你的用户名:
<html:text property="userName"></html:text><br />
请输入你想说的话:
<html:textarea property="worldToSay"></html:textarea><br />
<html:submit value="submit"></html:submit>
</html:form>
</body>
</html>
Fail.jsp
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>请输入完整的信息</title>
</head>
<body>
<bean:message key="helloWorld.userNameRequire"/><br />
<bean:message key="helloWorld.worldToSayRequire"/><br />
<a href="index.jsp" >转到转入页面</a>
</body>
</html>
Success.jsp
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Welcome you <bean:write name="helloWorldForm" property="userName" /></title>
</head>
<body>
<bean:write name="helloWorldForm" property="userName" /> 你想对我们说的是<bean:write name="helloWorldForm" property="worldToSay" />
</body>
</html>
好写完了
打开ie输入http://localhost:8080/Struts_HelloWorld/
正常运行中
在这个过程中我们做了什么呢,我们已经完成了我们的第一个struts 程序(废话)
具体做了什么
To be continued
posted on 2007-11-08 22:39
风の使者 阅读(266)
评论(0) 编辑 收藏 所属分类:
struts