(JSP)在文本域中显示超链接new——服务器部分代码

本文介绍了一次服务器端代码的重大更新,新增了统一算法处理的Java文件,通过AppletContainer类管理和存储用户请求,以及ServerFactory类实现客户端连接处理与重试机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        这次的服务器端相应代码也是改动比较大,并且也加入了新的类。

        这次增加了一个新的Java文件,用于将算法统一化:

 

package project.util;

import java.util.HashMap;


/**
 * This class is used to abstract the data type for algorithm
 * 
 * 
@author Zenny Chen
 *
 
*/


class ContainerWrapper {
    String value 
= null;
    
int count = 0;
}



/**
 * This class is used to store and get the users' requests.</br>
 * It is a singleton, and the algorithm is encapsulated.
 * 
 * 
@author Zenny Chen
 *
 
*/


public class AppletContainer {
    
    
/**
     * a container that stores users' request info
     
*/

    
private HashMap<String, ContainerWrapper> container = new HashMap<String, ContainerWrapper>();
    
    
/**
     * the only instance of this class in an application
     
*/

    
private static AppletContainer applet_container = null;
    
    
/**
     * the total number of requests
     
*/

    
private volatile int total_request = 0;
    
    
/**
     * As a singleton, the constructor cannot be accessed by other classes.
     *
     
*/

    
private AppletContainer() {
        
    }

    
    
/**
     * As a singleton, there's an only method for other objects to use to create the only
     * instance.
     * 
@return the only instance
     
*/

    
public static synchronized AppletContainer getInstance() {
        
if(applet_container == null)
            applet_container 
= new AppletContainer();
        
return applet_container;
    }


    
/**
     * add a user's request info
     * 
@param key It will be referred to a string that identifies the request.
     * 
@param value the relevant info
     
*/

    
public synchronized void add(String key, String value) {
        
if(container.containsKey(key)) {
            container.get(key).value 
= value;    // Update the value
            container.get(key).count++;            // Increase reference count
        }

        
else {
            ContainerWrapper wrapper 
= new ContainerWrapper();
            wrapper.count 
= 1;
            wrapper.value 
= value;
            container.put(key, wrapper);
        }

    }

    
    
/**
     * Get a user's request info
     * 
@param key reference to a particular request
     * 
@return the relevant info
     
*/

    
public synchronized String get(String key) {
        String res 
= null;
        
        
if(container.containsKey(key)) {
            res 
= container.get(key).value;
            container.get(key).count
--;
            
if(container.get(key).count == 0)
                container.remove(key);
        }

        
        
return res;
    }

    
    
/**
     * clear all the elements of the container
     *
     
*/

    
public void reset() {
        
if(total_request == 0)
            container.clear();
    }

    
    
/**
     * Get whether the container is empy or not.
     * 
@return If the container is empty, return true; Otherwise, return false.
     
*/

    
public boolean isEmpty() {
        
        
return container.isEmpty();
    }

    
    
/**
     * Increase the total number of requests
     *
     
*/

    
public synchronized void increaseRequest() {
        total_request
++;
    }

    
    
/**
     * Decrease the total number of requests
     *
     
*/

    
public synchronized void decreaseRequest() {
        total_request
--;
    }

}

 

 

        下面再看看ServerFactory代码:

 

package project.util;


import java.util.ArrayList;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;


/**
 * 
 * SocketMonitor queues the ServerFacotry objects that are timeout
 * during serving the network connection and make them respectively
 * restart at a proper time.</br>
 * This class only can be accessed by ServerFactory class.
 * 
 * 
@author Zenny Chen
 *
 
*/


