2007-05-30

听《爱情转移》听到了深夜,一直抱着陶陶,想着她。

一个人并不孤单,想一个人才孤单。

查看更多...

Tag: 静静
2007-04-18
[本日志已设置加密]

查看更多...

2007-04-14
生如夏花之灿烂,死为秋叶之静美

查看更多...

2007-04-02
     其实从上面两篇文章已经可以大体看出这个项目的思路来了,所以此篇文章不再讲述其他三个超链接的功能,接下来我们讲讲涉外功能,如预处理功能、国际化、以某种软件打开(如txt)和页面显示出的时间变化。

      为了页面可以显示中文,我们首先利用sturts的一个扩展功能,可以实现(相当于servlet中的过滤功能):
程序代码 程序代码

 <controller contentType="text/html;charset=UTF-8" locale="true" processorClass="companypj.MyProRequestProcessor" />

      struts_config中的controller标签写入这样的代码,表明在每次处理代码之前先进入MyProRequestProcessor类里面,我们看下这个类:
程序代码 程序代码

import org.apache.struts.action.RequestProcessor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.tiles.TilesRequestProcessor;

public class MyProRequestProcessor extends TilesRequestProcessor
{
protected boolean processPreprocess (HttpServletRequest request,
HttpServletResponse response)
{
try
{
request.setCharacterEncoding("UTF-8");
//other code
}
catch(Exception e){}
return true;
}
}

      因为页面jsp使用的是utf-8,所以这里也做了下utf-8的预处理。重写原来的processPreprocess()方法,这个方法在父类TilesRequestProcessor里面是一个空的方法。为了方便我们以后使用,俗称的预处理功能。


      下面我们看一下struts中的国际化配置:
程序代码 程序代码

<message-resources parameter="ApplicationResources" />

      实在不愿意说国际化,这个工作就是民工的活,简单且繁重。。pass

      下面还有两个插件,一个是tiles框架,一个validator框架,都是struts中的经典:
程序代码 程序代码
<plug-in className="org.apache.struts.tiles.TilesPlugin">
    <set-property property="definitions-config" value="/WEB-INF/tiles-congfig.xml" />
    <set-property property="definition-parser-validate" value="true"/>
  </plug-in>
  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
  </plug-in>



      细心的朋友可能发现在sidebar页面有一个小太阳或小月亮的图标,后面跟随时间,来看看那段代码的实现吧:
      在jsp页面有这样两行代码,一个是调出年月日,一个是调出图标:
程序代码 程序代码

 <%=companypj.OtherBean.getTime()%>
 <img src="<%=companypj.OtherBean.bgPhoto()%>" alt="" >

   
     下面我们查看一下OtherBean类:
程序代码 程序代码

import java.util.*;
import java.text.SimpleDateFormat;

public class OtherBean {
    public static String getTime() {

        Date now = new Date();
        SimpleDateFormat smpDateFormat =
                new SimpleDateFormat("yyyy-MM-dd");

        String buf = smpDateFormat.format(now);
        return buf;
    }

    public static String bgPhoto() {
        GregorianCalendar calendar = new GregorianCalendar();
        String bgcolor = "";
        String path1="img/time/1.gif";
        String path2="img/time/2.gif";
        int hour = calendar.get(Calendar.HOUR_OF_DAY)+8;
        if(hour>6&&hour<18)
        {
            bgcolor=path1;

            //return bgcolor;
        }
        else if(hour<=6)
        {
            bgcolor=path2;

            //return bgcolor;
        }
        else if(hour>=18)
        {
            bgcolor=path2;

            //return bgcolor;
        }
      System.out.println(hour);
      System.out.println(bgcolor);
      return bgcolor;
    }

    public static void main(String arg[]) {
        new OtherBean().bgPhoto();
    }
}

       这里就可以清楚的看到为了图片会变化的原因了。另外,因为在虚拟机JVM上面跑,用的是GMT时间,必须+8才能是北京时间。

       另外值得说一下的是,在超链接“查看员工”的时候,有一个以txt打开某员工的信息(为了方便保存档案,大多情况下是Excel,大同小异),它的处理过程是这样的:
程序代码 程序代码

<html:link page="/link4_one_loaddown.do" paramId="id" paramName="ID"><bean:message key="lable.emp.read.open"/></html:link>


      在配置文件中的代码:
程序代码 程序代码
<action input="/link4_one_view.jsp" path="/link4_one_loaddown" parameter="link4_one_loaddown" type="companypj.LoadDownAction" validate="false" >
<forward name="link4_one_success" path="/link4_one_view.jsp">
</forward>

      接着我们找到LoadDownAction:
程序代码 程序代码

import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.Action;
import java.util.Collection;
import javax.sql.*;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.apache.struts.validator.DynaValidatorForm;
import java.io.*;

