博客换主题啦!!!

feed订阅 腾讯微博 你好,欢迎光临! 

数据库触发器与事务

2008.10.13 , 未分类 , 1 条评论 , 2,161 浏览

当对数据库中的一张表进行操作且同时又要对与之相关的其他表的数据进行修改时,要如何操作呢?一种方法是写出每一个操作的SQL语句,然后逐一执行。但是,如果碰到银行转账这种业务,我们需要先从A帐户扣钱,然后给B帐户加钱。若A帐户扣钱成功但是B帐户加钱失败,我们还得再多写一条SQL用以在失败的时候再把A的钱给加上。这样太麻烦而且需要我们在底层写很多数据库操作代码,容易出错也不安全。
此时就可以用触发器与事务来处理,当对A帐户进行修改时自动触发执行对B帐户的修改,并且当其中任何一个操作失败时,事务会自动回滚,取消之前所有的操作,这样就无形的减少了不少代码及安全隐患。
我所做的项目就有这样的一个需要:有一个文章表和一个文章类别表,文章类别表中有个字段用于存储该类别下的文章数量。所以,增加或删除一篇文章同时需要对类别表进行修改,只需要使用如下的代码创建一个触发器即可。

 
  1. CREATE TRIGGER trig_Article_Ins--开始创建触发器
  2. ON dbo.blog_Article--指明要对哪个表创建
  3. FOR INSERT--创建INSERT类型的触发器
  4. AS
  5. BEGIN TRANSACTION--开始事务
  6.     DECLARE @cateId int,@errorSum int--声明变量,分别用于存储类别ID和错误统计
  7.     SET @errorSum = 0--错误统计初值为0
  8.     SELECT @cateId=log_CateID FROM inserted--查到新插入的文章的类别ID
  9.     SET @errorSum=@errorSum+@@ERROR--累计错误
  10.     UPDATE blog_Category SET cate_Count=cate_Count+1 WHERE cate_ID=@cateId--对相应的表进行更新
  11.     SET @errorSum=@errorSum+@@ERROR--累计错误
  12.     
  13.     IF @errorSum <> 0--若执行期间出现错误则回滚,否则提交事务
  14.         BEGIN
  15.             print '创建失败,回滚事务!'
  16.             ROLLBACK TRANSACTION
  17.         END
  18.     ELSE
  19.         BEGIN
  20.             print '创建成功,提交事务!'
  21.             COMMIT TRANSACTION
  22.         END
  23. GO

 

另外,使用这个还有另外一个原因:好久没有写过这些东西了,该练练手了。所以,今天在编写这个触发器的时候还小查了一下帮助手册。

 

列名或所提供值的数目与表定义不匹配

2008.10.12 , 未分类 , 无评论 , 1,397 浏览

今天在操作数据库的时候报出了一个错误:java.sql.SQLException: [Microsoft][ODBC SQL Server Driver][SQL Server]插入错误: 列名或所提供值的数目与表定义不匹配。怎么可能呢,我昨天对同样的数据库同样的表执行同样的操作时候是没有问题的啊!开玩笑呢吧!开始抓虫...
首先从程序的代码入手,顺便用企业管理器打开对应的表,检查了一下字段数是对的呀,难道代码中的SQL我拼错了?给代码中又加了句System.out.println(sql)。

 
  1. public static boolean createCategory(CategoryBean cate)
  2.     {
  3.         String sql = "INSERT INTO blog_Category VALUES('"+cate.getCateName()+"',"+cate.getCateCount()+")";
  4.         dbc = new DataSource();
  5.         System.out.println(sql);
  6.         stmt = dbc.getPreparedStatement(sql);
  7.         return dbc.executeUpdate(stmt);
  8.     }

