`
Ivan_Pig
  • 浏览: 388224 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Struts meets Swing 1 (翻译)

阅读更多
原文:http://javaboutique.internet.com/tutorials/Swing/index.html

1.简介: 
   Jakarta Struts是基于MVC模式创建servlet应用程序的框架。大部分的Struts应用程序都是使用浏览器作为客户端,实际上Struts足够的开放,它可以使用其它的客户端模式。在这里我将在我 "Coding your second Jakarta Struts Application"这篇文章里的一个浏览器应用实例改成Swing客户端模式,只需要修改一点代码。
   这篇文章主要介绍如何使用Swing客户端去连接已经存在的Servlet应用。如果你打算开发一个java应用程序,既能够使用浏览器做客户端也可以用Swing做客户端,你就需要根据你程序的需要灵活的选择构架,如EJB或web service,他们提供了简单的接口。

2.Struts结构
   在我们开始之前,先看看浏览器如何和Struts应用通信的。这些将在我们的Swing应用程序中体现。
   *Struts应用程序是由servlet接受到GET或POST请求开始的。
   *servlet决定调用哪个"action",是从URL中获得信息的。
   *实现了Action的java类是在struts-config.xml中配置的。
   * Struts的输出由jsp来显示,jsp的名字也在struts-config.xml文件中指定。
   所以第一个非浏览器应用需要能够给servlet发送一个请求,并且能从jsp页面得到响应。

3.The URLConnection class

    使用URLConnection类能够很简单的使用java编写servlet请求代码。这个类很有趣,因为它有一些奇怪的设计。如果你想看看它的实现,我建议你读一读"Dodge the traps hiding in the URLConnection class".
    如果想发送一个带有"list"action的请求,并接受打印响应,你需要这样写代码:

URL url = new URL("http://myserver/project/list.do");
    URLConnection conn = url.openConnection();
    
    BufferedReader in = 
       new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line;  
    while ((line = in.readLine()) != null) {
       System.out.println(line);
    }


    一般来讲你通常需要在请求的同时发送一些数据--就像提交表单那样。这些数据需要在你读取响应前发送过去。

URL url = new URL("http://myserver/project/list.do");
    URLConnection conn = url.openConnection();
    conn.setDoOutput(true);
    conn.setRequestProperty("user-agent","SWING");  
    
    BufferedWriter out =
       new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
    out.write("name1=value1&name2=value2");
    out.flush();
    out.close();
    
    String c = conn.getHeaderField("Set-Cookie");
    BufferedReader in = 
       new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line;  
    while ((line = in.readLine()) != null) {
       System.out.println(line);
    }


    这个例子同时也显示了如何读写HTTP头信息。
    第一个例子使用GET方法与HTTP通信,而第二个例子使用POST方法通信。你同样可以使用GET方法来给servlet传送数据,但是就必须要把数据加到URL里,像这样:
URL url = new URL("http://myserver/project/list.do?name1=value1&name2=value2");


4.Identifying the client
    现在我们知道怎么发送和请求数据了,但是我们怎么接受数据呢?如果响应是给浏览器的,那响应里就包含了HTML或者还有JavaScript和样式。对于我们的Swing客户端,我们只需要数据。这将带来一个新问题:Struts应用程序如何能识别出客户端是一个浏览器,是个Swing还是其它什么呢?
    一种解决办法是在每个请求里添加参数时其能间鉴别出是哪种客户端。我在第二个例子里已经使用了user-agent这个头信息来使其识别出是个Swing客户端。
    当Struts应用程序准备好给客户端返回数据时,它就会检测user-agent的值,然后选择适合客户端的jsp页面。这将会替代Struts Action类设置的跳转信息。

String client = (String)request.getHeader("user-agent");
    // Forward control to the list page
    if (client.equals("SWING")) 
     return (mapping.findForward("swinglist"));
    else return (mapping.findForward("list"));


     "list"和"swinglist"的在Struts配置文件里定义:
<forward name="list" path="/list.jsp"/>
    <forward name="swinglist" path="/swinglist.jsp"/>


    list.jsp是为在浏览器显示的,swinglist.jsp则是在Swing上显示的。

    在我们开始创建swinglist.jsp前,先看一个例子程序,改程序将使用文章里提到的方法。

    The DVD application

    这个应用程序是在xml文件里管理DVD的。它将会以列表的方式显示所有的DVD,并且可以在详细页面里添加,修改或删除DVD.列表像这样。
     图片见原文

    DVDManager类监听DVD应用程序,它将DVD信息保存为JDOM的树结构。DVDManager从xml文件中读取DVD信息,并能够将这些信息再保存到xml文件里。xml格式很明显是返回数据给Swing应用程序的一种选择。

Returning XML data to the client

    这就意味着,swinglist.jsp要返回数据给Swing客户端,就必须以xml的方式来存放DVD。JDOM有能将树结构转换成PRintWriter的方法,我们只要简单的获取这些输出流并将它发送给Swing客户端即可。DVDmanager里的第一个新方法就是:
public void outList(PrintWriter out) {
      XMLOutputter outputter = new XMLOutputter("",false);
      // NB: the outputter does not accept XML headers:  
      outputter.setOmitDeclaration(true); 
      try {
        outputter.output(doc, out);
      } catch (IOException e) {
        e.printStackTrace();
      }    
    }


这个方法将被swinglist.jsp调用:

<%@ page language="java" %>
    <%@ page import="java.io.*" %>
    
    <jsp:useBean id="dvds" 
      class="hansen.playground.DVDManager" scope="session"/>
     
    <%
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        dvds.outList(pw); 
        pw.flush();
        out.print(sw.toString());
    %>


相似的方法我们创建一个swingdetail.jsp页面,这个页面将返回一个的xml文件,包含着单个的DVD信息:

<%@ page language="java" %>
    <%@ page import="java.io.*" %>
    
    <jsp:useBean id="dvds" 
      class="hansen.playground.DVDManager" scope="session"/>
    
    <%
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        dvds.outListElement(pw); 
        pw.flush();
        out.print(sw.toString());
    %>


    我们可以不使用JDOM的XMLOutputter类来创建xml响应而直接手动编码。让我来给个例子:如果我们只想返回DVD的名字,我们能创建一个像这样的jsp页面:
    
<%@ page language="java" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
    
    <jsp:useBean id="dvds" 
      class="hansen.playground.DVDManager" scope="session"/>
    
    <collection>
    <logic:iterate id="dvd" indexId="i" name="dvds" property="dvds">
    <% 
    // Transfer the iteration index to the DVDManager 
    dvds.setIndex(i.intValue()); 
    %>
    <dvd>
    <title><bean:write name="dvds" property="title"/></title>
    </dvd>
    </logic:iterate>
    </collection>


当这个页面执行,它将会产生一个像这样的输出。

<collection>
      <dvd>
        <title>Amadeus</title>
      </dvd>
      <dvd>
        <title>Lord of the Rings: The Fellowship of the Ring</title>
      </dvd>
      <dvd>
        <title>The Matrix</title>
      </dvd>
    </collection>


Testing the Swing jsp-pages


    除了错误页面,DVD应用程序只使用了swinglist.jsp和swingdetail.jsp,所以让我们用DemoRequest来测试一下这两个jsp页面。
    它包含一个request方法能发送一个请求给servlet,并将响应输出到System.out。注意怎样设置请求的user-agent为"SWING"。如果我们像这样请求:
DemoRequest dr = new DemoRequest("http://localhost:8080/dvdapp2/list.do");
    dr.request();


    我们得到输出:

<collection>
      <dvd id="C">
        <title>Amadeus</title>
        <length>158</length>
        <actor>F. Murray Abraham</actor>
        <actor>Tom Hulce</actor>
        <actor>Elizabeth Berridge</actor>
      </dvd>
      <dvd id="A">
        <title>Lord of the Rings: The Fellowship of the Ring</title>
        <length>178</length>
        <actor>Ian Holm</actor>
        <actor>Elijah Wood</actor>
        <actor>Ian McKellen</actor>
      </dvd>
      <dvd id="B">
        <title>The Matrix</title>
        <length>136</length>
        <actor>Keanu Reeves</actor>
        <actor>Laurence Fishburne</actor>
      </dvd>
    </collection>



    如果和第三个代码相比,你会发现他们很像。让我们来发送个请求来请求第一个DVD的详细信息。

DemoRequest dr = new DemoRequest("http://localhost:8080/dvdapp2/list.do");
    dr.request();  
    dr = new DemoRequest("http://localhost:8080/dvdapp2/detail.do");
    dr.setData("index=0");  
    dr.request(); 


    结果不是我们期望的。我们得到了正确的DVD列表,但是输出却是这样的:
<html>
    <head>
    <title>System Error</title>
    </head>
    <body>
    <h2>System Error</h2>
    
    No DVD information available
    
    </body>
    </html>


    这是error.jsp页面返回的,它告诉我们处理Detail页面的Struts Action类没有在session范围内找到DVD列表信息。

Maintaining the Session


    这种错误你可能要花数小时去确定。或一下子就找到了原因。这里是原因。

    当服务显示的为浏览器用户提供服务时,我们都经常会忘记session状态为每个用户创建了cookie,并通过cookie来识别用户。当我们第一次访问应用时cookie会被发送到我们机器上。当我们进行下一次请求时,就该我们把cookie送还给服务器了,这样服务器就能识别出session.在测试程序里我们没有做这个,所以现在我们必须修改代码来存储返回来的cookie,并再以后的请求中把cookie发送回去。DemoRequestCookie这个新类,看这里。

     新的请求就像这样:

DemoRequestCookie dr = 
       new DemoRequestCookie("http://localhost:8080/dvdapp2/list.do");
    dr.request();  
    String cookie = dr.getCookie();
    dr = new DemoRequestCookie("http://localhost:8080/dvdapp2/detail.do");
    dr.setData("index=0");  
    dr.setCookie(cookie);
    dr.request();  



    这次输出就和期望的相符了。
. . . (list of all DVDs) . . .
    <dvd id="C">
        <title>Amadeus</title>
        <length>158</length>
        <actor>F. Murray Abraham</actor>
        <actor>Tom Hulce</actor>
        <actor>Elizabeth Berridge</actor>
    </dvd>


Updating the Struts configuration file


    我们必须在struts-config.xml里配置前面的方法。每个定义都必须包含jsp文件,且这个文件必须要Swing-counterpart。比较下配置文件。
section
name
refers to

global-forwards
error
error.jsp

  list
list.jsp

  detail
detail.jsp

action-mappings
create
detail.jsp

  update
detail.jsp

  delete
list.jsp

  cancel
list.jsp


我们添加新节点。

section
name
refers to

global-forwards
swingerror
swingerror.jsp

  swinglist
swinglist.jsp

  swingdetail
swingdetail.jsp

action-mappings
swingcreate
empty.jsp

  swingupdate
empty.jsp

  swingdelete
empty.jsp

  swingcancel
empty.jsp

就像你看到的action mappings的empty.jsp节点,它有如下内容:

<empty/>

   它包含一个单独的xml元素所以是个有效的xml文件。你会发现很奇怪的是,在创建,删除和去掉时不会需要返回任何信息,但是原因很简单。Swing客户端是胖客户端,而浏览器是瘦客户端。胖客户端能存储当前DVD的数据和可能所有DVD的列表。

    所以,胖客户端只需要从服务器段获取一次DVD列表即可,此后它将数据保存在本地。如果DVD列表不高喊所有的DVD数据,没那么当选择某个DVD时,它将会从服务器获取。这就是swingdetail action停止调用swingdetail.jsp的原因。

    有一点需要指出。在下一版本的Struts(1.1)中,将会包含不止一个配置文件。通过阅读给我的初步说明,Swing actions可能会放到其它配置文件中,这也许会是个让代码整洁的解决办法。

Coding the Swing client
   我们完成了Swing客户端的代码:
    我们知道了怎样通过URLConnection和Session cookies调用servlet。我们知道了怎样格式化xml响应。
    在下一篇文章里,我将讲述如何创建一个Swing客户端,来解析和显示xml响应,并且我们来看看如何找到错误。





分享到:
评论
2 楼 alanytam 2009-03-12  
强顶!正在找这方面的东东,打算用Struts做一个Swing的项目!好像有点挑战!打算用struts2,所以还有多加研究。

1 楼 liyaxi 2009-02-15  
有创意! 支持!

相关推荐

    struts1和struts2的区别

    ### Struts1与Struts2的主要区别 #### 概述 Apache Struts 是一个用于构建企业级Java Web应用的开源框架。它分为两个版本:Struts1 和 Struts2。虽然两者都基于模型-视图-控制器(MVC)设计模式,但它们之间存在...

    struts2.0整合Struts 1

    Struts 2整合Struts 1,允许开发者利用Struts 1已有的投资,同时享受Struts 2带来的优势,如增强的类型安全和更强大的拦截器机制。 在《Struts 2权威指南--基于WebWork核心的MVC开发》这本书中,作者李纲深入浅出地...

    Struts2与Struts1区别

    Struts2 和 Struts1 是两个著名的 Java Web 开发框架,它们都出自 Apache Software Foundation,但有着显著的区别。Struts1 是早期的 MVC 框架,而 Struts2 则是在 WebWork 框架的基础上发展起来的,它吸收了 Struts...

    Struts1和Struts2区别

    Struts1和Struts2是两个非常著名的Java Web框架,它们都由Apache软件基金会开发,用于构建MVC(Model-View-Controller)架构的应用程序。虽然它们在目标上相似,但在设计模式、功能特性和使用体验上存在显著差异。...

    struts1jar包

    Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它基于Model-View-Controller(MVC)架构模式,为构建动态、数据驱动的Web应用程序提供了强大的支持。标题中的"struts1jar包"指的是Struts1框架所需...

    struts1&struts2

    Struts1和Struts2是两个著名的MVC框架,它们都是Apache软件基金会的Apache Struts项目的一部分,用于构建基于Java的Web应用程序。然而,两者在设计和实现上有显著的差异。 1. **架构模式的区别** - **Struts1.x** ...

    精通struts1.x技术,struts1完整详细教程

    Struts1.x 是一款经典的Java Web开发框架,由Apache软件基金会发起的Jakarta Struts项目创建,旨在实现MVC(Model-View-Controller)设计模式,以提高开发效率和代码的可维护性。该框架最初由Craig McClanahan在2000...

    java Struts J2EE MVC 外文翻译

    ### Java Struts J2EE MVC 外文翻译 #### 概述 本文旨在介绍 Struts,一种基于 Model-View-Controller (MVC) 设计模式的开源实现方式。该模式利用了 Servlet 和 JavaServer Pages (JSP) 技术来构建 Web 应用程序。...

    struts1完整demo

    Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它主要负责处理MVC(Model-View-Controller)架构中的Controller部分。Struts1在2000年代初期非常流行,为开发者提供了构建企业级应用程序的强大工具...

    struts1和struts2的jar包

    Struts1和Struts2是两个不同的版本,它们各自拥有独特的特性和功能,但在Java Web开发领域都扮演了重要角色。 **Struts1** Struts1是最早的版本,它在2001年发布,是基于ApacheJakarta项目的一个框架。Struts1的...

    Struts1实验项目

    Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它主要负责处理MVC(Model-View-Controller)架构中的控制器部分。本实验项目旨在帮助开发者深入理解Struts1的核心概念和工作流程,以便更好地在实际...

    struts1 和 struts2所需jar包

    struts1 和 struts2所需jar包。主要包含以下内容: struts-1.3.10-all.zip struts-1.3.10-apps.zip struts-1.3.10-lib.zip struts-1.3.10-src.zip struts-2.3.4.1-all.zip struts.rar

    struts2和struts1 API及使用指南 chm

    Struts2是Struts1的升级版,它在Struts1的基础上引入了许多改进和新特性,提高了开发效率和应用性能。 Struts1是一个经典的MVC框架,它的核心组件包括Action、Form Bean、Action Mapping和Tiles等。Action是业务...

    Struts1和Struts2的区别和对比

    Struts1和Struts2是两个非常著名的Java Web框架,它们在设计模式、可测试性、输入处理和表现层等方面存在显著的区别。 首先,Action类的设计有所不同。在Struts1中,Action类需要继承一个抽象基类,这限制了Action...

    Struts1-1API.rar_Struts1_API_struts 1 api_struts1_struts1 api_st

    Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它主要负责处理MVC(Model-View-Controller)架构中的控制器部分。Struts1 API是开发者在使用Struts1框架进行开发时的重要参考文档,提供了框架的...

    struts1和struts2的区别(详细)

    ### Struts1与Struts2的主要区别 #### 一、Action执行机制的不同 - **Struts1**: 在Struts1框架中,Action是基于单例模式的,这意味着所有的请求都会共享同一个Action实例。这就导致了如果在Action中保存实例变量...

    struts1标签库详解

    Struts1 标签库详解 Struts1 标签库是 Apache Jakarta 的一个著名的开源项目,目标是为构建基于 Java 的 web 应用程序提供一个框架。Struts 提供了非常多的标签,依据功能和使用习惯的不同被分到了五个标签库中:...

    struts1.x和struts2.0电子书

    这个压缩包包含了两个关键版本的Struts框架的电子书,即Struts1.x和Struts2.0的相关资料。 **Struts1.x** Struts1.x是最初的Struts版本,它极大地简化了Java Servlet和JSP的应用开发。Struts1的核心概念包括Action...

    struts1 jar包

    Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它基于Model-View-Controller(MVC)架构模式,为构建动态、数据驱动的Web应用程序提供了强大的支持。标题中的"struts1 jar包"指的是Struts1框架的...

Global site tag (gtag.js) - Google Analytics