public class LoadDownAction extends Action {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
       // DynaValidatorForm empDynForm = (DynaValidatorForm) form;
        javax.servlet.ServletOutputStream servletoutputstream = null;
        DataSource ds = getDataSource(request);
        Log log = LogFactory.getLog("A");
        String type = mapping.getParameter();
        if (type.equals("link4_one_loaddown")) {
            File f = null;
            FileInputStream fileinputstream = null;
            String downloadfilepath = "/WEB-INF/download/";//定义temp文件存在的目录
            String filename = "testDownload.txt";//文件名
            String path= request.getRealPath("/");//表示网站所在文件夹
            String filepathname = path + downloadfilepath;

            //写入文件完成
            EmployeeBean empbean = new EmployeeBean(ds);
            EmployeeVO emp = empbean.getEmployee(request.getParameter("id"));
            //读出文件开始
            try {
                f = new File(filepathname, filename);
                f.createNewFile();//创建文件
                LoadDownBean loadbean=new LoadDownBean();
                loadbean.writeFile(emp,f); //把人员信息和具体文件传入,写文件的具体过程

                //做读出过程
                fileinputstream = new FileInputStream(
                        filepathname+ filename);

                servletoutputstream = response.getOutputStream();
                response.reset();
                response.setHeader("Content-disposition",
                                   "attachment; filename=" + filename);
                response.setContentType("text/plain;charset=gb2312");
                int j = 0;
                int k = 0;
                byte abyte0[] = new byte[1024];
                while ((k = fileinputstream.read(abyte0)) != -1) {
                    j += k;
                    servletoutputstream.write(abyte0);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                //最后删除文件
                try {
                    servletoutputstream.close();
                    fileinputstream.close();
                    File f1 = new File(filepathname+filename);
                    if (f1.exists()) {
                        System.out.println("linnan");
                        f1.delete(); //删除File.txt文件
                    }
                } catch (Exception ex1) {
                    ex1.printStackTrace();
                }
            }
            //跳转回页完成,把原来信息再显示
            emp = empbean.getEmployee(request.getParameter("id"));
            request.setAttribute(Constants.EMP_KEY, emp);
            return mapping.findForward("link4_one_success");
        }
        return null;
    }
}

       request.getRealPath("/") 表示网站所在文件夹;
       request.getRealPath(". /") 表示本网页所在文件夹;
       request.getRealPath(". . /") 表示本网页文件夹的上层文件夹;
       上面每一部我都写了注释,方便理解,再来看下LoadDownBean,它就是做在txt里面的具体写入些什么,包括简单的排版:
程序代码 程序代码

package companypj;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import java.io.*;


public class LoadDownBean {
    Log log = LogFactory.getLog("A");



    public void writeFile(EmployeeVO emp, File f) {

            try {
                FileWriter fw = new FileWriter(f);
                BufferedWriter bw = new BufferedWriter(fw);
                byte[] line = new byte[128];
                bw.write("*****************************");
                bw.write("*****************************");
                bw.write("员工ID号:"+emp.getId());
                bw.newLine(); //断行
                //bw.write("\r\n");
                bw.write("员工姓名:"+emp.getName());
                bw.newLine();
                bw.write("*****************************");
                bw.write("*****************************");
                bw.write("性别:"+emp.getSex());
                bw.newLine();
                bw.write("年龄:"+emp.getAge());
                bw.newLine();
                bw.write("月薪:"+emp.getSalary());
                bw.newLine();
                bw.write("所在部门:"+emp.getDepartment());
                bw.newLine();
                bw.write("婚否:"+emp.getMarriage());
                bw.newLine();
                bw.write("家庭住址:"+emp.getAddress());
                bw.newLine();
                bw.write("联系电话:"+emp.getPhone());
                bw.newLine();
                bw.write("员工简历:");
                bw.write("\r\n");
                bw.write(emp.getResume());
                bw.flush(); //将数据更新至文件
                fw.close(); //关闭文件流
                bw.close();

        } catch (Exception e) {
            // out.println(e);
            e.printStackTrace();
        }

    }

}


       好了,该讲的重点,到这里都讲完了!

查看更多...

2007-04-02
      接着上次的继续说,上次说了讲的是“雇员添加”,程序步骤大致是:首页——遍历出部门列表——加入添加雇员表单——提交到存储过程——返回;但同时我忽略了一个前提:如果部门列表值为if(x.equest.("")||x==null)。那么应该给出一个error值,然后转发到“部门添加"页。但此种情况只会在程序第一次运行初始化的时候出现,而程序设计者在编写时就会在数据库中加入一些测试值,所以不会应该的使用情况。

      添加部门表单页与上篇文章说的添加添加雇员程序思路大体一致,这里就不再赘述。下面我们看一下”管理部门员工 “功能的实现,主要思想:遍历和删除。如图:



      数据库里写的东西很杂,呵呵。但我们主要关注的还是程序的实现!这个链接是link3.do,我们来看一下它在Stuts-config中的配置:
程序代码 程序代码

<action path="/link3" parameter="link3" type="companypj.Link3Action" validate="false" >
<forward name="link3_success" path="/link3.jsp">
</forward>

      这里看到,没有作任何处理,它直接转到了Link3Action。那么我们看这个Atcion是怎么写的:
程序代码 程序代码

if (type.equals("link3")) {
            log.info("return_link3..");
            DepartmentBean depbean=new DepartmentBean(ds);
            Collection DEPARTMENTS=depbean.getDepartments(); //取得所有部门信息
            request.setAttribute(Constants.DEPARTMENTS_KEY,DEPARTMENTS);//request到下一个页面
            return mapping.findForward(Constants_url.RETURN_LINK3_SUCCESS);//给sturts mapping传一个值
        }

      好了,转到getDepartments():

程序代码 程序代码

public Collection getDepartments()
    {
        log.info("提交所有部门数据集合");
        return this.getDepartmentsHelper(Constants_sql.DEPARTMENT_ALL_SQL);
    }


      这里还是看不出什么,只是借助了Constants_sql类得到一个常量,上次我没有详细介绍过这里,这次我们来看看这个常量的定义:
程序代码 程序代码

public class Constants_sql {
    public Constants_sql() {
    }
    public static final String DEPARTMENT_ADD_SQL=
"insert into department(name,description,leader,phone,address,starttime,info)values(?,?,?,?,?,?,?)";
    public static final String DEPARTMENT_ALL_SQL="select * from department where name!='无部门' order by id desc"; //这里就是我们调用的常量
    public static final String EMP_ADD_SQL=
"insert into employee (name,sex,age,salary,department,marriage,address,phone,resume) values(?,?,?,?,?,?,?,?,?)";
    public static final String EMP_ALL_SQL="select * from employee where department!='无部门' order by id desc";
    public static final String EMP_TEMP_ALL_SQL="select * from employee where department='无部门' order by id desc";
    //public static final String

}


      DEPARTMENT_ALL_SQL:把table department中所有name非'无部门'的记录取出,并降序排列。
      回到getDepartments()方法,这个方法就是为了更好的解耦合,之后它再调用getDepartmentsHelper()方法,并且传入了一个String DEPARTMENT_ALL_SQL;getDepartments()方法:
程序代码 程序代码

private Collection getDepartmentsHelper(String sql) //遍历集合 帮助方法
    {
        Collection list=new ArrayList();
        try {
            Connection conn=ds.getConnection();
            Statement stmt=conn.createStatement();
            ResultSet rs=stmt.executeQuery(sql);
            while(rs.next())
            {
                DepartmentVO departmentvo=new DepartmentVO();
               // log.info("取部门数据开始");
                departmentvo.setId(rs.getInt("id"));
                departmentvo.setName(rs.getString("name"));
                departmentvo.setDescription(rs.getString("description"));
                log.info(rs.getString("description"));
                departmentvo.setLeader(rs.getString("leader"));
                departmentvo.setPhone(rs.getString("phone"));
                departmentvo.setAddress(rs.getString("address"));
                departmentvo.setStarttime(rs.getString("starttime"));
                departmentvo.setInfo(rs.getString("info"));
                list.add(departmentvo);
               // log.info("取部门数据结束");
            }
            conn.close();
            stmt.close();
            rs.close();
        } catch (SQLException ex) {
            ex.getMessage();
        }
        return list;
    }

      返回list,而list里面就是我们要的部门集合;拿着它返回页面遍历即可;就是上面的这两句:
程序代码 程序代码

request.setAttribute(Constants.DEPARTMENTS_KEY,DEPARTMENTS);//request到下一个页面
            return mapping.findForward(Constants_url.RETURN_LINK3_SUCCESS);//给sturts mapping传一个值

      返回的时候依旧是先调用一个常量类(我发现我那时写程序真够BT的了,BT..病态)
    
程序代码 程序代码

public static final String RETURN_LINK3_SUCCESS="link3_success";
    

      把link3_success信息传给strut_config来处理,Struts这句话是用来接收它的:
程序代码 程序代码

<forward name="link3_success" path="/link3.jsp">




      好了,现在我们来看看link3.jsp的组成,Tiles配置:
<definition extends="layout-definition" name="link3-definition">
<put name="content" value="return/departmentManage.jsp"></put>
</definition>
      从这里看到,实际把权的是departmentManage.jsp页。看看它的信息:
程序代码 程序代码

