Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Tomcat环境中保存名称-值对?_Java_Tomcat_Servlets - Fatal编程技术网

Java 如何在Tomcat环境中保存名称-值对?

Java 如何在Tomcat环境中保存名称-值对?,java,tomcat,servlets,Java,Tomcat,Servlets,我们有一个servlet,它需要某些变量,如密码、加密盐等,而不是永久保存在文件系统上。这就是我们目前所做的(总结): 在初始化期间 Perl脚本将ReadMode设置为2以屏蔽标准输出echo,提示用户输入变量,过滤已知文件以将其放入,并调用tomcat/bin/startup.sh servlet init()方法从文件中读取变量并将其删除(文件) 问题: 重新编译WAR时,tomcat会尝试部署它(autodeploy=true),这是我们想要的。但是数据文件不再存在,因此会抛出FileN

我们有一个servlet,它需要某些变量,如密码、加密盐等,而不是永久保存在文件系统上。这就是我们目前所做的(总结):

在初始化期间

  • Perl脚本将ReadMode设置为2以屏蔽标准输出echo,提示用户输入变量,过滤已知文件以将其放入,并调用tomcat/bin/startup.sh

  • servlet init()方法从文件中读取变量并将其删除(文件)

  • 问题: 重新编译WAR时,tomcat会尝试部署它(autodeploy=true),这是我们想要的。但是数据文件不再存在,因此会抛出FileNotFoundException(正确地说)


    问:是否有一个属性或一些HashMap/表可供servlet使用,在手动启动期间可以存储一些变量?其思想是,如果在重新部署期间数据文件不存在,init()可以检查它们。谢谢,-女士。

    如果您想以编程方式处理它,我想您可能需要的是一个。创建一个实现接口的类,并在contextInitialized(ServletContextEvent sce)-方法中编写所需的功能,请参见简单示例。

    将易失性数据放入JNDI。JNDI在重新部署之间没有得到清理。您的servlet仍然可以在
    init
    期间执行相同的操作,以确保JNDI中的数据是最新的

    我不记得JNDI读/写是否是线程安全的,但事实并非如此,您可以始终放置一个线程安全的对象(例如,
    ConcurrentHashMap
    )并毫无问题地使用它

    由MS编辑:

    ==========
    restart.pl:
    ==========
    ReadMode 2; print "\nEnter spice: "; chomp ($spice = <STDIN>); print "\n";
    ReadMode 0;
    open (FP, ">$spicefile") or die "$0: Cannot write file $spicefile: $!\n";
    print FP "$spice\n"; close (FP);
    system "bin/shutdown.sh";       sleep 8;
    system "bin/startup.sh";        sleep 8;        system "wget $tomcaturl";
    system '/bin/rm -rf *spicefile*';               # delete wget output file
    foreach $sCount (1..10) {                       # give it 10 more secs
        sleep 1;
        if (-f $spicefile) {
            print "$0: Waiting on servlet to delete spicefile [$sCount]\n"
        } else {
            print "$0: Successful servlet initialization, no spicefile\n";
            exit 0
    }}
    print "\n$0: deleting file $spicefile ...\n";   # Error condition
    system "unlink $spicefile";
    exit 1;
    
    ===========
    context.xml
    ===========
        <Resource name="MyServlet/upsBean" auth="Container" type="packageName.UPSBean"
                    factory="org.apache.naming.factory.BeanFactory" readOnly="false"/>
    
    ===================
    app/WEB-INF/web.xml
    ===================
      <listener>
            <listener-class>packageName.DBInterface</listener-class>
      </listener>
      <resource-env-ref>
        <description>Use spice as transferable during redeployment</description>
        <resource-env-ref-name>MyServlet/upsBean</resource-env-ref-name>
        <resource-env-ref-type>packageName.UPSBean</resource-env-ref-type>
      </resource-env-ref>
    
    ==============
    MyServlet.java:
    ==============
    init() {
            if (new File (spiceFile).exists())      # Same name in restart.pl
                    dbi = new DBInterface (spiceFile);
            else
                    dbi = new DBInterface ();       # Redeployment
            otherInitializations (dbi.getSpice());
    }
    
    ================
    DBInterface.java:
    ================
    public DBInterface () {
            // Comment out following block if contextInitialized works
            FileInputStream fin = new FileInputStream (safeDepositBox);
            ObjectInputStream ois = new ObjectInputStream (fin);
            UPSBean upsBean = (UPSBean) ois.readObject();
            ois.close();
            spice = upsBean.getSpice();
            dbiIndex = 2;
            // do stuff with spice
    }
    
    public DBInterface (String spiceFileName) {
            File file = new File (spiceFileName);
            BufferedReader br = new BufferedReader (new FileReader (file));
            spice = br.readLine();
            br.close();
            file.delete();
            dbiIndex = 1;
    
            // Delete following block if contextInitialized works
            UPSBean upsBean = new UPSBean();
            upsBean.setSpice (spice);
            FileOutputStream fout = new FileOutputStream (safeDepositBox);
            ObjectOutputStream oos = new ObjectOutputStream (fout);
            oos.writeObject (upsBean);
            oos.flush();
            oos.close();
            // do stuff with spice and if it works, ...
            // contextInitialized (null);
    }
    
    // Above is working currently, would like the following to work
    
    public void contextDestroyed(ServletContextEvent sce) {
            System.setProperty ("spice", spice);
            System.out.println ("[DBInterface" + dbiIndex +
                                            "] Spice saved at " +
                            DateFormat.getDateTimeInstance (DateFormat.SHORT,
                                            DateFormat.LONG).format (new Date()));
    }
    
    public void contextInitialized(ServletContextEvent sce) {
            if (sce != null) {
                    spice = System.getProperty ("spice");
                    System.out.println ("[DBInterface" + dbiIndex +
                                            "] Spice retrieved at " +
                            DateFormat.getDateTimeInstance (DateFormat.SHORT,
                                            DateFormat.LONG).format (new Date()));
            }
            // do stuff with spice
    }
    
    ============
    UPSBean.java:
    ============
    public class UPSBean implements Serializable {
            private String  spice = "parsley, sage, rosemary and thyme";
            public UPSBean() { }
            public String getSpice() {      return spice;   }
            public void setSpice (String s) {       spice = s;      }
    }
    
    ==========
    restart.pl:
    ==========
    阅读模式2;打印“\n输入香料:”;chomp($spice=);打印“\n”;
    读取模式0;
    打开(FP,“>$spicefile”)或关闭“$0:无法写入文件$spicefile:$!\n”;
    打印FP“$spice\n”;关闭(FP);
    系统“bin/shutdown.sh”;睡眠8;
    系统“bin/startup.sh”;睡眠8;系统“wget$tomcaturl”;
    系统“/bin/rm-rf*spicefile*”;#删除wget输出文件
    每个$scont(1..10){#再给它10秒
    睡眠1;
    如果(-f$s文件){
    打印“$0:正在等待servlet删除文件[$Scont]\n”
    }否则{
    打印“$0:servlet初始化成功,没有文件\n”;
    出口0
    }}
    打印“\n$0:删除文件$spicefile…\n”#错误条件
    系统“取消链接$spicefile”;
    出口1;
    ===========
    context.xml
    ===========
    ===================
    app/WEB-INF/WEB.xml
    ===================
    packageName.DBInterface
    在重新部署期间,使用spice作为可转移工具
    MyServlet/upsBean
    包装名称
    ==============
    MyServlet.java:
    ==============
    init(){
    if(新文件(spiceFile.exists())#在restart.pl中同名
    dbi=新的dbi接口(文件);
    其他的
    dbi=新的DBInterface();#重新部署
    其他初始化(dbi.getSpice());
    }
    ================
    DBInterface.java:
    ================
    公共数据库接口(){
    //如果contextInitialized有效,请注释掉下面的块
    FileInputStream fin=新的FileInputStream(SafeDepositorBox);
    ObjectInputStream ois=新ObjectInputStream(fin);
    UPSBean UPSBean=(UPSBean)ois.readObject();
    ois.close();
    spice=upsBean.getSpice();
    dbiIndex=2;
    //用香料做东西
    }
    公共数据库接口(字符串文件名){
    文件文件=新文件(文件名);
    BufferedReader br=新的BufferedReader(新文件读取器(文件));
    spice=br.readLine();
    br.close();
    delete();
    dbiIndex=1;
    //如果contextInitialized工作,请删除以下块
    UPSBean UPSBean=新的UPSBean();
    upsBean.setSpice(香料);
    FileOutputStream fout=新的FileOutputStream(安全存储框);
    ObjectOutputStream oos=新的ObjectOutputStream(fout);
    oos.writeObject(upsBean);
    oos.flush();
    oos.close();
    //用香料做一些东西,如果有用的话。。。
    //contextInitialized(null);
    }
    //以上是目前正在工作,希望以下工作
    公共无效上下文已销毁(ServletContextEvent sce){
    System.setProperty(“spice”,spice);
    System.out.println(“[DBInterface”+dbiIndex+
    “]香料保存在”+
    DateFormat.getDateTimeInstance(DateFormat.SHORT,
    格式(new Date());
    }
    public void contextInitialized(ServletContextEvent sce){
    如果(sce!=null){
    spice=System.getProperty(“spice”);
    System.out.println(“[DBInterface”+dbiIndex+
    “]在检索到香料”+
    DateFormat.getDateTimeInstance(DateFormat.SHORT,
    格式(new Date());
    }
    //用香料做东西
    }
    ============
    UPSBean.java:
    ============
    公共类UPSBean实现了可序列化{
    私人串香料=“欧芹、鼠尾草、迷迭香和百里香”;
    公共UPSBean(){}
    公共字符串getSpice(){return spice;}
    公共void setSpice(字符串s){spice=s;}
    }
    

    我正在尝试查看上面的get/setProperty是否有效。我试图直接使用JNDI,但是当我在contextDestroyed()中使用资源MyServlet/upsBean设置pice并尝试在contextInitialized()中读取它时,我得到一个null(对不起,我已经删除了代码的这一部分)。现在context.xml和resource env ref中的声明变得多余。当前的解决方法是将序列化实例保存在数据文件中(不是很好)。

    在调用startup.sh(即“bin/startup.sh-DencryptionSalt=foobar”)时,如何将它们作为系统属性传入?然后,您可以调用System.getProperty(“EncryptionAlt”),在