西部村里人

常用链接

统计

其它BLOG

最新评论

2006年3月16日 #

WebWork标签技术的简化版本--JSP模板

   WebWork标签非常出色,在有些应用中,可能不想使用其环境,但希望能够使用其标签思路。JSP模板的使用面更广,随简化WebWork方式,提供思路供大家参考。

1、开发标签基础类:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public abstract class AbstractTag extends BodyTagSupport {

    protected String templateName ;

    private final static String templatePath = "/WEB-INF/tags/";

    private static final long serialVersionUID = -1201668454354226175L;

    public String getTemplateName() {
        return templateName;
    }

    public void setTemplateName(String templateName) {
        this.templateName = templateName;
    }

    protected String getBody() {
        if (bodyContent == null) {
            return "";
        } else {
            return bodyContent.getString().trim();
        }
    }
   
    protected abstract void prepareData ();

    public int doEndTag() throws JspException {
        try {
            prepareData ();
            include(templatePath + this.getTemplateName(), pageContext.getOut(),
                    pageContext.getRequest(),
                    (HttpServletResponse) pageContext.getResponse());

        } catch (Exception e) {
            // e.printStackTrace();
            throw new JspException(e);
        }
        return EVAL_BODY_INCLUDE;
    }

    public int doStartTag() throws JspException {
        try {
            pageContext.getOut().write(getBody());
        } catch (IOException e) {
            throw new RuntimeException("IOError: " + e.getMessage(), e);
        }
        return EVAL_PAGE;
    }

    public static void include(String aResult, Writer writer,ServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String resourcePath = aResult;
        RequestDispatcher rd = request.getRequestDispatcher(resourcePath);
        if (rd == null) {
            throw new ServletException("Not a valid resource path:"
                    + resourcePath);
        }
        // Include the resource
        PageResponse pageResponse = new PageResponse(response);

        // Include the resource
        rd.include((HttpServletRequest) request, pageResponse);

        // write the response back to the JspWriter, using the correct encoding.
        String encoding = "GB2312";

        if (encoding != null) {
            // use the encoding specified in the property file
            pageResponse.getContent().writeTo(writer, encoding);
        } else {
            // use the platform specific encoding
            pageResponse.getContent().writeTo(writer, null);
        }
    }

    static final class PageResponse extends HttpServletResponseWrapper {

        protected PrintWriter pagePrintWriter;

        protected ServletOutputStream outputStream;

        private PageOutputStream pageOutputStream = null;

        /**
         * Create PageResponse wrapped around an existing HttpServletResponse.
         */
        public PageResponse(HttpServletResponse response) {
            super(response);
        }

        /**
         * Return the content buffered inside the {@link PageOutputStream}.
         *
         * @return
         * @throws IOException
         */
        public FastByteArrayOutputStream getContent() throws IOException {
            // if we are using a writer, we need to flush the
            // data to the underlying outputstream.
            // most containers do this - but it seems Jetty 4.0.5 doesn't
            if (pagePrintWriter != null) {
                pagePrintWriter.flush();
            }

            return ((PageOutputStream) getOutputStream()).getBuffer();
        }

        /**
         * Return instance of {@link PageOutputStream} allowing all data written
         * to stream to be stored in temporary buffer.
         */
        public ServletOutputStream getOutputStream() throws IOException {
            if (pageOutputStream == null) {
                pageOutputStream = new PageOutputStream();
            }

            return pageOutputStream;
        }

        /**
         * Return PrintWriter wrapper around PageOutputStream.
         */
        public PrintWriter getWriter() throws IOException {
            if (pagePrintWriter == null) {
                pagePrintWriter = new PrintWriter(new OutputStreamWriter(
                        getOutputStream(), getCharacterEncoding()));
            }

            return pagePrintWriter;
        }
    }

    static final class PageOutputStream extends ServletOutputStream {

        private FastByteArrayOutputStream buffer;

        public PageOutputStream() {
            buffer = new FastByteArrayOutputStream();
        }

        /**
         * Return all data that has been written to this OutputStream.
         */
        public FastByteArrayOutputStream getBuffer() throws IOException {
            flush();

            return buffer;
        }

        public void close() throws IOException {
            buffer.close();
        }

        public void flush() throws IOException {
            buffer.flush();
        }

        public void write(byte[] b, int o, int l) throws IOException {
            buffer.write(b, o, l);
        }

        public void write(int i) throws IOException {
            buffer.write(i);
        }

        public void write(byte[] b) throws IOException {
            buffer.write(b);
        }
    }
   
   
    static public class FastByteArrayOutputStream extends OutputStream {

        // Static --------------------------------------------------------
        private static final int DEFAULT_BLOCK_SIZE = 8192;


        private LinkedList buffers;

        // Attributes ----------------------------------------------------
        // internal buffer
        private byte[] buffer;

        // is the stream closed?
        private boolean closed;
        private int blockSize;
        private int index;
        private int size;


        // Constructors --------------------------------------------------
        public FastByteArrayOutputStream() {
            this(DEFAULT_BLOCK_SIZE);
        }

        public FastByteArrayOutputStream(int aSize) {
            blockSize = aSize;
            buffer = new byte[blockSize];
        }


        public int getSize() {
            return size + index;
        }

        public void close() {
            closed = true;
        }

        public byte[] toByteArray() {
            byte[] data = new byte[getSize()];

            // Check if we have a list of buffers
            int pos = 0;

            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    System.arraycopy(bytes, 0, data, pos, blockSize);
                    pos += blockSize;
                }
            }

            // write the internal buffer directly
            System.arraycopy(buffer, 0, data, pos, index);

            return data;
        }

        public String toString() {
            return new String(toByteArray());
        }

        // OutputStream overrides ----------------------------------------
        public void write(int datum) throws IOException {
            if (closed) {
                throw new IOException("Stream closed");
            } else {
                if (index == blockSize) {
                    addBuffer();
                }

                // store the byte
                buffer[index++] = (byte) datum;
            }
        }

        public void write(byte[] data, int offset, int length) throws IOException {
            if (data == null) {
                throw new NullPointerException();
            } else if ((offset < 0) || ((offset + length) > data.length) || (length < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (closed) {
                throw new IOException("Stream closed");
            } else {
                if ((index + length) > blockSize) {
                    int copyLength;

                    do {
                        if (index == blockSize) {
                            addBuffer();
                        }

                        copyLength = blockSize - index;

                        if (length < copyLength) {
                            copyLength = length;
                        }

                        System.arraycopy(data, offset, buffer, index, copyLength);
                        offset += copyLength;
                        index += copyLength;
                        length -= copyLength;
                    } while (length > 0);
                } else {
                    // Copy in the subarray
                    System.arraycopy(data, offset, buffer, index, length);
                    index += length;
                }
            }
        }

        // Public
        public void writeTo(OutputStream out) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    out.write(bytes, 0, blockSize);
                }
            }

            // write the internal buffer directly
            out.write(buffer, 0, index);
        }

        public void writeTo(RandomAccessFile out) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    out.write(bytes, 0, blockSize);
                }
            }

            // write the internal buffer directly
            out.write(buffer, 0, index);
        }

        public void writeTo(Writer out, String encoding) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();

                    if (encoding != null) {
                        out.write(new String(bytes, encoding));
                    } else {
                        out.write(new String(bytes));
                    }
                }
            }

            // write the internal buffer directly
            if (encoding != null) {
                out.write(new String(buffer, 0, index, encoding));
            } else {
                out.write(new String(buffer, 0, index));
            }
        }

        /**
         * Create a new buffer and store the
         * current one in linked list
         */
        protected void addBuffer() {
            if (buffers == null) {
                buffers = new LinkedList();
            }

            buffers.addLast(buffer);

            buffer = new byte[blockSize];
            size += index;
            index = 0;
        }
    }
}