<table cellpadding="0" cellspacing="5"  width="100%" >
  <tr>
    <td width="14%"><bean:message key="lable.dept.row.id"/></td>
    <td width="14%"><bean:message key="lable.dept.row.name"/></td>
    <td width="14%"><bean:message key="lable.dept.row.leader"/></td>
    <td width="14%"><bean:message key="lable.dept.row.add.emp"/></td>
    <td width="14%"><bean:message key="lable.dept.row.delete.emp"/></td>
  </tr>
  <tr>
    <td width="100%" colspan="5">
    <page:pager dz="5">
    <%int i=1; %>
    <logic:iterate id="departments" name="DEPARTMENTS" type="companypj.DepartmentVO">
    <table border="1" cellpadding="0" cellspacing="1" style="border-collapse: collapse"  width="100%" >
      <page:item nr="<%=i++%>">
      <tr>
        <td width="14%"><bean:write name="departments" property="id"/></td>
        <td width="14%"><bean:write name="departments" property="name"/></td>
        <td width="14%"><bean:write name="departments" property="leader"/></td>
        <td width="14%"><html:link page="/link3_add.do">
          <bean:message key="lable.dept.add.emp"/>
          </html:link></td>
        <td width="14%">
        <bean:define id="dep_id" name="departments" property="id">
        </bean:define>

          <html:link page="/link3_delete.do" paramId="dep_id" paramName="dep_id">
           <bean:message key="lable.dept.delete.emp"/>
          </html:link>
        </td>
      </tr>
      </page:item>
    </table>
    
    <br>
    
    </logic:iterate>
    </page:pager>
    </td>
  </tr>
</table>
<center>
<p>
<page:bt/>


      <%@taglib uri="/WEB-INF/jpager.tld" prefix="page"%>这里的pager标签是分页用的插件,我们先不去考虑它,在最后的时候我再讲关于这个项目外的一些扩展功能。
      从上面jsp我们可以看到logic遍历,还有一些很重要的东西,一个是添加员工到部门的功能,主要我的话,这个和添加新员工有一定的区别,是把一些'‘无部门’的员工加入到该部门。为什么会出现"无部门"员工呢?出于种种原因的考虑,主要是因为员工档案的重要性,所以这个项目的删除员工并非是作delete操作,还是update,把某员工的部门属性到上标记。也考虑到新员工不一定会直接配分到某部门,可能再过一段时间。再来还有一个逻辑性的问题,在删除一个部门的时候,员工必须先转移到别的部门,这么以来。删除员工的操作势必不可行。
      
程序代码 程序代码
<html:link page="/link3_add.do">
       <bean:message key="lable.dept.add.emp"/>
       </html:link>


如图:


      在这里,我们就可以看到所有”无部门“人员列表。
      jsp页面,我全部是用<bean:message标签来做的,lable.dept.add.emp对应资源文件中的uc码,也就是”添加“。link3_add.do,那我们跟着这条线走吧。。

程序代码 程序代码
<action path="/link3_add" parameter="link3_add" type="companypj.Link3Action" validate="false">


Link3Action:
程序代码 程序代码

if(type.equals("link3_add"))
        {
            log.info("link3_temp..");
            EmployeeBean empbean=new EmployeeBean(ds);
            Collection EMPSTEMP=empbean.getTempEmps(); //这里就看到了取得TEMP员工的方法
            request.setAttribute(Constants.EMPS_TEMP_KEY,EMPSTEMP);
            return mapping.findForward(Constants_url.RETURN_LINK3_ADD_SUCCESS);
        }


      看一下getTempEmps()方法,下面的一系列程序是在做找到所有没有部门的员工:
程序代码 程序代码

public Collection getTempEmps() { //获得所有无部门的员工
        return this.getEmployeesHelper(Constants_sql.EMP_TEMP_ALL_SQL);
    }

      这里值得注意的是SQL的写法EMP_TEMP_ALL_SQL:
 
程序代码 程序代码
public static final String EMP_TEMP_ALL_SQL="select * from employee where department='无部门' order by id desc";

      接着看实质的方法getEmployeesHelper:
程序代码 程序代码

private Collection getEmployeesHelper(String sql) {
        Collection list = new ArrayList();
        try {
            Connection conn = ds.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                EmployeeVO employeeVO = new EmployeeVO();
                log.info("取人员信息开始");
                employeeVO.setId(rs.getInt("id"));
                employeeVO.setName(rs.getString("name"));
                employeeVO.setSex(rs.getString("sex"));
                employeeVO.setAge(rs.getInt("age"));
                employeeVO.setSalary(rs.getString("salary"));
                employeeVO.setDepartment(rs.getString("department"));
                employeeVO.setMarriage(rs.getString("marriage"));
                employeeVO.setAddress(rs.getString("address"));
                employeeVO.setPhone(rs.getString("phone"));
                employeeVO.setResume(rs.getString("resume"));
                list.add(employeeVO);
                log.info("取人员信息结束");
            }
            conn.close();
            stmt.close();
            rs.close();
        } catch (SQLException ex) {
        }
        return list;
    }


      OK,已经取得list集合,返回,并遍历显示到页面即可!


     下面这个是删除部门中员工的链接:
程序代码 程序代码

<bean:define id="dep_id" name="departments" property="id">
        </bean:define>
          <html:link page="/link3_delete.do" paramId="dep_id" paramName="dep_id">
           <bean:message key="lable.dept.delete.emp"/>
      
      先要确定某一部门的id,得到id后,相应的去数据库中找到集合。如图:

      在Action中的取得方法:
程序代码 程序代码

if(type.equals("link3_delete"))
        {
            log.info("delete ready..");
            EmployeeBean empbean=new EmployeeBean(ds);
            Collection DEPTEMPS=empbean.getDepartemtDemployees(request.getParameter("dep_id"));
            request.getSession().setAttribute("DEP_ID",request.getParameter("dep_id"));
            //保存部门ID号,以便删除之后可以返回页
            request.setAttribute(Constants.DEPT_EMPS_KEY,DEPTEMPS);
            return mapping.findForward(Constants_url.RETURN_LINK3_Delete_READY);
        }


     最先调用的方法getDepartemtDemployees():
程序代码 程序代码

public Collection getDepartemtDemployees(String dep_id) { //指定部门中的员工
        log.info("该部门是:" + dep_id);
        String sql_dep =
                "select * from employee where department=(select name from department where id=" +
                dep_id + ")";
        log.info(sql_dep);
        return this.getEmployeesHelper(sql_dep);
    }

       这里的SQL挺有意思,带有子查询,当然写法很多,不止这一种。
       接着转入帮助方法getEmployeesHelper();帮助方法都是一样,上面已经写出,不再重复。不过写到现在,可以明显看出,实际操作的方法并不多,都是经过bean前的一个方法中转——解耦。
       
      好了,接下来说一下删除部门中的某一个成员:
     上面说到把某部门的所有成员遍历到页面显示,返回的集合是:
     
程序代码 程序代码
public static final String DEPT_EMPS_KEY="DEPTEMPS";

     下面到对应的jsp页面来看下:
程序代码 程序代码

<logic:iterate id="dept_emps" name="DEPTEMPS">
    <page:item nr="<%=i++%>">
    <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" width="100%">
      <tr>
        <td width="33%"><bean:write name="dept_emps" property="id"/>��</td>
        <td width="33%"><bean:write name="dept_emps" property="name"/></td>
        <td width="34%">
          <bean:define id="ID" name="dept_emps" property="id"/>
          <html:link page="/link3_deleted.do" paramId="id" paramName="ID">
          <bean:message key="lable.delete.emp.this"/>
          </html:link>
        </td>
      </tr>

    </table>
    <br>
    </page:item>
    </logic:iterate>

       这里可以看出,name已经接收了返回的集合,并做了遍历,而删除按钮lable.delete.emp.this做了一个超链,带有传参:传的是员工的id号,我们下面看看后台它的运作过程:
程序代码 程序代码

if(type.equals("link3_deleted"))
        {
            EmployeeBean empbean=new EmployeeBean(ds);
            empbean.deleteEmployee(request.getParameter("id"));//删除某个员工
            Collection DEPTEMPS=empbean.getDepartemtDemployees(String.valueOf(request.getSession().getAttribute("DEP_ID")));//再取部门人员
            log.info("转发回页面");
            request.setAttribute(Constants.DEPT_EMPS_KEY,DEPTEMPS);
            return mapping.findForward(Constants_url.RETURN_LINK3_DeleteD_SUCCESS);
        }
        return null;
    }

      中间层调用了两个方法,一个是删除员工,为了删除后保持页面的一致性,再重新遍历一下该部门的所有员工:
      而部门ID已经存入了session中,为DEP_ID。先看deleteEmployee():
