方枪枪的java世界

不要因为风雨飘落就停止了你的脚步,真正的得失就在你的心中。 做喜欢做的事,不轻言放弃!

#

ChatClient

package com.tianhe.frm.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 *
 *<br>
 * 客户端的实现效果 <br>
 *<br>
 * 1.登录服务器,如果服务器端口号和IP号输入的字符都是"0"则,客户端连接到默认的服务器 <br>
 *<br>
 * 2.输入聊天昵称 <br>
 *<br>
 * 3.输入"-quit"会自动退出聊天 <br>
 *<br>
 * 4.输入"-getList"会得到在线用户的名称 <br>
 *<br>
 * 5.输入"-to <用户名称> <聊天信息>"会把信息发送到指定的用户处,他人看不到 <br>
 *<br>
 * 6.输入"-help"会得到客户端相应操作帮助 <br>
 *<br>
 * 6.直接输入内容则会将内容发送到所有在线的用户处 <br>
 *<br>
 *<br>
 *<br>
 *<br>
 * 客户端的类与方法 <br>
 *<br>
 * 1.建立连接方法:connectServer(String ip,int serverPort) <br>
 *<br>
 * 2.断开连接方法:disconnectServer() <br>
 *<br>
 * 2.发送消息方法:sendMes(String mes) <br>
 *<br>
 * 3.接受消息方法:getMes() <br>
 *<br>
 * 4.接受一次消息:getMesOnce() <br>
 *<br>
 * 5.获得用户列表:getList(String mes) <br>
 *<br>
 * 6.测试连接方法:testConnect(String ip,int serverPort) <br>
 *<br>
 * 7.检查用户名 :checkNickName(String nickName) <br>
 *<br>
 * 8.获得帮助列表:helpList(); <br>
 *<br>
 * 9.各项内容的输入在main方法中进行 <br>
 *<br>
 *<br>
 *<br>
 *<br>
 * 重点注意的地方 <br>
 *<br>
 * 由于客户端无法知道服务器何时转发数据,所以客户端需要一直不停地监听消息,为了不影响其他的方法,如发送数据,这里用到多线程,即为接受数据单独建立一个线程,以防止影响其他方法的正常工作。
 *
 */
public class ChatClient implements Runnable
{
    private String serverIp = "localhost";
   
    private int serverPort = 9999;
   
    private InetAddress serverAddr = null;
   
    // 客户端
    private DatagramSocket ds = null;
   
    // 发送的数据报
    private DatagramPacket dp = null;
   
    // 用来测试是否能够连接成功或者用户名是否正确
    // 在testConnect和checkNickName中会用到.
    // 并穿插在sendMes方法中
    private boolean test = true;
   
    /**
     * 建立连接
     *
     * @param ip 服务器IP号
     * @param serverPort 服务器Port
     */
    public boolean initServer(InetAddress serverAddr, int serverPort)
    {
        this.serverAddr = serverAddr;
        this.serverPort = serverPort;
       
        try
        {
            ds = new DatagramSocket();
        }
        catch (SocketException s)
        {
            System.out.println("The Connection of server is error.");
            return false;
        }
       
        return true;
    }
   
    /**
     * 断开连接
     */
    public void disconnectServer()
    {
        // 当客户端断开连接之前,客户端会向服务器端发送一个信息,
        // 以便告诉服务器该客户下线
        this.sendMes("-quit");
        if (ds != null)
            ds.close();
       
    }
   
    /**
     * 发送消息
     *
     * @param mes
     */
    public void sendMes(String mes)
    {
        byte[] buf = mes.getBytes();
        dp = new DatagramPacket(buf, buf.length, serverAddr, serverPort);
        // 当建立发送时,测试正常
        test = true;
        try
        {
            ds.send(dp);
        }
        catch (NullPointerException n)
        {
            // 如果无法得到要发送的消息,测试终止
            test = false;
            System.out.println("The nullity of the address of connection");
        }
        catch (IOException s)
        {
            // 如果无法发送消息至服务器,测试终止
            test = false;
            System.out.println("There is a problem to send message.");
        }
        finally
        {
        }
    }
   
    /**
     * 得到数据
     */
    public void getMes()
    {
        byte[] buf = new byte[1024];
        DatagramPacket getDatas = new DatagramPacket(buf, buf.length);
        String mes = null;
        try
        {
            while (true)
            {
                ds.receive(getDatas);
                mes = new String(buf, 0, getDatas.getLength());
                // 如果服务器发送的消息中的头片段有-getList
                // 表明客户端获得在线用户列表,调用getList方法解析
                if (mes.indexOf("-getList") == 0)
                    this.getList(mes);
                else
                    System.out.println(mes);
            }
        }
        catch (IOException i)
        {
            System.out.println("Fail in receving message");
        }
    }
   
    /**
     * 得到一次数据
     *
     */
    public String getMesOnce()
    {
        byte[] buf = new byte[1024];
        DatagramPacket getDatas = new DatagramPacket(buf, buf.length);
        String mes = null;
        try
        {
            ds.receive(getDatas);
            mes = new String(buf, 0, getDatas.getLength());
        }
        catch (Exception e)
        {
            System.out.println("!-Can not receive the message!");
        }
        finally
        {
        }
        return mes;
    }
   