2、定义一个具体的标签类
public class ListTag extends RiseAbstractTag {

    private static final long serialVersionUID = 3385568988234498913L;

    protected String templateName = "list.jsp";

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    protected void prepareData() {
        this.setTemplateName(this.templateName);
        pageContext.getRequest().setAttribute("id", this.id);
    }
}

3、定义TLD文件
   参考TLD文档
4、定义list.jsp模板
<%@ page contentType="text/html; charset=GBK" %>

<%
String id = (String)request.getAttribute("id");
%>
<table width="90%" border="0" cellpadding="0" cellspacing="2">

  <tr>
    <td>Id</td>
    <td align="right"><%= id %></td>
  </tr>
</table>
5、使用默认模板
   <WWTag:list id="Hello World!"/>
6、使用自定义模板
   a: 定义模板
<%@ page contentType="text/html; charset=GBK" %>

<%
String id = (String)request.getAttribute("id");
out.println("Id is : " + id);
%>
   b: use it , 模板名:testList.jsp,放在/WEB-INF/tags目录下
   <WWTag:list id="Hello World!" templateName="testList.jsp"/>


posted @ 2006-03-16 22:57 西部村里人 阅读(1114) | 评论 (2)编辑 收藏

团队在局域网中共享ADSL方法(windows, linux)

   团队在外地封闭开发,没有带交换机功能能的HUB来连接到ADSL。只好共享ADSL方式。
   1、windows下共享非常简单,把ADSL共享即可,但不要把每一个连接都拨号给选上,否则无法使用。此时局域网内IP地址在192.168.0.1--192.168.0.2XX之间。问题是:容易坏,不稳定。随改用Linux。
   2、Linux环境下使用。Red Hat Linux ES3版本。(文档来自网络收集,共享大家使用)