程序代码 程序代码

 public void deleteEmployee(String id) {
        try {
            log.info("1");
            Connection conn = ds.getConnection();
            Statement stmt = conn.createStatement();
            String sql_update = "update employee set department='无部门' where id=" +
                                id + "";
            log.info(sql_update);
            stmt.executeUpdate(sql_update);
            log.info("2");
            conn.close();
            stmt.close();
        } catch (SQLException ex) {
        }

       删除方法够简单的,传进id,update把dep字段改成"无部门"就OK。
       重新遍历出员工和上一个超级链接做的是一样的工作,然后还是返回刚才的页面,可以看见新的数据。

查看更多...

2007-04-02
一直感觉PJBlog2的标签云集通过字体的大小来区别标签使用的频繁程度的,不是很美观,感觉有点乱,今天在”阿不“那边发现一中以固定字体,通过标签排列的先后顺序来说明使用的频繁程度,并在右侧标明使用该标签的日志数的方法,现转过来用。
  
(1) 在tag.asp中找到以下代码:

<a href="default.asp?tag=<%=Server.URLEncode(log_Tag(1))%>" title="共包含 <%=log_Tag(2)%> 篇日志"><span style="font-size:<%=getTagSize(log_Tag(2))%>px"><%=log_Tag(1)%></span></a>

将其改为:

<a href="default.asp?tag=<%=Server.URLEncode(log_Tag(1))%>" style="font-size:12px;line-height:250%" title="共包含 <%=log_Tag(2)%> 篇日志"><%=log_Tag(1)%><span style="font-size:11px;color:#ccc">[<%=log_Tag(2)%>]</span></a>


(2) 在common文件夹下找到cache.asp,在“写入标签Tag缓存”中找到

Select tag_id,tag_name,tag_count FROM blog_tag

将其改为

Select tag_id,tag_name,tag_count FROM blog_tag orDER BY tag_count DESC,tag_id ASC

(3) 重建数据缓存。

查看更多...

2007-04-02
       很长一段时间来,确切的说是两个多月,从年前开始就没有再过多的写程序。主要精力都投入在这个网站上面了,对于Java编程很少去碰。只是偶尔翻翻《核心技术》,不过是蜻蜓点水。前天本想编写一个米店(Domain)的管理系统为自己用,发现编的很吃力。本觉得瞒简单的东西,突然看来如此复杂。编了两天,决定不再写了。去温习一下从前写过的代码。我觉得,这样的话对我的帮助会很大。
       下面介绍我去年11月编写的一套人事部门管理系统,项目用时一周(需求分析2天,美工设计2天,其余时间为代码实现)。如图:



       需求文档的地址:http://www.new321.com/blog/attachments/month_0703/person_xuqiu.htm

       从需求文档可以看出,这个项目的布局是由Tiles框架完成的。我们要作的是首先设计出一个完成的框架布局结构页layout.jsp.然后在其中定义其他页面分布位置。此项目共有四部分组成:siderbar.jsp用来作左侧列表选择,header.jsp用来放置logo,footer.jsp用于作者声明,另外一个至关重要的部分是可变的——随着siderbar.jsp的超链接选择而变。有了这种思想以后就可以写tiles-config了:
程序代码 程序代码

<definition name="layout-definition" path="/layout.jsp">
<put name="sidebar" value="sidebar.jsp"></put>
<put name="header" value="header.jsp"></put>
<put name="content"></put>
<put name="footer" value="footer.jsp"></put>
</definition>

       从上面可以看出内容是可变的,这段代码是接下来所有代码的父级代码,用于作继承之用。
       接下来作一个内容页:
程序代码 程序代码

<definition extends="layout-definition" name="index-definition">
<put name="content" value="indexContent.jsp"></put>
</definition>

       从name大致可以看出这个是为了index首页来使用的。而在index.jsp页面写入代码
程序代码 程序代码
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<tiles:insert definition="index-definition">
</tiles:insert>

       这样即可,其实我们最关心的是列表(siderbar)及其内容(contents)部分。它们之间的互动性是我们使用tiles框架的原因。

       列表的第一个超链接是"添加员工":
程序代码 程序代码

<html:link page="/link1.do"><font color="#000000" style="text-decoration: none"><bean:message key="link.add.emp"/></font></html:link>

       link.add.emp分别对应两份bundle文件——这里使用了中英文国际化。国际化是一种反复的简单劳动,这里就不多作阐述了。我们关心的是link1.do的走向,看sturts-config:
程序代码 程序代码

<action path="/link1" parameter="link1" type="companypj.AddEmployeeAction" validate="false">
<forward name="link1_success" path="/link1.jsp">
</forward>

进入AddEmployeeAction

图1-1,AddEmployeeAction全部代码:
程序代码 程序代码

public class AddEmployeeAction extends Action {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) {
         DynaValidatorForm empDynForm=(DynaValidatorForm)form;
         Log log=LogFactory.getLog("A");
         String type=mapping.getParameter();
         DataSource ds=getDataSource(request);
         if(type.equals("link1"))
         {
             log.info("return_link1..");
             DepartmentBean departmentbean=new DepartmentBean(ds);
             Collection onlydep=departmentbean.getOnlyDepartments();//这里转入部门类,取出部门集合
             request.getSession().setAttribute(Constants.ONLYDEPARTMENTS_KEY,onlydep);//集合保存,并传入下一页面
             return mapping.findForward(Constants_url.RETURN_LINK1_SUCCESS);
         }
         if(type.equals("link_addemp"))
         {
            EmployeeBean empbean=new EmployeeBean(ds);
            //String address=empDynForm.get("address").toString();
            empbean.addEmployee(empDynForm);
            return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
         }
         return null;
    }
}