    /**
     * 显示在线用户列表
     *
     * @param mes
     */
    private void getList(String mes)
    {
        String[] list = mes.split(",");
        System.out.println("在线用户:\n-------------");
        for (int i = 1; i < list.length; i++)
        {
            System.out.println("    * " + list[i]);
        }
        System.out.println("-------------");
    }
   
    /**
     * 判断用户名输入是否正确
     */
    private boolean checkNickName(String nickName)
    {
        test = true;
        String mes = null;
        // 判断昵称是否符合约定
        for (int i = 0; i < nickName.length(); i++)
        {
            char temp = nickName.charAt(i);
            // 如果不符合,则终止测试
            if (!Character.isLetterOrDigit(temp))
            {
                test = false;
                break;
            }
        }
        // 如果通过约定,则试图向服务器发送昵称,进行判断
        if (test)
        {
            this.sendMes("-nick " + nickName);
            mes = this.getMesOnce();
            // 如果服务器返回"-nick"标识
            // 说明测试昵称失败,终止测试
            if (mes.startsWith("-nick"))
            {
                test = false;
            }
        }
       
        System.out.println(mes);
        return test;
    }
   
    /**
     * 得到帮助列表
     *
     */
    public void helpList()
    {
        System.out.println("重要说明:如果已经成功连接,只要输入内容,所有在线用户都能看到您的发言。" + "\n" + "-help" + "         获取客户端相应操作的帮助" + "\n"
                + "-test" + "         测试与服务器的连接,如果已经服务器连接,请不要选用此项" + "\n" + "-getList" + "    得到在线用户的列表" + "\n"
                + "-to <name> <message>" + "\n" + "                    将消息发送到特定的在线用户处" + "\n" + "-quit"
                + "         断开连接,退出聊天室" + "\n");
    }
   
    /**
     * 线程部分
     */
    public void run()
    {
        getMes();
    }
   
    /**
     * 各项内容的操作器
     */
    public static void main(String[] args)
    {
        ChatClient cc = new ChatClient();
       
        // serverAddr && serverPort
        String serverIp = "localhost";
        int serverPort = 9999;
        InetAddress serverAddr = null;
       
        if (args != null && args.length > 0)
        {
            int i = 0;
            while (i < args.length)
            {
                // serverAddr
                if (args[i].equalsIgnoreCase("-ServerAddr"))
                {
                    i = i + 1;
                    serverIp = args[i];
                    continue;
                }
               
                // serverPort
                int ti = 9999;
                if (args[i].equalsIgnoreCase("-ServerPort"))
                {
                    i = i + 1;
                    ti = Integer.parseInt(args[i]);
                    if (ti > 0)
                    {
                        serverPort = ti;
                    }
                    i = i + 1;
                    continue;
                }
            }
        }
       
        try
        {
            serverAddr = InetAddress.getByName(serverIp);
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
            System.exit(-1);
        }
       
        System.out.println("欢迎登录Lexiaofei聊天室!");
        Scanner input = new Scanner(System.in);
       
        // 连接服务器
        cc.initServer(serverAddr, serverPort);
       
        // 输入昵称
        boolean goon = true;
        while (goon)
        {
            // 第三步:输入昵称
            System.out.println("3.请输入您登录后显示的昵称(只能输入中文、英文字母及数字):");
            String nick = input.next();
            boolean judge = cc.checkNickName(nick);
            // 判断昵称是否输入正确
            if (judge)
                goon = false;
            else
                System.out.println("!-您输入的用户名不符合条件,请重新输入!");
        }
       
        // 开始运行接收数据
        new Thread(cc).start();
        // 聊天
        String mes = null;
        System.out.println("!-您成功进入聊天室!");
       
        while (!(mes = input.nextLine()).equalsIgnoreCase("-quit"))
        {
            // 如果输入"-test"命令,开始测试
            if (mes.trim().equalsIgnoreCase("-getList"))
            {
                cc.sendMes(mes);
                // -nick 设置昵称
            }
            else if (mes.equalsIgnoreCase("-help"))
            {
                cc.helpList();
                // 如果输入的是空字符,则不发送
            }
            else
            {
                if (!mes.equals(""))
                {
                    cc.sendMes(mes);
                }
            }
        }
       
        // 退出
        input.close();
        cc.disconnectServer();
       
    }
   
    /**
     * 错误提示标记
     *
     * @param str
     */
    public static void errorTip(String str)
    {
        System.out.println("-----------------\n" + str + "\n-----------------");
    }
}

posted @ 2013-12-16 21:13 做强大的自己 阅读(202) | 评论 (0)编辑 收藏

ChatServer

package com.tianhe.frm.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Scanner;