http://www.chinalinuxpub.com/read.php?wid=558

 

 

1、 网卡配置。
我这里用的网卡是RTL80293com905。在系统中,RTL8029标记为eth03com905标记为eth1RTL80293com905IP地址分别是192.168.0.1192.168.1.1(其他的地址也可),掩码均为255.255.255.0
eth0用于连接网通,eth1用于连接内网,局域网网段为192.168.0.0
注意:此处两块网卡均不能设网关。
2 PPPoE软件的升级与安装
1) 在 http://www.roaringpenguin.com/pppoe/#download 下载
2) 安装rp-pppoe。以root身份执行
rpm Uvh rp-pppoe-3.5-1.i386.rpm
3、 修改/etc/ sysctl.conf
将其中的
net.ipv4.ip_forward = 0
改为
net.ipv4.ip_forward = 1
4、 去除ipchains模块,只选择iptables方法如下:
1setup
2)选择system service
3)去除ipchains
4)选中iptables
5)重启机器
5 PPPoE客户端配置
rp-pppoe-3.5-1.i386.rpm安装完毕后,接下来就可进行PPPoE客户端配置了。过程如下。
#/usr/sbin/adsl-setup
>>> Enter your PPPoE user name: ——此处输入拨号帐号的用户名
>>> Enter the Ethernet interface connected to the ADSL modem For Solaris, this is likely to be something like /dev/hme0. For Linux, it will be ethn, where 'n' is a number. (default eth0): ——输eth0
>>> Enter the demand value (default no): ——输no
>>> Enter the DNS information here: ——输210.83.130.18
>>> Please enter your PPPoE password: ——输网通用户口令
>>> Choose a type of firewall (0-2): ——输0
>>> Accept these settings and adjust configuration files (y/n)? ——输y
6、 启动拨号连接
/usr/sbin/adsl-start
成功连接后,屏幕显示Connected
此时这台linux已可以上网浏览了。
7 IP伪装
为了使局域网中的其他机器能通过Linux服务器共享上网,至少须执行下面的命令:
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
完成后,在192.168.0.0网段(网关为192.168.0.1)的PC机就可透过Linux上网了!
8、 开机自启动
为了使Linux服务器能够自动拨号,执行下面步骤。
1chkconfig --add adsl
2setup
3)选择system services
4)选中ADSL
5OK退出
6)打开/etc/rc.d/rc.local,在该文件的末尾添上下面语句
echo "[OK]"
echo "Drop ICMP form anywhere"
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo "[OK]"
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
说明:前面四句用于关闭ICMP,防止别人Ping
9、 至此,一切OK,一个简单的拨号建成了。重启机器后,发现linuxinternet共享连接已经一切就绪了,好妙!!!

为了建立更安全的拨号连接,请再设置各种安全机制吧,好事多磨嘛。
另外,如果网关后面的客户机无法通过linux上网,请留意一下linux的防火墙设置。

REDHAT9ADSL最终解决方案

 

发布于2005-05-29 被读559 【字体:大 小】

 

LINUXSIRLINUXFANS上看了很多关于ADSL的文章,都没有解决我的REDHAT9ADSL上网的问题,今天实在是没有办法,重新建立连接,曲折的经历,终于上网了(非常激动,可能表达的不是很好),特的写下我的过程,作为参考:

 

REDHAT默认的PPPOE有问题,需要RPM -E,然后,安装这个 --实际在RedES3上没必要按照这个共享包。

http://www.roaringpenguin.com/pppoe/rp-pppoe-3.5.tar.gz(北南兄推荐)

解压和安装:

#tar zxvf rp-pppoe-3.5.tar.gz

进入解压目录执行

#sh ./go

 

 

然后再来设置ADSL。这一处,我们要用命令。

 

#adsl-setup

 

 

Welcome to the Roaring Penguin ADSL client setup. First, I will run

some checks on your system to make sure the PPPoE client is installed

properly...

 

Looks good! Now, please enter some information:

 

USER NAME

 

>>> Enter your PPPoE user name (default XXX): 在这里输入ADSL的用户名

 

INTERFACE

 

>>> Enter the Ethernet interface connected to the ADSL modem

For Solaris, this is likely to be something like /dev/hme0.

For Linux, it will be ethn, where 'n' is a number.

(default eth0):如果一张网卡就设置写上eth0

 