class SocketMonitor implements Runnable {
    
    
/**
     * The number of objects it can hold.
     
*/

    
private static final int MAX_THREADS = 255;
    
    
/**
     * The memory space where it holds the ServerFactory objects.
     
*/

    
private ArrayList<ServerFactory> list = new ArrayList<ServerFactory>(MAX_THREADS);
    
    
/**
     * It is a Singleton. 
     
*/

    
private static SocketMonitor monitor= null;
    
    
/**
     * 
     *    As a singleton, the constructor cannot be accessed.
     
*/

    
private SocketMonitor() {
        startMonitor();
    }

    
    
    
/**
     * The only method to get the object.
     * 
     * 
@return the monitor
     
*/

    
synchronized static SocketMonitor getInstance() {
        
if(monitor == null)
            monitor 
= new SocketMonitor();
        
        
return monitor;
    }

    
    
/**
     * 
     * Add a ServerFactory object that is timeout during running into the
     * monitor's queue. 
     * 
     * 
@param s: reference to a ServerFactory object that will be stored.
     * 
     
*/

    
synchronized void addSocket(ServerFactory s) {
            if(list.size() == MAX_THREADS) {
                   list.remove(0);
                   AppletContainer container = AppletContainer.getInstance();
                   container.decreaseRequest();
              }

        
        list.add(s);
    }

    
    
/**
     * This is the monitor's running thread method.<br>
     * It is running forever unitl the server(Apache for example)
     * is closed.
     
*/

    
public void run() {
        
for(;;) {
            
try {
                Thread.sleep(
1000);
            }

            
catch(InterruptedException e) {
                System.out.println(
"Sleep Interupted in monitor!");
            }

        
            ServerFactory server 
= digestSocket();
            
if(server != null)
                server.beginCommunication(
false);
        
            Thread.yield();
        }

    }

    
    
    
/**
     * Dequeue a monitored object. 
     * 
     * 
@return the ServerFactory object that will be restarted.
     
*/

    
private synchronized ServerFactory digestSocket() {
        
if(list.size() != 0{
            
return list.remove(0);
        }

        
        
return null;
    }

    
    
    
/**
     * Start the monitor's running thead.
     *
     
*/

    
private final void startMonitor() {
        Thread thread 
= new Thread(this);
        thread.start();
    }

}



class CommunicationProtocol {
    
static final String OK_RESPONSE = "OK";
    
static final String NG_RESPONSE = "NG";
}




/**
 * This class is used to encapsulate the socket server object.</br>
 * Maybe the class name is not quite proper, but now I don't wanna alter it.</br>
 *
 * 
@author Zenny Chen
 *
 
*/


public class ServerFactory implements Runnable{
    
    
/**
     * This lock is used to synchronize the threads that come from
     * different clients.
     
*/

    
private static volatile Boolean lock = false;
    
    
/**
     * port number.</br>
     * Maybe a dynamic port number is better. Hope the port is not used
     * by other tasks.
     
*/

    
private static final int PORT = 8079;
    
    
/**
     * server socket connection time out.
     
*/

    
private static final int SOCKET_TIMEOUT = 3000;
    
    
/**
     * the number of retries when the connection is time out.
     
*/

    
private static final int TIMES_OF_TIMEOUT = 10;
    
    
/**
     * the server socket reference</br>
     * It is created in this class.
     
*/

    
private ServerSocket server = null;
    
    
private AppletContainer container = null;
    
    
/**
     * This flag is used to delay the main process.
     
*/

    
private volatile boolean mayReturn = false;
    
    
/**
     * reference to a socket monitor object.
     
*/

    
private SocketMonitor monitor = null;
    
    
/**
     * used to count the remaining times for retries.
     
*/

    
private int n_remainingTimeouts = TIMES_OF_TIMEOUT;
    
    
/**
     * Close the server socket.
     *
     
*/

    
private void close() {
        
try {
            server.close();
            server 
= null;
            lock 
= false;
        }

        
catch(IOException e) {
            System.out.println(
"socket server closing error!");
        }

    }

    
    
/**
     * constructor
     * 
@param value:the string that'll be output to a specified applet.
     
*/

    
public ServerFactory(String func, String value) {
        
//this.value = value;
        monitor = SocketMonitor.getInstance();
        container 
= AppletContainer.getInstance();
        container.increaseRequest();
        container.add(func, value);
    }


    
/**
     * Start the server's running thread.
     * 
     * 
@param ifWait:the flag used to spcify whether the main process
     * should be wait or not.
     
*/

    
public void beginCommunication(boolean ifWait) {
        
        Thread thread 
= new Thread(this);
        thread.start();
        
        
if(ifWait == false)
            
return;
        
        
while(!mayReturn);
        mayReturn 
= false;
    }

    
    
    
/**
     * Serverfactory's running method.
     
*/

    
public synchronized void run() {
        
        
try {
            
for(;;) {
                
while(lock) {
                    Thread.yield();
                    Thread.sleep(
200);
                }

                
synchronized(lock) {
                    
if(lock == true)
                        
continue;
                    
                    lock 
= true;
                    
break;
                }

            }

        }

        
catch(InterruptedException e) {
            System.out.println(
"Interrupt abnormally broken!");
        }

        
        mayReturn 
= true;
        
        
try {
            System.out.println(
"Ready to listen!");
            
            server 
= new ServerSocket(PORT);
            server.setSoTimeout(SOCKET_TIMEOUT);
            Socket sock 
= server.accept();
 
            DataInputStream in 
= new DataInputStream(sock.getInputStream());
            DataOutputStream out 
= new DataOutputStream(sock.getOutputStream());
            
            String value 
= null, cmd = null;
            cmd 
= in.readUTF();
            
if(cmd != null)
                value 
= container.get(cmd);          
            
if(value == null{
                System.out.println(
"mismatched!");
                out.writeUTF(CommunicationProtocol.NG_RESPONSE);
                monitor.addSocket(
this);
                close();
                
return;
            }

            
            out.writeUTF(CommunicationProtocol.OK_RESPONSE);
            out.writeUTF(value);

            System.out.println(
"Data transmitted!");
            close();
            container.decreaseRequest();
            System.out.println(
"Is the container empty? " + container.isEmpty());
        }

        
catch(IOException e) {
            
if(e instanceof SocketTimeoutException) {
                System.out.println(
"Time out!");
                
if(--n_remainingTimeouts > 0)
                    monitor.addSocket(
this);
                
else {
                    container.decreaseRequest();
                    container.reset();
                }

                close();
            }

            
else {
                System.out.println(
"Connecting...");
                container.decreaseRequest();
                container.reset();
                close();
            }

        }

    }

}

 

 

        而HTMLParser部分代码没有改动,可以参照《(JSP)在文本域中显示超链接——如何使用服务器端代码》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值