/**
 *
 *<br>
 * 服务器的实现效果: <br>
 *<br>
 * 1.输入-help得到所有有关服务器操作的命令 <br>
 *<br>
 * 2.输入-run进入服务器各项内容初始化 <br>
 *<br>
 * 3.输入-stop断开服务器 <br>
 *<br>
 * 4.输入-quit断开服务器,并退出操作 <br>
 *<br>
 * 5.服务器创建成功后,会通过单独的线程运行监听客户端信息(listenLink) <br>
 *<br>
 * 6.服务器接收到数据后,会将数据移交至数据分析器(analyseMes)处理 <br>
 *<br>
 * 7.当用户确定连接并确定昵称后,服务器将该用户的地址及姓名存储在infoMemory中。 <br>
 *<br>
 *<br>
 *<br>
 *<br>
 * 服务器的类与方法: <br>
 *<br>
 * 1.测试服务器创建:testServer(String ip,int serverPort) <br>
 *<br>
 * 2.初始化服务器 :initServer(String ip,int serverPort) <br>
 *<br>
 * 3.确定IP与Port :fixServerLink(String ip,int serverPort) <br>
 *<br>
 * 4.信息监听器 :listenLink() <br>
 *<br>
 * 5.数据分析器 :analyseMes(String mes) <br>
 *<br>
 * 6.获取地址用户名:getConsumerName(SocketAddress sa) <br>
 *<br>
 * 7.数据转发器 :transforMes(String mes) <br>
 *<br>
 * 8.数据单项转发器:transforMesSingle(SocketAddress adr,String mes) <br>
 *<br>
 * 9.停止服务器 :cutServer() <br>
 *<br>
 * 10.获得帮助列表 :helpList() <br>
 *<br>
 * 11.错误提示方法 :errorTip(String str) <br>
 *<br>
 * 12.在主函数中进行相应操作 <br>
 *<br>
 *<br>
 * 重点注意的地方: <br>
 *<br>
 * 与客户端相仿,为了顺利监听信息,需要另一个线程运行信息监听器
 *
 */
public class ChatServer implements Runnable
{
    private DatagramSocket ds = null;
   
    private DatagramPacket dp = null;
   
    private String serverIp = "localhost";
   
    private int serverPort = 9999;
   
    private InetAddress serverAddr = null;
   
   
    // 开始运行监听的变量
    private boolean beStart = false;
   
    // 信息存储器
    private Hashtable<String, SocketAddress> userCache = new Hashtable<String, SocketAddress>();
   
    /**
     * 服务器初始化
     *
     * @param ip
     * @param serverPort
     */
    public boolean initServer(InetAddress serverAddr, int serverPort)
    {
        this.serverAddr = serverAddr;
        this.serverPort = serverPort;
       
        try
        {
            ds = new DatagramSocket(serverPort, serverAddr);
            System.out.println("!-The Server Initialization Success!");
            // 可以开始运行变量
            beStart = true;
        }
        catch (SocketException s)
        {
            // 如果出现异常,则服务器测试不通过
            errorTip("!-The Server Initialization Fail!--new DatagramSocket(" + serverPort + ", " + serverAddr + ")");
            return false;
        }
       
        return true;
    }
   
    /**
     * 监听信息
     *
     */
    public void listenLink()
    {
        byte[] buf = new byte[1024];
        String mes = null;
        try
        {
            dp = new DatagramPacket(buf, buf.length);
            System.out.println("!-The Server starts listenning to message.");
            while (beStart)
            {
                ds.receive(dp);
                mes = new String(buf, 0, dp.getLength());
                // 将获取的数据传递至数据分析器
                this.analyseMes(mes);
            }
        }
        catch (IOException e)
        {
            errorTip("!-The Server Can not receive message");
        }
    }
   
    /**
     * 数据分析器,给予相应处理
     *
     * @param mes
     */
    private void analyseMes(String mes)
    {
        // 获取当前客户端的地址:
        SocketAddress adr = dp.getSocketAddress();
       
        // -test:进行服务器与客户端的连接测试
        // 若成功,则将该客户端发送成功消息
        if (mes.trim().equalsIgnoreCase("-test"))
        {
            transforMesSingle(adr, "-test: !-From Server:Succeed in Testing.");
        }
       
        // -quit:接受客户端退出信息
        // 将该用户的退出信息转发至所有在线成员
        else if (mes.trim().equalsIgnoreCase("-quit"))
        {
            String name = this.getConsumerName(adr);
            System.out.println(name + "//" + adr + " quit! ");
            transforMes("* " + name + "退出聊天室");
            userCache.remove(name);
        }
       
        // -getList:接受客户端获取列表的请求
        // 将所有用户连接为字符串的形式,如:"-getList,用户1,用户2...用户n"
        else if (mes.trim().equals("-getList"))
        {
            StringBuffer list = new StringBuffer();
            list.append("-getList,");
            Enumeration<String> names = userCache.keys();
            while (names.hasMoreElements())
            {
                list.append(names.nextElement() + ",");
            }
            transforMesSingle(dp.getSocketAddress(), list.toString());
        }
       
        // -to:接受客户端请求,将信息转发给相应客户
        // 如果目标客户不存在,则向请求客户发送相应消息
        else if (mes.indexOf("-to ") != -1 && mes.startsWith("-to "))
        {
            String main = mes.substring("-to ".length(), mes.length());
            String toName = main.substring(0, main.indexOf(" "));
            String name = this.getConsumerName(adr);
            String con = name + " say to you :" + main.substring(toName.length() + 1, main.length());
            if (!userCache.containsKey(toName))
                transforMesSingle(adr, "!-The message can not be recevie by whom you send for,please check out.");
            else
                transforMesSingle(userCache.get(toName), con);
        }
       
        // -nick:接受客户端登录请求
        // 如果输入的匿名不存在,则登记该用户与infoMemory
        // 如果存在则返回相应提示
        else if (mes.indexOf("-nick ") != -1 && mes.startsWith("-nick "))
        {
            String nickName = mes.substring("-nick ".length(), mes.length());
            if (userCache.containsKey(nickName))
                transforMesSingle(adr, "-nick: !-The nickname you post is already exist,please try others.");
            else
            {
                userCache.put(nickName, adr);
                transforMes("Welcome " + nickName + " to Sunspot Chat!");
                System.out.println(nickName + "//" + adr.toString() + " succeed in lanuching.");
            }
        }
       
        // 一般消息将会转发至所有用户
        else
        {
            String name = this.getConsumerName(adr);
            transforMes(name + ": " + mes);
        }
    }
   