Do you want the link to come up on demand, or stay up continuously?

If you want it to come up on demand, enter the idle time in seconds

after which the link should be dropped. If you want the link to

stay up permanently, enter 'no' (two letters, lower-case.)

NOTE: Demand-activated links do not interact well with dynamic IP

addresses. You may have some problems with demand-activated links.

>>> Enter the demand value (default no):不用写什么

 

DNS

Please enter the IP address of your ISP's primary DNS server.

If your ISP claims that 'the server will provide DNS addresses',

enter 'server' (all lower-case) here.

If you just press enter, I will assume you know what you are

doing and not modify your DNS setup.

>>> Enter the DNS information here:在这里写上202.96.134.133

下一个DNS202.96.168.68 //这里根据个人不同可以修改

 

PASSWORD

 

>>> Please enter your PPPoE password:输入密码

>>> Please re-enter your PPPoE password:再输入一次

 

FIREWALLING

 

Please choose the firewall rules to use. Note that these rules are

very basic. You are strongly encouraged to use a more sophisticated

firewall setup; however, these will provide basic security. If you

are running any servers on your machine, you must choose 'NONE' and

set up firewalling yourself. Otherwise, the firewall rules will deny

access to all standard servers like Web, e-mail, ftp, etc. If you

are using SSH, the rules will block outgoing SSH connections which

allocate a privileged source port.

 

The firewall choices are:

0 - NONE: This script will not set any firewall rules. You are responsible

for ensuring the security of your machine. You are STRONGLY

recommended to use some kind of firewall rules.

1 - STANDALONE: Appropriate for a basic stand-alone web-surfing workstation

2 - MASQUERADE: Appropriate for a machine acting as an Internet gateway

for a LAN

>>> Choose a type of firewall (0-2):这里添写为2

 

** Summary of what you entered **

 

Ethernet Interface: eth0

User name: XXX

Activate-on-demand: No

DNS: Do not adjust

Firewalling: MASQUERADE

 

>>> Accept these settings and adjust configuration files (y/n)?

 

弄完后,就按一个y键。

(以上为北南兄文章里面内容)

不要急于连接,REBOOT -N

然后进入网络设置,停止ETH1(我的是用他)

然后ADSL-START

PING 你的DNS,如果可以,那么,恭喜你!

其中部分内容可能不同,仅作参考,主要在连接后,能够PINGDNS即可!

 

 

 

==========================================================================

首先应该确定您是否安装了pppoe的应用程序。

 

  如果确实已经安装了,可以在终端用 adslsetup命令启动adsl配置,提示过程为英文。

 

  大概为:

 

[root@localhost root]# adsl-setup

Welcome to the ADSL client setup. First, I will run some checks on

your system to make sure the PPPoE client is installed properly...

 

The following DSL config was found on your system:

 

Device: Name:

ppp0 DSLppp0

 

Please enter the device if you want to configure the present DSL config

(default ppp0) or enter 'n' if you want to create a new one: ppp0 //默认为ppp0

 

LOGIN NAME

 

Enter your Login Name (default SJ00411210A1): anthrax //这里用你自己的用户名代替我的anthrax:)

 

INTERFACE

 

Enter the Ethernet interface connected to the ADSL modem

For Solaris, this is likely to be something like /dev/hme0.

For Linux, it will be ethX, where 'X' is a number.

(default eth0): eth0 //默认网卡设备为eth0

 

Do you want the link to come up on demand, or stay up continuously?

If you want it to come up on demand, enter the idle time in seconds

after which the link should be dropped. If you want the link to

stay up permanently, enter 'no' (two letters, lower-case.)

NOTE: Demand-activated links do not interact well with dynamic IP

addresses. You may have some problems with demand-activated links.

Enter the demand value (default no): no //这里使用默认no就可以了,断线后不自动拨号。

 

 

DNS

 

Please enter the IP address of your ISP's primary DNS server.

If your ISP claims that 'the server will provide dynamic DNS addresses',

enter 'server' (all lower-case) here.

If you just press enter, I will assume you know what you are

doing and not modify your DNS setup.

Enter the DNS information here: 202.96.134.133 //DNS地址设置,根据您的具体情况替换。

Please enter the IP address of your ISP's secondary DNS server.

If you just press enter, I will assume there is only one DNS server.

Enter the secondary DNS server address here: 202.96.134.133 //第二DNS地址设置。

 

PASSWORD

 

Please enter your Password: //这里设置密码,和unix规则一样,密码并不回显,因此不要认为您的键盘出了毛病:)

Please re-enter your Password:

//确认密码

USERCTRL

 

Please enter 'yes' (two letters, lower-case.) if you want to allow