接着再次执行了一下还是报错:
INSERT INTO blog_Category VALUES('测试',0)
java.sql.SQLException: [Microsoft][ODBC SQL Server Driver][SQL Server]插入错误: 列名或所提供值的数目与表定义不匹配。
从输出的结果来看,我的SQL是绝对没有拼错的!OK,静下心来整理一下思路:
假如数据库中有张表,此表包含3个字段且均为必填,如果有一个字段是自增类型的标识列,那么我们写SQL的时候就不需要管它。反之,在插入一条数据的时候就必须有这一字段的数据,否则就会报出这样的错误。
OK,想明白了,也知道自己的SQL是的确没有拼错,那么问题就是出在我的标识列上了,仔细检查了一下这张表的主键列,结果发现竟然忘记设置它为标识列并令其自增了。这时突然想起来我昨天貌似把数据库重新覆盖过一次,用来覆盖的那个数据库是还没有设计完整的!我狂晕~
不过,其实遇到问题遇到错误是件好事,从中可以学到很多知识,没有问题才是最大的问题!切记:遇到问题时不要头大,或许当时有点烦躁,但一定要冷静一下,静下心来仔细想想为什么会出现这样的问题,你会发现原来问题如此简单!

IT行业需要什么人才

2008.10.11 , , 5 条评论 , 805 浏览

作为一个搞软件开发的IT工作者来说,时时关注行业中最需要的技能是什么是很重要的事情。
Robert Half Technology调查了1400位CIO,调查问题是:他们最需要的IT技能是什么?调查结果反映的也是当今IT的局势及其未来走向。
所有的被提问者(CIO们)均工作在有100名以上员工的公司,可以选择不止一项技能。以下是在2008年9月的调查结果:
•    网络管理员( Network administration (LAN, WAN)): 70%
•    Wiondows管理员(Windows administration): 69%
•    桌面支持(Desktop support): 69%
•    数据库管理( Database management): 58%
•    无线网络管理( Wireless network management): 47%
•    通讯支持(Telecommunications support): 44%
•    Web开发/网站设计(Web development/Website design): 42%
•    商业情报/报告服务(Business intelligence/reporting services): 33%
•    虚拟化(Virtualization): 32%
•    .NET开发(.NET development): 22%
•    CRM 实施(CRM implementation): 22%
•    ERP 实施(ERP implementation): 20%
•    Linux/Unix 管理员(Linux/Unix administration): 20%
•    Java开发(Java development): 17%
•    开源开发(Open source development): 17%
•    XML 开发(XML development): 17%
从上面的调查可以看出我将要从事的都在20%左右徘徊...

Churrasco巴西烤肉很好很强大

2008.10.10 , , 7 条评论 , 3,018 浏览

在拿到WEBSHELL进行入侵提权经常会碰到可以执行CMD但是却不能执行例如net user neeke /add这样的操作的情况,这一下就把一条提权的捷径封杀了,不过现在有了Churrasco.exe碰到这种事就真的成了捷径了。
今天在“腾讯西安文明群”看到皇子大牛(群签名“父亲”)在说话:

父亲 12:28:53
谁有win2003的 webshell 能执行命令的
父亲 12:29:01
丢来一个 我看看提权
父亲 12:29:25
快点
父亲 12:29:28
刚拿到的东西
父亲 12:31:07
麻痹算了我自己去找shell

竟然没人鸟他,汗~~十分钟后皇子发图:
父亲(543261053) 12:41:40


看看时差!就是10分钟的事,不得不佩服皇子啊!(拍个马屁)
看到这个图,我无语啦,太强大了!以前我碰到那么多可以执行CMD但是提不上去的...赶紧百度搜Churrasco...
不知道是这个名字怪还是真的知道的人很少,找出来的都是葡萄牙语“巴西烤肉”,怪不得皇子说“刚拿到的东西”,不过还是被我Google到了,看来老外还是牛!
拿到了就得亲自试用一下,找了找N久以前的一个可以执行CMD但无法提权的WEBSHELL,结果发现SHELL已经被删了,索性又夺了回来(几个月前的漏洞还在,无语~)。然后传了Churrasco.exe上去,接着执行/c d:\wwwroot\Churrasco.exe "net user neeke /add"竟然真的提示成功了!不敢相信,以为眼花了,又直接执行了/c net user test /add结果啥没反应都没有的,接着又用Churrasco.exe把neeke加到administrators里,然后登录服务器...我没啥要说的了。竟然还免杀!