    /**
     * 通过地址得到用户的昵称 由于Hashtable无法通过Value获取Key,所有专门写该方法
     *
     * @param sa
     * @return
     */
    private String getConsumerName(SocketAddress sa)
    {
        Enumeration<String> names = userCache.keys();
        String name = null;
        while (names.hasMoreElements())
        {
            String temp = names.nextElement();
            SocketAddress adrs = userCache.get(temp);
            // 进行比较
            if (sa.equals(adrs))
            {
                name = temp;
                break;
            }
        }
        return name;
    }
   
    /**
     * 向所有的用户发送数据
     *
     * @param mes
     */
    public void transforMes(String mes)
    {
        byte[] buf = mes.getBytes();
        DatagramPacket sendDatas = null;
        Enumeration<SocketAddress> all = userCache.elements();
        try
        {
            while (all.hasMoreElements())
            {
                sendDatas = new DatagramPacket(buf, buf.length, all.nextElement());
                ds.send(sendDatas);
            }
        }
        catch (SocketException s)
        {
            errorTip("!-The feedback address is error!");
        }
        catch (IOException i)
        {
            errorTip("!-Can not send message!");
        }
    }
   
    /**
     * 向单个用户发送数据
     *
     * @param adr
     * @param mes
     */
    public void transforMesSingle(SocketAddress adr, String mes)
    {
        byte[] buf = mes.getBytes();
        try
        {
            DatagramPacket sendDatas = new DatagramPacket(buf, buf.length, adr);
            ds.send(sendDatas);
        }
        catch (SocketException s)
        {
            errorTip("!-The feedback address is error!");
        }
        catch (IOException i)
        {
            errorTip("!-Can not send message!");
        }
    }
   
    /**
     * 断开连接
     *
     */
    public void cutServer()
    {
        beStart = false;
        if (ds != null)
            ds.close();
        System.out.println("!-The ds is done.");
    }
   
    public void helpList()
    {
        System.out.println("-help" + "    获取服务器相应操作的帮助" + "\n" + "-run " + "    运行服务器,并同时建立信息监听" + "\n" + "-stop"
                + "    停止服务器" + "\n" + "-quit" + "    停止服务器,并退出命令" + "\n");
    }
   
    /**
     * 线程
     */
    public void run()
    {
        listenLink();
    }
   
    /**
     * 主要操作
     *
     * @param args
     */
    public static void main(String[] args)
    {
        ChatServer cs = new ChatServer();
       
        // serverAddr && serverPort
        String serverIp = "localhost";
        int serverPort = 9999;
        InetAddress serverAddr = null;
       
        if (args != null && args.length > 0)
        {
            int i = 0;
            while (i < args.length)
            {
                // serverAddr
                if (args[i].equalsIgnoreCase("-ServerAddr"))
                {
                    i = i + 1;
                    serverIp = args[i];
                    continue;
                }
               
                // serverPort
                int ti = 9999;
                if (args[i].equalsIgnoreCase("-ServerPort"))
                {
                    i = i + 1;
                    ti = Integer.parseInt(args[i]);
                    if (ti > 0)
                    {
                        serverPort = ti;
                    }
                    i = i + 1;
                    continue;
                }
            }
        }
       
        try
        {
            serverAddr = InetAddress.getByName(serverIp);
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
            System.exit(-1);
        }
       
        // 建立输入
        System.out.println("Lexiaofei聊天室创建成功!");
        Scanner input = new Scanner(System.in);
        System.out.println("!-请输入服务端命令:");
       
        // 开始输入
        String command = null;
        // 如果输入quit将断开连接,并退出操作
        while (!(command = input.next()).equalsIgnoreCase("-quit"))
        {
            // 获取帮助
            if (command.equalsIgnoreCase("-help"))
            {
                cs.helpList();
            }
           
            // 初始化服务器
            if (command.equalsIgnoreCase("-run"))
            {
                boolean goon = true;
                while (goon)
                {
                   
                    // 测试服务器创建,如果成功则同时为信息监听器建立线程
                    System.out.println("!-创建服务器并运行...");
                    if (cs.initServer(serverAddr, serverPort))
                    {
                        new Thread(cs).start();
                        goon = false;
                    }
                    else
                        System.out.println("!-服务器创建失败,请检查!");
                }
            }
           
            // 关闭服务器
            if (command.equalsIgnoreCase("-stop"))
            {
                cs.cutServer();
            }
        }
        input.close();
        cs.cutServer();
    }
   