normal user to start or stop DSL connection (default yes): yes //是否允许普通用户共享ADSL

 

FIREWALLING

 

Please choose the firewall rules to use. Note that these rules are

very basic. You are strongly encouraged to use a more sophisticated

firewall setup; however, these will provide basic security. If you

are running any servers on your machine, you must choose 'NONE' and

set up firewalling yourself. Otherwise, the firewall rules will deny

access to all standard servers like Web, e-mail, ftp, etc. If you

are using SSH, the rules will block outgoing SSH connections which

allocate a privileged source port.

 

The firewall choices are:

0 - NONE: This script will not set any firewall rules. You are responsible

for ensuring the security of your machine. You are STRONGLY

recommended to use some kind of firewall rules.

1 - STANDALONE: Appropriate for a basic stand-alone web-surfing workstation

2 - MASQUERADE: Appropriate for a machine acting as an Internet gateway

for a LAN

Choose a type of firewall (0-2): 1 //配置防火墙等级,根据您的需要选择。

 

Start this connection at boot time

 

Do you want to start this connection at boot time?

Please enter no or yes (default no):no //是否允许开机自动加载,这里选择no,否则系统启动速度太慢!

 

** Summary of what you entered **

 

Ethernet Interface: eth0

User name: anthrax

Activate-on-demand: No

Primary DNS: 202.96.134.133

Secondary DNS: 202.96.134.133

Firewalling: STANDALONE

User Control: yes

Accept these settings and adjust configuration files (y/n)?

 

 

  选择y,配置完成。您可以用 adslstart命令启动,可以用adslstop命令停止。

 

  为了方便,可以在桌面建立一个应用程序链接,命令就使用adslstart。这样每次双击那个快捷图标就可以建立adsl链接了,跟windows中一样方便。

 

好了,现在就开始您的网络之旅吧。(技巧:如果依据本内容操作扔不能链接网络,可以尝试在"系统设置->网路"中删除当前的网卡,重新配置adsl项。)


posted @ 2006-03-16 15:31 西部村里人 阅读(372) | 评论 (0)编辑 收藏

Eclipse CVS 在局域网中与防火墙共用

    在打开windows网络防火墙的情况下,cvs的验证过程非常慢,几乎难以忍受。关闭防火墙虽然比较快捷,但计算机的安全性受到考验。
    方法1、使用天网等防火墙产品,允许所有低端端口,允许局域网访问所有端口。注:此时它关闭了Windows的防火墙,使用自己提供的功能。
    方法2、Windows配置,打开113,2401在局域网范围内的TCP端口。

posted @ 2006-03-16 15:11 西部村里人 阅读(1179) | 评论 (0)编辑 收藏

2006年3月12日 #

补充:(Hibernate XDoclet 在Eclipse中的模版随笔)

原文:Hibernate XDoclet 在Eclipse中的模版
补充:Hibernate对象关联--UML基础知识、XDoclet---- 5 XDoclet Template In Eclipse
      (系列内容参看:浏览)

posted @ 2006-03-12 15:38 西部村里人 阅读(1456) | 评论 (0)编辑 收藏

一些Java技术网站--四处收集--没有分类

http://www.javaalmanac.com - Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的去处.
http://www.onjava.com - O'Reilly的Java网站. 每周都有新文章.
http://java.sun.com - 官方的Java开发者网站 - 每周都有新文章发表.
http://www.developer.com/java - 由Gamelan.com 维护的Java技术文章网站.
http://www.java.net - Sun公司维护的一个Java社区网站.
http://www.builder.com - Cnet的Builder.com网站 - 所有的技术文章, 以Java为主.
http://www.ibm.com/developerworks/java - IBM的Developerworks技术网站; 这是其中的Java技术主页.
http://www.javaworld.com - 最早的一个Java站点. 每周更新Java技术文章.
http://www.devx.com/java - DevX维护的一个Java技术文章网站.
http://www.fawcette.com/javapro - JavaPro在线杂志网站.
http://www.sys-con.com/java - Java Developers Journal的在线杂志网站.
http://www.javadesktop.org - 位于Java.net的一个Java桌面技术社区网站.
http://www.theserverside.com - 这是一个讨论所有Java服务器端技术的网站.
http://www.jars.com - 提供Java评论服务. 包括各种framework和应用程序.
http://www.jguru.com - 一个非常棒的采用Q&A形式的Java技术资源社区.
http://www.javaranch.com - 一个论坛,得到Java问题答案的地方,初学者的好去处。
http://www.ibiblio.org/javafaq/javafaq.html - comp.lang.java的FAQ站点 - 收集了来自comp.lang.java新闻组的问题和答案的分类目录.
http://java.sun.com/docs/books/tutorial/ - 来自SUN公司的官方Java指南 - 对于了解几乎所有的java技术特性非常有帮助.
http://www.javablogs.com - 互联网上最活跃的一个Java Blog网站.
http://java.about.com/ - 来自About.com的Java新闻和技术文章网站.
http://www.codechina.net 提供大量的java源代码及教程。