pager-taglib分页标签使用方法

2008.10.9 , , 4 条评论 , 3,968 浏览

以前写的那个[jsp中实现分页显示数据] 方法不通用,得找个分页标签。关于pager-taglib的使用方法网上虽说一大堆,但是同样费我不少脑细胞去看。有的代码不齐全,有的根本就是错误的,有的写的很潦草,看的我是云里雾里的,经过本人耗费大量的脑细胞奋战N个小时终于搞出了点猫腻。
想明白了,写出来运行成功了,我才发现其实用法很简单,没那些人写的那么麻烦。
首先当然还是要导pager-taglib.jar包了,可以去http://jsptags.com/tags/navigation/pager/index.jsp下载,从下载下来的war文件中找到pager-taglib.jar包以及pager-taglib.tld文件。将pager-taglib.tld文件放在WEB-INF目录下,将pager-taglib.jar放在WEB-INF/lib目录下(JBuilder中的导入方法可以参考[Servlet中实现文件上传] )。
新建一个bean文件定义如下两个方法(不一定非要这个样子):

 
  1. /**
  2.      * 该方法用于获得数据总数
  3.      * @return int
  4.      */
  5. public int getArticlesCount() {
  6.         String sql = "SELECT COUNT(*) FROM blog_Article";
  7.         dbc = new DataSource();
  8.         stmt = dbc.getPreparedStatement(sql);
  9.         rs = dbc.getResultSet(stmt);
  10.         int count = 0;
  11.         try {
  12.             if(rs.next()){
  13.               count = rs.getInt(1);
  14.             }
  15.         } catch (SQLException ex) {
  16.             ex.printStackTrace();
  17.         } finally {
  18.             dbc.closeConnection();
  19.         }
  20.         return count;
  21.     }
  22.     
  23.     /**
  24.      * 该方法用于数据分页
  25.      * @param begin int
  26.      * @param end int
  27.      * @return ArrayList
  28.      */
  29. public ArrayList getArticlesAll(int begin,int end) {
  30.         String sql = "select top "+end+" * from blog_Article where (log_ID <= (select min(log_ID) from (select top "+begin+" log_ID from blog_Article order by log_PostTime desc) as t)) order by log_PostTime desc";
  31.         ArrayList list = new ArrayList();
  32.         dbc = new DataSource();
  33.         stmt = dbc.getPreparedStatement(sql);
  34.         rs = dbc.getResultSet(stmt);
  35.         try {
  36.             while (rs.next()) {
  37.                 ArticleBean article = new ArticleBean();
  38.                 article.setId(rs.getInt(1));
  39.                 //赋值操作...
  40.                 article.setTag(rs.getString(10));
  41.                 article.setIsTop(rs.getByte(11));
  42.                 list.add(article);
  43.             }
  44.         } catch (SQLException ex) {
  45.             ex.printStackTrace();
  46.         } finally {
  47.             dbc.closeCon
    nection();
  48.         }
  49.         return list;
  50.     }

 