    /**
     * 错误提示
     *
     * @param str
     */
    public static void errorTip(String str)
    {
        System.out.println("-----------------\n" + str + "\n-----------------");
    }
}

posted @ 2013-12-16 21:12 做强大的自己 阅读(191) | 评论 (0)编辑 收藏

分布式事务管理

 <!--weblogic-->
 <bean id="jtaTxManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
        <property name="transactionManagerName" value="javax.transaction.TransactionManager" />
 </bean>
 
 <!--websphere-->
 <bean id="jtaTxManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />  
   
 <tx:advice id="txAdvice" transaction-manager="jtaTxManager">
  <tx:attributes>
   <tx:method name="select*" read-only="true" />
   <tx:method name="query*" read-only="true" />
   <tx:method name="list*" read-only="true" />
   <tx:method name="detail*" read-only="true" />
   
   <tx:method name="insert*" />
   <tx:method name="update*" />
   <tx:method name="delete*" />
   <tx:method name="transfer*" />
  </tx:attributes>
 </tx:advice>

 <aop:config>
  <aop:pointcut id="transactionPointcut"
   expression="execution(public * com.wbd.ngcrm.example.dictitem.service.*.*(..))" />
  <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" />
 </aop:config>

 <!-- dataSource begin -->
 <bean id="dataSource.yy1a" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName">
   <value>jdbc/yy1a</value>
  </property>
 </bean>
 
 <bean id="dataSource.yy1b" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName">
   <value>jdbc/yy1b</value>
  </property>
 </bean>

 <bean id="dataSource.yy2a" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName">
   <value>jdbc/yy2a</value>
  </property>
 </bean>
 
 <bean id="dataSource.yy2b" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName">
   <value>jdbc/yy2b</value>
  </property>
 </bean>

posted @ 2012-09-19 11:08 做强大的自己 阅读(396) | 评论 (0)编辑 收藏

struts2的ActionContextCleanUp filter

为了使用WebWork,我们只需要在web.xml配置FilterDispatcher一个过滤器即可,阅读一下FilterDispatcher的JavaDoc和源码,我们可以看到它调用了:

 finally
 {
            ActionContextCleanUp.cleanUp(req);
 } 

在ActionContextCleanUp中,有这样的代码:

req.setAttribute(CLEANUP_PRESENT, Boolean.TRUE); 

如果FilterDispatcher检测到这个属性,就不会清除ActionContext中的内容了,而由ActionContextCleanUp后续的代码来清除,保证了一系列的Filter访问正确的ActionContext.

文档中提到,如果用到SiteMesh的Filter或者其他类似Filter,那么设置顺序是:

 ActionContextCleanUp filter
 SiteMesh filter
 FilterDispatcher
 所以最后我们的web.xml应该类似这样:

    <filter>
        <filter-name>ActionContextCleanUp</filter-name>
        <filter-class>com.opensymphony.webwork.dispatcher.ActionContextCleanUp</filter-class>
    </filter>

    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.webwork.sitemesh.FreeMarkerPageFilter</filter-class>
    </filter>

    <filter>
        <filter-name>webwork</filter-name>
        <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>ActionContextCleanUp</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>webwork</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 

 

posted @ 2008-04-23 21:38 做强大的自己 阅读(3713) | 评论 (0)编辑 收藏

filter-mapping的执行顺序和字符集设置的优先级研究

问题起因:
   今天遇到一个乱码问题,以前已经配置好了的呀。而且是普遍现象,看来是公共的变更引起的问题。
   
分析过程:

  于是开始进行调试,因为是公共问题,所以就对web.xml最近的变更进行增删调试,发现如果使用SecurityFilter就报错,去掉久正常了。
  仔细检查,发现如下现象:
  1、在设置字符集之前, 提前调用了request.getParameter()方法,就会出现问题。即使后来再设置字符集,随后的action接收的数据也会乱码。
    2、对于同一个url,如:*.do,filter-mapping 是有顺序的,按照web.xml中的配置顺序。

    从网上查到的结论:
  根据servlet2.3规范filter执行是按照web.xml配置的filter-mapping先后顺序进行执行,所以上面的配置会导致遇见*.do的url请求,先进行SecurityFilter的过滤器处理,这时候没有做编码处理,已经是乱码,到下面的filter处理时已经时乱码,再做编码处理已经没有用处。