posted @ 2006-03-12 14:34 西部村里人 阅读(278) | 评论 (0)编辑 收藏

2006年3月10日 #

Hibernate XDoclet 在Eclipse中的模版

开发Hibernate很久,最终还是XDoclet提供的帮助最大。能够处理复杂的对象关系,也最符合面向对象的原则。
方法1:
OO类图--〉数据库设计--〉MiddleGen (能够处理基本的关联关系--打开XDoclet标签生成开关,但不能处理继承概念,较为遗憾ing)-->在Eclipse手工更新Java类中 的XDoclet标签,然后XDoclet生成Hbm文件。当然了再写个JUnit测试一下关联关系是否正确,必要的Lazy是否标注。

下载Template: http://raibledesigns.com/wiki/Wiki.jsp?page=XDocletEclipse#hibcolidx 非常感谢MattRaible.

在中文环境中,window xp的字符切换键与Eclipse模版的字符快捷键重合,需要修改之。为了避免麻烦,直接修改Template文件,简单添加@标示符:全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<templates>
    <template name="@hibarray" description="@hibernate.array" context="javadoc" enabled="true">@hibernate.array table=&quot;&quot; cascade=&quot;save-update&quot;</template>
    <template name="@hibbag" description="@hibernate.bag" context="javadoc" enabled="true">@hibernate.bag table=&quot;&quot; lazy=&quot;false&quot; cascade=&quot;none&quot; inverse=&quot;false&quot;</template>
    <template name="@hibclass" description="@hibernate.class" context="javadoc" enabled="true">@hibernate.class table=&quot;${enclosing_type}&quot;</template>
    <template name="@hibcolelm" description="@hibernate.collection-element" context="javadoc" enabled="true">@hibernate.collection-element column=&quot;&quot; type=&quot;&quot; length=&quot;&quot;</template>
    <template name="@hibcolidx" description="@hibernate.collection-index" context="javadoc" enabled="true">@hibernate.collection-index column=&quot;&quot; type=&quot;&quot; length=&quot;&quot;</template>
    <template name="@hibcolkey" description="@hibernate.collection-key" context="javadoc" enabled="true">@hibernate.collection-key column=&quot;&quot; generator-class=&quot;native&quot;</template>
    <template name="@hibcolmtm" description="@hibernate.many-to-many" context="javadoc" enabled="true">@hibernate.set name=&quot;${enclosing_method}&quot; table=&quot;link_table_name_here&quot; cascade=&quot;save-update&quot; inverse=&quot;true|false&quot; lazy=&quot;true&quot;
     * @hibernate.collection-key column=&quot;${enclosing_type}_ID&quot;
     * @hibernate.collection-many-to-many class=&quot;relationship_class_the_set_contains&quot; column=&quot;relationship_foreign_key&quot;
     * @return ${return_type}</template>
    <template name="@hibcolotm" description="@hibernate.one-to-many relationship" context="javadoc" enabled="true">@hibernate.set name=&quot;${enclosing_method}&quot; table=&quot;relationship_table&quot;
     *                     sort=&quot;comparator_class&quot; inverse=&quot;true|false&quot;
     *                     cascade=&quot;save-update&quot; lazy=&quot;true&quot;
     * @hibernate.collection-key column=&quot;${enclosing_type}_ID&quot;
     * @hibernate.collection-one-to-many class=&quot;relationship_class&quot;
     *
     * @return ${return_type}</template>
    <template name="@hibcomelm" description="@hibernate.collection-composite-element" context="javadoc" enabled="true">@hibernate.collection-composite-element class=&quot;&quot;</template>
    <template name="@hibcomp" description="@hibernate.component" context="javadoc" enabled="true">@hibernate.component class=&quot;component_class_name&quot;</template>
    <template name="@hibdisc" description="@hibernate.discriminator" context="javadoc" enabled="true">@hibernate.discriminator column=&quot;subclass&quot; type=&quot;character&quot;</template>
    <template name="@hibid" description="@hibernate.id" context="javadoc" enabled="true">Note: unsaved-value An identifier property value that indicates that an instance
     * is newly instantiated (unsaved), distinguishing it from transient instances that
     * were saved or loaded in a previous session.  If not specified you will get an exception like this:
     * another object associated with the session has the same identifier
     *
     * @hibernate.id generator-class=&quot;&quot; type=&quot;${return_type}&quot; column=&quot;${enclosing_type}_ID&quot;
     * unsaved-value=&quot;null&quot; length=&quot;&quot;
     * @return ${return_type}</template>
    <template name="@hiblist" description="@hibernate.list" context="javadoc" enabled="true">@hibernate.list table=&quot;relationship-table&quot; lazy=&quot;false&quot; cascade=&quot;none&quot;</template>
    <template name="@hibmap" description="@hibernate.map" context="javadoc" enabled="true">@hibernate.map name=&quot;${enclosing_method}&quot; table=&quot;relationship-table&quot; lazy=&quot;false&quot; cascade=&quot;none&quot;</template>
    <template name="@hibmto" description="@hibernate.many-to-one" context="javadoc" enabled="true">@hibernate.many-to-one column=&quot;${return_type}_ID&quot; class=&quot;package.${return_type}&quot;
     *
     * @return ${return_type}
     *</template>
    <template name="@hiboto" description="@hibernate.one-to-one" context="javadoc" enabled="true">hibernate.one-to-one cascade=&quot;none&quot; class=&quot;&quot; outer-join=&quot;auto&quot;</template>
    <template name="@hibprimarr" description="@hibernate.primitive-array" context="javadoc" enabled="true">@hibernate.primitive-array table=&quot;&quot; cascade=&quot;none&quot;</template>
    <template name="@hibprop" description="@hibernate.property" context="javadoc" enabled="true">@hibernate.property name=&quot;${enclosing_method}&quot; column=&quot;${enclosing_method}&quot; type=&quot;${return_type}&quot; not-null=&quot;false&quot; unique=&quot;false&quot;
     *
     * @return ${return_type}</template>
    <template name="@hibquery" description="@hibernate.query" context="javadoc" enabled="true">@hibernate.query name=&quot;&quot; query=&quot;&quot;</template>
    <template name="@hibset" description="@hibernate.set" context="javadoc" enabled="true">@hibernate.set name=&quot;${enclosing_method}&quot; table=&quot;relationship_table&quot;
     *                     sort=&quot;comparator_class&quot; inverse=&quot;true&quot;
     *                     cascade=&quot;save-update&quot; lazy=&quot;true&quot;</template>
    <template name="@hibsubc" description="@hibernate.subclass" context="javadoc" enabled="true">@hibernate.subclass name=&quot;&quot; discriminator-value=&quot;&quot;</template>
    <template name="@hibts" description="@hibernate.timestamp" context="javadoc" enabled="true">@hibernate.timestamp column=&quot;${enclosing_method}&quot;
     *
     * @return ${return_type}</template>
    <template name="@hibver" description="@hibernate.version" context="javadoc" enabled="true">@hibernate.version column=&quot;${enclosing_method}&quot;
     *
     * @return ${return_type}</template>