接下来新建一个JSP页面(需要JSTL):

 
  1. <%@ page contentType="text/html; charset=GBK" import="java.util.*,com.nkblog.bean.ArticleBean,com.nkblog.dbc.*" %>
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  3. <%@ taglib uri="WEB-INF/pager-taglib.tld" prefix="pg" %>
  4. <%
  5. request.setCharacterEncoding("GBK");
  6. String offset = request.getParameter("pager.offset");//pager.offset为此分页标签内置变量用于传递页数
  7.         int page = 0;
  8.         if(offset == null){
  9.         //若offset为null则是第一次访问,所以显示第一页
  10.             page= 1;
  11.         }else{
  12.         //反之,则按照传递来的页数来分
  13.             page = Integer.parseInt(offset)+1;
  14.         }
  15. //获取数据总数        
  16. int dataTotal = ArticleManager.getArticlesCount();
  17. //查询分页数据,10为每页要显示的数据量,可自定义
  18. ArrayList articles = ArticleManager.getArticlesAll(page,10);
  19. %>
  20. <%
  21. for(int i=0;i<articles.size();i++)
  22. {
  23. //输出取出的10条数据...
  24. }
  25. %>
  26. <pg:pager scope="request" maxIndexPages="5" index="center" maxPageItems="10" url="index.jsp" items="<%=dataTotal%>" %>" export="currentPageNumber=pageNumber">
  27.         <pg:first><a href="${pageUrl}">首页</a></pg:first>
  28.         <pg:prev><a href="${pageUrl}">前页</a></pg:prev>
  29.   <pg:page>
  30.   </pg:page>
  31.         <pg:pages>
  32.             <c:choose>
  33.             <c:when test="${pageNumber eq currentPageNumber }">
  34.             <font color="red">${pageNumber }</font>
  35.             </c:when>
  36.             <c:otherwise>
  37.             <a href="${pageUrl }">${pageNumber}</a>
  38.             </c:
    otherwise>
  39.             </c:choose>
  40.    </pg:pages>
  41.         <pg:next><a href="${pageUrl}">下页</a></pg:next>
  42.         <pg:last><a href="${pageUrl}">尾页</a></pg:last>
  43. </pg:pager>

接下来具体说明上面的分页标签<pg:pager>
maxIndexPages为分页条个数,形如:< << 1 2 3 4 5 >> >
maxPageItems为每页要显示的数据量
url为处理分页请求的文件,可以是JSP或Servlet。当程序运行起来后,会以index.jsp?pager.offset=5的形式传递页数。
items为数据总数,pager-taglib会自动根据以上参数进行分页。
需要进行修改的也就上面这几个参数,起初看别人写的方法,我以为只要导入这个标签然后给定一个List数据集合,它就完全自动的跟也并显示数据了,汗~~也不知道我这么写会有几个看得懂的,估计懂的人有,但是能看明白我写的就少了...我发现原来代码写起来简单,但是要给别人将明白了真的好难啊。

 

Servlet中实现文件上传

2008.10.8 , , 2 条评论 , 1,600 浏览

很久以前写的那个[文件上传] 是在JSP页面中实现的,此次我们来要在Servlet中实现文件的上传处理,两种方法的代码是不一样的,我看到有很多人说在Servlet中要使用commons-fileupload.jar的话还需要commons-io.jar提供支持而在JSP中不需要,经过我的测试,MS在Servlet中也是不需要这个commons-io.jar。
下面我们开始实现Servlet处理文件上传,首先我们需要去下载上面提到的两个jar包,下载地址分别为:
http://commons.apache.org/fileupload
http://commons.apache.org/io/
然后将这两个包导入到你的Web工程下的WEB-INF中的lib目录中去,没有lib的话请自建。另外如果你使用的是JBuilder来做的话,这样放进去是没有用的,使用的时候会提示DOES NOT EXIST。需要按照如下方法导入:
1.选则菜单栏中的“Tools”->“Configure”->“Libraies”。
2.点击“New”,Name这里随便输入(例如:CommonsFileUpload),最好是见其名知其意,Location这里可以不管他。
3.点击“Add”,将那两个包都导入进来,最后一路“OK”。
4.在你的工程命(例如:Neeke.jpx)上右键并选择“Properties”进入“Properties for 'Neeke.jpx'”对话框,选择“Required Libraries”项,选择“Add”,找到你刚才新建的那个“CommonsFileUpload”然后一路“OK”。
现在就可以正常使用了,且JBuilder会自动将这两个包放在lib下。
新建一个upload.jsp,其代码如下:

<%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title>
upload
</title>
</head>
<body>
<form action="../uploadservlet" method="POST" enctype="Multipart/form-data">
<input type="file" name="file" /><input type="submit" value="上传" />
</form>
</body>
</html>