解决办法:   
 错误的顺序:
    
     <filter-mapping>
         <filter-name>SecurityFilter</filter-name>
         <url-pattern>*.do</url-pattern>
     </filter-mapping>
 
     <filter-mapping>
         <filter-name>CharacterEncoding</filter-name>
         <url-pattern>*.do</url-pattern>
     </filter-mapping>
 
     <filter-mapping>
         <filter-name>CharacterEncoding</filter-name>
         <url-pattern>*.jsp</url-pattern>
     </filter-mapping>
 
 正确的顺序:
 
     <filter-mapping>
         <filter-name>CharacterEncoding</filter-name>
         <url-pattern>*.do</url-pattern>
     </filter-mapping>
 
     <filter-mapping>
         <filter-name>CharacterEncoding</filter-name>
         <url-pattern>*.jsp</url-pattern>
     </filter-mapping>
 
     <filter-mapping>
         <filter-name>SecurityFilter</filter-name>
         <url-pattern>*.do</url-pattern>
     </filter-mapping>
   
   

posted @ 2008-04-23 21:06 做强大的自己 阅读(1973) | 评论 (0)编辑 收藏

weblogic 下的spring2.06 xsd 使用问题

问题起因:
    升级spring2.x的dtd声明为xsd声明以后,spring2.x+struts2.x的应用在weblogic81下报错,日志提示建议使用jdk1.5或升级xerces。

解决过程:
    自己写了一个spring2.x+struts2.x应用在weblogic81下正常运行。说明问题出在应用上。

    拷贝出问题的应用的jar包到成功应用的lib目录,问题仍然存在。说明还有其他隐情。

    比对两个应用,发现出问题的应用使用了weblogic.xml, 其中配置了优先加载web-inf\lib的jar包。

    此时建立jrokit/jar/lib/endrosed目录,放入最新的xerces包,也不生效。

    换一个思路,查询DocumentBuilderFactoryImpl,发现有应用中有4处引用,删除xerces.jar的时候,发布成功。至此问题解决!!!!!!!

问题总结:
    1    要注意保留成功的案例,以便比对。
          最近碰到两个类似的问题了:一个是websphere下的web-inf\template问题,一个就是由于weblogic.xml干预,造成xerces.jar
的问题。

    2    要注意观察实际使用的类的版本

    3    升级以后,一定要验证单个平台下是否都能正常使用,并增加评审环节,避免影响他人。




posted @ 2008-04-19 12:58 做强大的自己 阅读(239) | 评论 (0)编辑 收藏

Weblogic中部署应用的注意事项

1、gbk -> GBK
2、weblogic.xml中上下文要写为war的应用名字
3、8.1版本中的j2ee组件(filter,listener,servlet)初始化顺序与tomcat,websphere不一样,如果组件之间有依赖,无法实现跨平台相同部署。

posted @ 2008-04-13 13:07 做强大的自己 阅读(287) | 评论 (0)编辑 收藏

在JSP开发中的对象和范围属性

  在JSP页面中的对象,包括用户创建的对象(例如,JavaBean对象)和JSP的隐含对象,都有一个范围属性。
  范围定义了在什么时间内,在哪一个JSP页面中可以访问这些对象。
  例如,session对象在会话期间内,可以在多个页面中被访问。application对象在整个Web应用程序的生命周期中都可以被访问。
  在JSP中,有4种范围,如下所示。

  page范围

  具有page范围的对象被绑定到javax.servlet.jsp.PageContext对象中。在这个范围内的对象,只能在创建对象的页面中访问。可以调用pageContext这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象(pageContext对象还提供了访问其他范围对象的getAttribute方法),pageContext对象本身也属于page范围。当Servlet类的_jspService()方法执行完毕,属于page范围的对象的引用将被丢弃。page范围内的对象,在客户端每次请求JSP页面时创建,在页面向客户端发送回响应或请求被转发(forward)到其他的资源后被删除。

  request范围

  具有request范围的对象被绑定到javax.servlet.ServletRequest对象中,可以调用request这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象。在调用forward()方法转向的页面或者调用include()方法包含的页面中,都可以访问这个范围内的对象。要注意的是,因为请求对象对于每一个客户请求都是不同的,所以对于每一个新的请求,都要重新创建和删除这个范围内的对象。

  session范围

  具有session范围的对象被绑定到javax.servlet.http.HttpSession对象中,可以调用session这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象。JSP容器为每一次会话,创建一个HttpSession对象,在会话期间,可以访问session范围内的对象。

  application范围

  具有application范围的对象被绑定到javax.servlet.ServletContext中,可以调用application这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象。在Web应用程序运行期间,所有的页面都可以访问在这个范围内的对象。

posted @ 2008-04-13 13:03 做强大的自己 阅读(195) | 评论 (1)编辑 收藏

Javascript访问html页面的控件

 访问控件的主要对象是:document对象, 提供几个主要方法来访问对象:
 1. document.getElementById
 2. document.getElementsByName
 3. document.getElementsByTagName
 4. document.all
下面谈谈以上几个方法的具体用法:

一.document.getElementById
 Var obj=document.getElementById("ID")
 根据指定的ID属性值得到对象。返回id属性值等于ID的第一个对象的引用。假如对应的为一组对象,则返回该组对象中的第一个。
 <input name="a" type="text" id="b"/>
 <input name="b" type="text" id="a"/> 
 <input type="button" name="submint1" value="text1" onclick=:"alert(document.getElementById("b"))"/>
 <input type="button" name="submint2" value="text2" onclick="alert(document.getElementById("a")))"/>
 
 我在IE中测试了上面代码,在第一个文本框中输入1,在第二个文本中输入2,然后点击两个按钮,大吃一惊。
 结果两个按钮都返回了第一个文本框的值。
 这说明了IE执行document.getElementById(elementName)的时候,返回的是第一个name或者id等于elementName的对象,并不是根据ID来查找的。
 相反我在firefox中就不存在这个问题。Firefox执行document.getElementById(elementName)的时候只能查找ID等于elementName对象,如果不存在在返回null.
 
二.document.getElementsByName
 Var obj=document.getElementsByName("Name")
 根据Name属性的值获取对象集合。返回name等于指定Name对象的集合。注意这里返回的是一个集合,包括只有一个元素的情况也是一个集合。
 document.getElementsByName("name")[0]
 这样来获取某一个元素。注意javascript中的集合取一个值可以用[],也可以用()。
 如:
 <script>
 function prop()
 {
  var objs=document.getElementsByName("a");
  alert(objs(0).value);//或者可以alert(objs[0].value)也正确的。
 }
 </script>
 <input type="text" name="a" id="b" value="this is textbox"/>
 <input type="button" value="testing" onclick="prop()"/>
 
三.Document.getElementsByTagName
 Var ojbs=document.getElementsByTagName("Tag")
 根据基于指定元素名称对象的集合。返回Tag属性等于指定Tag标记的集合。这里也返回的是一个集合。(同上)
 
四.document.all用法。
 document.all是页面内所有元素的一个集合。例如:
 document.all(0)表示页面的第一个元素。
 Document.all("txt")表示页面上id或name等于txt的所有对象的单个元素和集合元素。
 如果页面上的id或name等于txt只有一个元素(包括name和id情况),那么document.all()的结果就只是一个元素,反之就是获取一个集合。
 (综合了document.getElementById和document.getElementsByName的各自的特点)。
 也可以这样写:document.all.txt也是一样。
 例如:
 <input   name=aaa   value=aaa>
 <input   id=bbb   value=bbb>
  <script   language=Jscript>
      alert(document.all.aaa.value)     //根据name取value
      alert(document.all.bbb.value)     //根据id取value
  </script>
 代码2:
   但是常常name可以相同(如:用checkbox取用户的多项爱好的情况)
  <input   name=aaa   value=a1>
  <input   name=aaa   value=a2> 
  <input   id=bbb   value=bbb> 
  <script   language=Jscript> 
     alert(document.all.aaa(0).value)//显示a1
     alert(document.all.aaa(1).value)//显示a2
     alert(document.all.bbb(0).value)//这行代码会失败  
  </script> 
 理论上一个页面中的ID是互不相同的,如果出现不同的tags而有相同的id的话,document.all.id就会失败,就象这样:
 <input   id=aaa   value=a1>
  <input   id=aaa   value=a2>
  <script   language=Jscript>
      alert(document.all.aaa.value)//显示undefined而不是a1或者a2
  </script>
 所以说遇到了这种情况的话用下面这种写法:
  <input   id=aaa   value=aaa1>
  <input   id=aaa   value=aaa2>
  <input   name=bbb   value=bbb>
  <input   name=bbb   value=bbb2>
  <input   id=ccc   value=ccc>
  <input   name=ddd   value=ddd>
  <script   language=Jscript>
  alert(document.all("aaa",0).value)
  alert(document.all("aaa",1).value)
  alert(document.all("bbb",0).value)
  alert(document.all("bbb",1).value)
  alert(document.all("ccc",0).value)
  alert(document.all("ddd",0).value)
  </script>
 另外document.all可以判断浏览器的种类是否是IE,
 document.all---------针对IE
 document.layers------------针对Netscape
 这两个集合.all只在ie里面有效,layers只在nc里面有效
 所以就可以通过这个方式来判断不同的浏览器。
 最后我来说说getElementById和getElementsByName使用范围:
 Id就像身份证号,是唯一的,name就像姓名一样可以同名。
 一个元素定义了id,引用该元素时直接用id属性,而name通常用在form中,且必须由document.form.***而来,
 也就是说,name 属性定义的元素在脚本中是document 对象的子对象。
    1. name用于form内元素,提交需要.id用于form外元素好用因为DOM能直接取得单一元素
    2.id 每页只能有一个. name可以有多个 name,有些标签不推荐用它
    3. 表单元素(form input textarea select)与框架元素(iframe frame) 用 name这些元素都与表单(框架元素作用于form的target)提交有关,
    在表单的接收页面只接收有name的元素 , 赋ID 的元素通过表单是接收不到值的, 你自己可以验证一下有一个例外A 可以赋 name 作为锚点, 也可以赋 ID;只能赋ID不能赋name的元素:(除去与表单相关的元素都只能赋ID)  
    body li   table   tr   td   th   p   div   span   pre   dl   dt   dd   font   b   等等。
  这里我引出另一个问题,既然有了ID那为什么还要name呢?
  最直接答案:ID就像是一个人身份证号,而 name就像是他的名字,ID虽然是唯一的,但name是可以重复的。
    具体来说:对于ID来说,它就是Client端HTML元素的Identity 。而Name 其实要复杂的多,因为   Name   有很多种的用途,所以它并不能完全由ID来代替,从而将其取消掉。
    参考网站资料如下:具体用途有:
   用途1:作为可与服务器交互数据的HTML元素的服务器端的标示,比如input、select、textarea和button等。我们可以在服务器端根据其Name通过