</templates>

使用时:先把XML内容单独保存为文件,然后在Eclipse-->Windows-->Preferences
                                     在Preferences-->Java-->Editor-->Templates 点击Import按钮导入之前已经保存的XML文件。

方法2:
OO类图--〉在Eclipse手工编写属性--〉生成Get/Set方法--〉更新Java类中 的XDoclet标签,然后XDoclet生成Hbm文件。当然了再写个JUnit测试一下关联关系是否正确,必要的Lazy是否标注。
要求先修改Get方法的模板:源代码编辑器中鼠标右键--〉Source--〉Generate Getters And Setters..
bb.PNG
                      
               点击打开面板中Code Template链接。
aa1.PNG

编辑Getter方法模板:
/**
 * @hibernate.property name="${bare_field_name}" column="${field}" type="${field_type}" not-null="false" unique="false" length="128"
 * @return Returns the ${bare_field_name}.
 */
然后生成代码,手工微调部分属性。也能够节约大量时间。

注意:在编写Java POJO类时,java属性用完整的带包名的类,例如:
/**
* @author jdyao
 * @hibernate.class table="respri"
 * @version
 */
public class Resource implements Serializable {

    private static final long serialVersionUID = 1505581058179605003L;

    private java.lang.String guid;

    private java.lang.String context;

 

    public
Resource () {

    }

    /**
     * @return java.lang.String
     * @hibernate.property name="context" type="java.lang.String"
     *                     length="128"
     *
     */
    public java.lang.String getContext() {
        return context;
    }

    public void setContext(java.lang.String context) {
        this.context = context;
    }

    /**
     * @return java.lang.String
     * @hibernate.id generator-class="guid" type="java.lang.String" column="guid"
     *               unsaved-value="null" length="38"
     */
    public java.lang.String getGuid() {
        return guid;
    }