需要注意的是表单form的enctype属性一定要写“Multipart/form-data”,没有什么为什么!
接下来我们新建一个Servlet为UploadServlet(要有DOPOST方法)并导入如下几个包:
org.apache.commons.fileupload.*;
org.apache.commons.io.*;
org.apache.commons.fileupload.servlet.ServletFileUpload;
org.apache.commons.fileupload.disk.DiskFileItemFactory;
由于在JBuilder中doPost()调用了doGet()方法,所以我们可以直接改写doGet()方法,具体代码如下:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws
             ServletException, IOException {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        DiskFileItemFactory fac = new DiskFileItemFactory();
        //设置缓存文件大小
        fac.setSizeThreshold(1024*1024);
        //缓存文件位置,这里取的是默认的位置
        fac.setRepository(fac.getRepository());
        ServletFileUpload upload = new ServletFileUpload(fac);
        //设置最大允许上传的文件大小,这里是5MB
        upload.setFileSizeMax(1024*1024*5);
        List fileList = null;
        try {
            fileList = upload.parseRequest(request);
        } catch (FileUploadException ex) {
            response.sendRedirect("admin/upload.jsp?result=size");
            ex.printStackTrace();
            return;
        }
        Iterator iter = fileList.iterator();
        while(iter.hasNext()){ i>
            FileItem fileItem = (FileItem)iter.next();
            if(!fileItem.isFormField()){
                String name = fileItem.getName();
                String fileSize = new Long(fileItem.getSize()).toString();
                if(name == null || name.equals("") || fileSize.equals("0"))
                    continue;
                //截取出纯文件名
                name = name.substring(name.lastIndexOf("\\")+1);
                //存储文件
                File saveFile = new File("d:\\upload\\"+name);
                try {
                    fileItem.write(saveFile);
                } catch (Exception ex1) {
                    ex1.printStackTrace();
                    return;
                }
            }
        }
        out.close();
}

这样这个Servlet就能够实现对文件的上传了,这里文件的缓存大小及文件大小限制都可以动态的设置,我想这个问题具体就不需要我写了吧,嘿嘿。

Java读取XML文件

2008.10.7 , , 无评论 , 1,342 浏览

前天做了那个[JSP网站RSS的实现] ,此乃用Java写XML文件,学东西我们要学全(尽可能的全),不能只知其一不知其二,今天来实现在Java中对XML类型文件的读取。
在Java中要实现对XML文件的读取,首先,我们要导入一下几个包。
javax.xml.parsers.DocumentBuilder;
相关解释:
定义 API, 使其从 XML 文档获取 DOM 文档实例。使用此类,应用程序员可以从 XML 获取一个 Document。
javax.xml.parsers.DocumentBuilderFactory;
相关解释:
定义工厂 API,使应用程序能够从 XML 文档获取生成 DOM 对象树的解析器。
org.w3c.dom.Document;
相关解释:
Document 接口表示整个 HTML 或 XML 文档。从概念上讲,它是文档树的根,并提供对文档数据的基本访问。
org.w3c.dom.NodeList;
相关解释:
NodeList 接口提供对节点的有序集合的抽象,没有定义或约束如何实现此集合。DOM 中的 NodeList 对象是活动的。
NodeList 中的项可以通过从 0 开始的整数索引进行访问。
了解了这些知识,我们就可以在Java中像写JavaScript一样获得XML文件中的数据了。
下面是一个具体的方法用于读取前天创建的RSS文件:

 
  1. public static void getArticleList(String fpath){
  2.         try{
  3.             DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
  4.             DocumentBuilder db=dbf.newDocumentBuilder();
  5.             Document doc=db.parse(fpath);
  6.             NodeList nodeList=doc.getElementsByTagName("item");
  7.             for(int i=0;i<nodeList.getLength();i++){
  8.                 String title=doc.getElementsByTagName("title").item(i).getFirstChild().getNodeValue();
  9.                 String author=doc.getElementsByTagName("author").item(i).getFirstChild().getNodeValue();
  10.                 String pubDate=doc.getElementsByTagName("pubDate").item(i).getFirstChild().getNodeValue();
  11.                 String description=doc.getElementsByTagName("description").item(i).getFirstChild().getNodeValue();
  12.                 String category=doc.getElementsByTagName("category").item(i).getFirstChild().getNodeValue();
  13.                 
  14.                 System.out.println(title);
  15.                 System.out.println(author);
  16.                 System.out.println(pubDate);
  17.                 System.out.println(description);
  18.                 System.out.println(category);
  19.             }
  20.         }catch(Exception e){
  21.             System.out.println(e.getMessage());
  22.         }
  23.     }