request.getParameter('name')取得元素提交的值。     
   用途2:HTML元素Input type="radio" 分组,我们知道radio button控件在同一个分组类,check操作是mutex的,同一时间只能选中一个radio,这个分组就是根据相同的Name属性来实现的。
     用途3:建立页面中的锚点,我们知道<a href="URL" >link </a>是获得一个页面超级链接,
     如果不用href属性,而改用Name,如:<a name="PageBottom"></a>,我们就获得了一个页面锚点。
     用途4:作为对象的   Identity   ,如   Applet   、   Object   、   Embed   等元素。比如在   Applet  对象实例中,我们将使用其Name来引用该对象。
   用途5:在IMG元素和MAP元素之间关联的时候,如果要定义IMG的热点区域,需要使用其属性usemap,使usemap="#name"(被关联的MAP元素的Name)
   用途6:某些特定元素的属性,如attribute,和param。例如为Object定义参数<PARAM   NAME   =   "appletParameter"   VALUE   =   "value" > .
  显然这些用途都不是能简单的使用 ID来代替掉的,所以HTML元素的ID和   Name的却别并不是身份证号码和姓名这样的区别,它们更本就是不同作用的东西。
当然HTML元素的Name属性在页面中也可以起那么一点ID的作用,因为在DHTML对象树中,我们可以使用 document.getElementsByName 来
获取一个包含页面中所有指定Name元素的对象数组。
  在这里顺便说一下,要是页面中有n(n >1) 个HTML元素的ID都相同了怎么办?在DHTML对象中怎么引用他们呢?
    这个时候我们还是可以继续使用document.getElementById获取对象,只不过我们只能获取ID重复的那些对象中在HTML Render时第一个出现的对象。
    而这时重复的ID会在引用时自动变成一个数组,ID重复的元素按 Render的顺序依次存在于数组中。
getElementById("xxx")返回第一个id属性为"xxx"或者特定表单元素name为"xxx"的元素
getElementsByName("xxx")返回所有id属性为"xxx"或者特定表单元素name为"xxx"的元素
这里要说明一下其实getElementById和getElementsByName取元素的范围是一样的,区别只是前者只返回第一个元素后者返回所有元素的集合
    另外说明一下表单元素 表单元素指的是在<FORM >标签中数据可以被提交给服务器的标签,
主要有 <INPUT > <SELECT > <TEXTAREA >三个标签 这三个标签只有在name属性不为空的时候才能将数据提交给服务器 所以这三种标签多定义了一个name属性
其实这个name属性和id属性是完全一样的都可以定位元素
如果不是表单元素 就算你加了name属性getElementsByName也取不到不信你自己试试 

posted @ 2008-04-13 12:46 做强大的自己 阅读(599) | 评论 (0)编辑 收藏

jsp 页面性能的提升一个例子


问题起因:
        今天两个同事向我反映workspace.jsp页面性能下降了,开始以为他们机器性能差或者jsp没有编译的原因。碍于面子,就坐下来看了一下,这一看不要紧,每次点都比较慢。两个人的机器配置也不差,以前同样的应用速度还是能够忍受的。我立刻感觉到了可能确实存在了问题,一个页面在tomcat单机下要几秒才能出来,肯定是有问题了。我们的系统是企业级别的应用,并发客户量非常的大。要是出了这样的问题,肯定会当场瘫痪的。

问题分析:
        我首先通知了负责这个模块的同事,检查最近这个功能的修改纪录。最后发现原来是增加了一个ocx控件的调用。每次访问这个页面都要重新从服务器下载这个控件,导致了页面加载的性能问题。

解决办法:
        把控件的加载放到了同一个页面的另一个frame的top.jsp,这样登陆的时候只需要下载一次缓存这个控件,之后workspace.jsp通过top.jsp所在的frame访问到该ocx控件。工作区页面的显示速度又恢复了原来的样子。

问题总结: 
        1、要相信直觉的力量,发现问题及时定位,不能攒到一起,再排地雷
        2、要联系该模块最近的变更,及时找到问题的根源。
        3、要注意收集总结这样的案例,以备将来的性能改造。

posted @ 2008-04-08 12:38 做强大的自己 阅读(259) | 评论 (0)编辑 收藏

仅列出标题
共4页: 上一页 1 2 3 4 下一页