    public void setGuid(java.lang.String guid) {
        this.guid = guid;
    }

}
原因:XDoclet在生成的时候,如果type="string",有时会出现错误,无法生成Hbm文件,为了避免这个不必要的错误,务必要写全类名。

XDoclet build.xml文件:

<?xml version="1.0" encoding="ISO-8859-1"?>

<project name="XDoclet Examples" default="hibernate" basedir=".">
    <property name="xdoclet.root.dir" value="${basedir}"/>
    <property file="${xdoclet.root.dir}/build.properties"/>

    <!-- Include the build-dist properties. Since properties are immutable,
    this will not override available properties. You do not have to include
    this in your own build file. -->
    <property file="build-dist.properties"/>

    <!-- See CustomerBean. This is to demonstrate property substitution. -->
    <property name="ejb.prefix" value="blah"/>

    <!-- =================================================================== -->
    <!-- Define the class path                                               -->
    <!-- =================================================================== -->
    <path id="samples.class.path">
        <fileset dir="${lib.dir}">
            <include name="*.jar"/>
        </fileset>
        <fileset dir="${samples.lib.dir}">
            <include name="*.jar"/>
        </fileset>
        <fileset dir="${dist.lib.dir}">
            <include name="*.jar"/>
        </fileset>
    </path>

    <!-- =================================================================== -->
    <!-- Initialise                                                          -->
    <!-- =================================================================== -->
    <target name="init">
        <tstamp>
            <format property="TODAY" pattern="d-MM-yy"/>
        </tstamp>
        <taskdef
            name="xdoclet"
            classname="xdoclet.DocletTask"
            classpathref="samples.class.path"
            />
         <taskdef
            name="hibernatedoclet"
            classname="xdoclet.modules.hibernate.HibernateDocletTask"
            classpathref="samples.class.path"
            />
    </target>


    <!-- =================================================================== -->
    <!-- Prepares the directory structure                                    -->
    <!-- =================================================================== -->
    <target name="prepare" depends="init">
        <mkdir dir="${samples.classes.dir}"/>
        <mkdir dir="${samples.gen-src.dir}"/>
        <mkdir dir="${samples.meta-inf.dir}"/>
    </target>



    <!-- =================================================================== -->
    <!-- Invoke XDoclet's hibernate                                          -->
    <!-- =================================================================== -->
    <target name="hibernate" depends="prepare" description="Generate mapping documents (run jar first)">

        <echo>+---------------------------------------------------+</echo>
        <echo>|                                                   |</echo>
        <echo>| R U N N I N G   H I B E R N A T E D O C L E T     |</echo>
        <echo>|                                                   |</echo>
        <echo>+---------------------------------------------------+</echo>

        <hibernatedoclet
            destdir="${samples.gen-src.dir}"
            mergedir="${samples.src.dir}"
            excludedtags="@version,@author,@todo,@see"
            addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author XDoclet,@version ${version}"
            force="${samples.xdoclet.force}"
            verbose="false">

            <fileset dir="${samples.java.dir}">
                <include name="**/**/*.java"/>
            </fileset>

            <hibernate version="3.0"/>

        </hibernatedoclet>
    </target>

    <!-- =================================================================== -->
    <!-- Clean                                                               -->
    <!-- =================================================================== -->
    <target name="clean">
        <delete dir="${samples.dist.dir}"/>
    </target>

</project>
build-dist.properties 文件:
# These properties are only used when building the samples expanded from the distribution.

lib.dir = ${xdoclet.root.dir}/lib
dist.lib.dir = ${lib.dir}

samples.dir = ${xdoclet.root.dir}
samples.dist.dir = ${samples.dir}/target
samples.lib.dir = ${samples.dir}/lib
samples.src.dir = ${samples.dir}/src
samples.java.dir = ${samples.src.dir}/java
samples.gen-src.dir = ${samples.dist.dir}/gen-src

samples.meta-inf.dir = ${samples.dist.dir}/meta-inf
samples.web-inf.dir = ${samples.dist.dir}/web-inf
samples.merge.dir = ${samples.src.dir}/merge
samples.classes.dir = ${samples.dist.dir}/classes
samples.web.dir = ${samples.src.dir}/web
samples.xdoclet.force = false

工程目录结构:从XDoclet网站下载该包,解压缩后,把Example目录单独copy出来,把这2个文件放在Example目录下,同时建立lib目录,把XDoclet目录下--〉lib目录下的*.jar拷贝到Example新建立的lib目录下。

posted @ 2006-03-10 00:28 西部村里人 阅读(1443) | 评论 (0)编辑 收藏

仅列出标题