再来看下面的getOnlyDepartments()方法,用于取出部门的方法
程序代码 程序代码

    public Collection getOnlyDepartments()     //只找出所有部门的集合,这个方法多此一举,都是动态数据即时更新的,所有没必要用它,当写着玩了~
    {
        Collection list=new ArrayList();
        Collection departments = this.getDepartments();//跳转
        Iterator i = departments.iterator();
        while(i.hasNext()) {
          DepartmentVO Onlydepartments=(DepartmentVO) i.next();
          log.info("Onlydep:"+Onlydepartments.getName());
          Onlydepartments.setName(Onlydepartments.getName()); //筛选后重新放入
          list.add(Onlydepartments);
        }
        return list;
    }

       。。。不看不知道,当初我还写了不少没用的解释,哈哈!注意这里有个跳转,跳转到另一个方法,接着看:
程序代码 程序代码

public Collection getDepartments()
    {
        log.info("提交所有部门数据集合");
        return this.getDepartmentsHelper(Constants_sql.DEPARTMENT_ALL_SQL);
    }

       这个方法也只是为了层次清晰和重用性,接着把一条SQL丢给下面赶事实的方法getDepartmentsHelper():
程序代码 程序代码

private Collection getDepartmentsHelper(String sql) //遍历集合 帮助方法
    {
        Collection list=new ArrayList();
        try {
            Connection conn=ds.getConnection();
            Statement stmt=conn.createStatement();
            ResultSet rs=stmt.executeQuery(sql);
            while(rs.next())
            {
                DepartmentVO departmentvo=new DepartmentVO();
                log.info("取部门数据开始");
                departmentvo.setId(rs.getInt("id"));
                departmentvo.setName(rs.getString("name"));
                departmentvo.setDescription(rs.getString("description"));
                log.info(rs.getString("description"));
                departmentvo.setLeader(rs.getString("leader"));
                departmentvo.setPhone(rs.getString("phone"));
                departmentvo.setAddress(rs.getString("address"));
                departmentvo.setStarttime(rs.getString("starttime"));
                departmentvo.setInfo(rs.getString("info"));
                list.add(departmentvo);
                log.info("取部门数据结束");
            }
            conn.close();
            stmt.close();
            rs.close();
        } catch (SQLException ex) {
            ex.getMessage();
        }
        return list;
    }

       OK,拿到了所有部门的所有信息;回到上面那句:
程序代码 程序代码
Onlydepartments.setName(Onlydepartments.getName()); //筛选后重新放入

       看来当时我是想作一个优化,减轻页面的负担,而在后台多了下些功夫,现在想来大可不必,不如直接另写一个找差name的SQL语句。。我当时大脑在想些什么哩。。
       回到图1-1中的
程序代码 程序代码
request.getSession().setAttribute(Constants.ONLYDEPARTMENTS_KEY,onlydep);//集合保存,并传入下一页面

存入session中,返回到添加员工表单;
程序代码 程序代码
<forward name="link1_success" path="/link1.jsp">



箭头所指,就是我们刚才作遍历出来的部门集合位置。

       回到了link1.jsp,而在tiles中实际表单位置是CreateEmployee.jsp:
程序代码 程序代码

<definition extends="layout-definition" name="link1-definition">
<put name="content" value="return/CreateEmployee.jsp"></put>
</definition>

       下面找CreateEmployee.jsp代码,代码太多,我把主要的写上,至于其他部分感兴趣可以去下载我整个项目来看,我提供了下载。
       这里是拿到部门集合在表单上的遍历:
程序代码 程序代码

<html:select property="department">
              <logic:iterate id="onlydep" name="ONLYDEPARTMENTS" type="companypj.DepartmentVO" scope="session">
                <option value="<bean:write name="onlydep" property="name"/>">
                  <bean:write name="onlydep" property="name"/>
                </option>
              </logic:iterate>
            </html:select>

       name拿到了集合,type转型成VO以作分类遍历,scope指定去session中拿。
       再来看看表单的提交
程序代码 程序代码
<html:form action="/link_addemp.do" method="POST">

       在struts-config中找到:
程序代码 程序代码

<action input="/link1.jsp" name="EmpForm" path="/link_addemp" parameter="link_addemp" 
scope="request" type="companypj.AddEmployeeAction" validate="true" >

       看到还是转入AddEmployeeAction,图1-1。但是validate="true",表明先要进行表单验证,那么我们就去看一下配置文件validation:
程序代码 程序代码

<formset>
<form name="EmpForm">
<field property="name" depends="required">
<arg0 key="label.emp.name"/>
</field>
<field property="age" depends="required">
<arg0 key="label.emp.age"/>
</field>
<field property="salary" depends="required">
<arg0 key="label.emp.salary"/>
</field>
</form>
</formset>

       简单的让人觉得可怜哈,都不为空就行!
       PS:这里是作得动态表单,而下一个超链接的部门添加是用了静态表单。别的就没有太多差别,思想都一样!
       如果验证通过,转入Action中处理,看代码:
程序代码 程序代码

if(type.equals("link_addemp"))
         {
            EmployeeBean empbean=new EmployeeBean(ds);
            //String address=empDynForm.get("address").toString();
            empbean.addEmployee(empDynForm);
            return mapping.findForward(Constants_url.RETURN_ADD_EMP_READY);
         }

        addEmployee方法把form接收过去:
程序代码 程序代码

public void addEmployee(DynaValidatorForm empDynForm) {
        EmployeeVO employeeVO = this.NynaIntoEmp(empDynForm);
        String strSQL="{call demo_empadd(?,?,?,?,?,?,?,?,?)}";//存储过程
        this.executeEmpHelper(employeeVO, strSQL);
    }

        这里我作的是一个存储过程:
程序代码 程序代码

Create PROCEDURE demo_empadd 
@inparam1 varchar(10),@inparam2 varchar(20),@inparam3 int,
@inparam4 varchar(10),@inparam5 varchar(20),@inparam6 varchar(10),
@inparam7 varchar(20),
@inparam8 varchar(10),@inparam9 varchar(40)
 AS insert into employee(name,sex,age,salary,department,marriage,address,phone,resume)values
 (@inparam1,@inparam2,@inparam3,@inparam4,@inparam5,@inparam6,@inparam7,@inparam8,@inparam9)
GO

       接着再转到executeEmpHelper()方法来作实际工作,这时传入了一个VO,和一个存储过程的指令:
程序代码 程序代码

private void executeEmpHelper(EmployeeVO employeeVO, String sql) { //帮助方法
        try {
            Connection conn = ds.getConnection();
            java.sql.CallableStatement pstm=conn.prepareCall(sql);
            //PreparedStatement pstm = conn.prepareStatement(sql);
            log.info("雇员信息开始加入");
            pstm.setString(1, employeeVO.getName());
            pstm.setString(2, employeeVO.getSex());
            pstm.setInt(3, employeeVO.getAge());
            pstm.setString(4, employeeVO.getSalary());
            pstm.setString(5, employeeVO.getDepartment());
            pstm.setString(6, employeeVO.getMarriage());
            pstm.setString(7, employeeVO.getAddress());
            pstm.setString(8, employeeVO.getPhone());
           // log.info("1");
            pstm.setString(9, employeeVO.getResume());
           // log.info("2");
            pstm.executeUpdate();
            log.info("雇员信息加入结束");
        } catch (SQLException ex) {
        }
    }

       OK,从图1-1中的Action传回一个信号,config接收到
程序代码 程序代码
<forward name="link_addemp_ready" path="/link1_add_success.jsp">

       添加完成!

查看更多...

2007-03-15

简单使用批处理也可达到同样效果.

bat:

1.cd ..自己class下的路径

2.set classpath=%CLASSPATH%;.

3.java myclass

查看更多...

2007-03-15

1.继承   ActionForm   的类的所有字段必须为   String   型   
2.由于   Date   型转换为   String   需设置   DateFormat   ,所以你   Bean   里的日期字段最好用   String     
这样就不会出现类型转换错误了。

PS:其实我以前还真没遇到过这样的错误,呵呵。不管怎样,转换之后错误还真就解决了。。。

查看更多...

Tag: Struts.
2007-03-09
import java.util.*;

public class CalendarTest

   public static void main(String[] args)
   { 
      GregorianCalendar d = new GregorianCalendar();//定义d作为当前日期
      int today = d.get(Calendar.DAY_OF_MONTH);
      int month = d.get(Calendar.MONTH);
      d.set(Calendar.DAY_OF_MONTH, 1);// 设置当前日期d开始月份
      int weekday = d.get(Calendar.DAY_OF_WEEK);
      System.out.println("Sun Mon Tue Wed Thu Fri Sat");//打印日历头
      for (int i = Calendar.SUNDAY; i < weekday; i++ )//缩排日历
         System.out.print("    ");
      do
      { 
         int day = d.get(Calendar.DAY_OF_MONTH);// 打印天
         if (day < 10) System.out.print(" ");
         System.out.print(day);
         if (day == today)// 做当前天的标记 *
            System.out.print("* ");
         else
            System.out.print("  ");
         if (weekday == Calendar.SATURDAY)// 逢星期六开始一个新的行
            System.out.println();
         d.add(Calendar.DAY_OF_MONTH, 1);//增加 d 到下一天
         weekday = d.get(Calendar.DAY_OF_WEEK);
      }
      while (d.get(Calendar.MONTH) == month);
      if (weekday != Calendar.SUNDAY) // 当d 是下个月的第一天退出循环
         System.out.println();
   }
}

查看更多...

分页共44页 1 2 3 4 5 6 7 8 9 10 下一页 最后一页