frame与frame之间如何用JavaScript传值

2008.10.6 , , 4 条评论 , 2,529 浏览

这个依然是为我的项目而服务的,因为项目的功能需要此技术来实现,或许对很多人来说这个不难,可是对我这个不太对JavaScript感冒的人来说就不是那么容易了,办法只有一个:找资料现学呗。

先来了解一下相关知识:要实现框架中多窗体的不同元素的访问,则必须使用window对象中的Frames属性。Frames属性同样也是一个数组,它在父框架集中为每一个子框架设有一项。通过下标实现不同框架的访问:
parent.frames[Index1].docuement.forms[index2]
通过parent.frames.length确定窗口中窗体的数目。除了使用数组下标来访问窗体外还可以使用框架名和窗体名来实现各元素的访:
parent.framesName.document.getElementById()
OK,这么点资料就够用了,我们来小试一把。首先创建一个theFather.html,其代码如下:

 
  1. <html>
  2. <head>
  3. <title>frame get Value test</title>
  4. </head>
  5. <iframe frameborder="1" height="78" marginheight="0" marginwidth="0" scrolling="no" width="100%" src="theSon.html"></iframe>
  6. <h3>这是theFather的文本框</h3>
  7. <input type="text" name="txtFather" id="txtFather" />
  8. </html>

 

接下来创建theSon.html,其代码如下:

 
  1. <html>
  2. <head>
  3. <title>the son frame</title>
  4. <script type="text/javascript">
  5. //此方法用于向其父文本框类赋值
  6. function setValue(){
  7.   
  8.   //获得子类文本框中的值
  9.   var sonValue=document.getElementById("txtSon").value;
  10.   //弹出信息,此处仅用于测试
  11.   alert("theSon的值为:"+sonValue);
  12.   //向父类文本框赋值
  13.   parent.document.getElementById("txtFather").value=sonValue;
  14. }
  15. </script>
  16. </head>
  17. <body>
  18. <h3>这是theSon的文本框及按钮</h3>
  19. <input type="text" name="txtSon" id="txtSon" />
  20. <input type="button" name="btnSon" id="btnSon" value="提交" onclick="setValue();" />
  21. </body<
    span class="tag">>
  22. </html>

 

接下来运行测试,达到了预期的效果,现在可以正式融入项目中了。

 

JSP网站RSS的实现

2008.10.5 , , 7 条评论 , 1,992 浏览

RSS(也叫聚合内容,Really Simple Syndication)现在用的已经很广啦,最初的RSS要追溯到1995年,当Ramanathan V. Guha和其他在苹果电脑公司的高级技术组开发了一个测试的内容框架。更多有关RSS的资料可查看这里,下面我们来为我们的JSP网站生成RSS。

首先我们来看看最基本的RSS结构:

 
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"  
  3. xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"  
  4. xmlns:wfw="http://wellformedweb.org/CommentAPI/"  
  5. xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  6. </rss>

其实就是一个XML文件!在<rss></rss>之间我们可以自由配置自己要发布的RSS的格式。例如此次我们要发布的RSS是这样的:

 
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" x
  3. mlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" 
  4. xmlns:wfw="http://wellformedweb.org/CommentAPI/" x
  5. mlns:slash="http://purl.org/rss/1.0/modules/slash/">
  6. <channel>
  7. <item>
  8. <title>JSP网站RSS的实现</title>
  9. <author>neeke</author>
  10. <pubDate>2008-10-04</pubDate>
  11. <description>这是来自尼克技术博客博客的RSS</description>
  12. <category>J2EE技术</category>
  13. </item>
  14. </channel>
  15. </rss>

 

了解了它的结构实现起来就容易了。我们创建IO流,并从数据库中获取到我们要发布的RSS资源的集合,然后按照它的格式与结构一行一行的写入到一个RSS.XML文件中即可。

 
  1. public static void publishRss(String rssPath)
  2.     {
  3.       &
    nbsp; 
    //获得要发布的RSS数据集合
  4.         ArrayList rssArticle = ArticleManager.getArticlesAll();
  5.         try {
  6.             //创建输入输出流
  7.             FileWriter fw = new FileWriter(rssPath);
  8.             BufferedWriter bw = new BufferedWriter(fw);
  9.             //开始按照格式写入数据
  10.             bw.write(
  11.                     "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n");
  12.             bw.write("<?xml-stylesheet type=\"text/xsl\" href=\"CSS/rss.xslt\"?>");
  13.             bw.write("<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\" xmlns:wfw=\"http://wellformedweb.org/CommentAPI/\" xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\">\r\n");
  14.             bw.write("<channel>\r\n");
  15.             for (int i = 0; i < rssArticle.size(); i++) {
  16.                 ArticleBean article = (ArticleBean) rssArticle.get(i);
  17.                 bw.write("<item>\r\n");
  18.                 bw.write("<title>" + article.getTitle() + "</title>\r\n");
  19.                 bw.write("<author>" + article.getAuthorId() + "</author>\r\n");
  20.                 bw.write("<pubDate>" + article.getPostTime() + "</pubDate>\r\n");
  21.                 bw.write("<description>" + article.getIntro() +
  22.                          "</description>\r\n");
  23.                 bw.write("<category>" + article.getCateId() + "</category>\r\n");
  24.                 bw.write("</item>\r\n");
  25.             }
  26.             bw.write("</channel>\r\n");
  27.             bw.write("</rss>");
  28.             //关闭流,RSS发布完毕。
  29.             bw.close();
  30.             fw.close();
  31.         } catch (IOException ex) {
  32.             ex.printStackTrace();
  33.         }
  34.     }

发布完毕,经过我的测试打开后会提示出错,用记事本打开生成的源文件,然而我们的RSS文件是一点问题都没有的哇,怎么可能呢?接着又用JBuilder打开这个XML文件,晕倒~汉字全是乱码,立刻意识到问题出在了哪里了。在哪呢?其实就是文件的编码问题!将原先
bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n");该行代码中的UTF-8改为GBK,重新跑一次程序,一切OK!

J2EE MVC模式中首页初始化

2008.10.4 , , 4 条评论 , 1,283 浏览

虽然也学了这么久的J2EE了(基础型),但是我一直都搞不明白:MVC模式是要分三层的,显示层、控制层(业务逻辑层)及数据层,业务逻辑层才能访问数据层,而显示层不能够直接访问数据层。既然如此,那么网站的首页所需要的数据都是来自数据库的,是要动态读取的,这就要在jsp中直接访问数据层,岂不是相互矛盾了吗?
去了几个技术论坛看了看,有人说那只是一个高效的框架模型,不一定非要遵守,可以直接在首页jsp中调用数据层的方法,活人岂能被尿憋死?话虽说有那么点道理,不过我还是不想这么试。
我是这么想的:
方法1.能不能打开网站地址时候访问的第一个文件是一个Servlet,在Servlet中获得首页用于显示所需要的所有数据,然后将它放在request中,接着在使用
request.getRequestDispatcher("index.jsp").forward(request, response);
跳转到真实的首页,如此即可在index.jsp中从request中获得所要的数据了。那么,如何才能打开网址就直接访问Servlet呢?在网站的根目录下WEB-INF中的web.xml中有这么一对标签:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
类似于配置IIS中的默认首页 ,我们把这里的index.jsp改为对应的Servlet即可。

方法2.创建一个过滤器,专门用来过滤首页文件,当请求首页文件时就在过滤器中取数据。过滤器本身其实也是Servlet。
我就晕了,无论用这里面哪一个方法,那这里面的Servlet到底属于哪一层啊?是不是我太钻牛角尖了?