jndi 笔记

   JNDI 笔记(一) 概述 收藏
JNDI,Java Naming Directory Interface,J2EE的标准之一,所有的J2EE容器都必须提供一个JNDI的服务,但是,我一直都没用过,至少是没有刻意地去用过。因为,我也曾经把数据源配置在Tomcat的JNDI服务中,但那时,我也只是刚刚涉足JAVA,有人告诉我应该这么干而已。后来,我开始使用自定义的数据库连接配置文件,就再也没有跟JNDI打过交道了,直到今天。

现在之所以又想看一下,只是因为觉得这是J2EE的重要标准之一,如果不懂得的话,似乎有点说不过去。

JNDI的主要功能可以这样描述,它使用一张哈希表存储对象(大多数的J2EE容器也的确是这样做的),然后,开发人员可以使用键值——也就是一个字符串——来获取这个对象。这里就包括取JNDI的两个最主要操作,bind和lookup。bind操作负责往哈希表里存对象,存对象的时候要定义好对象的键值字符串,lookup则根据这个键值字符串往外取对象。

JNDI的命称可能会让人产生混淆,似乎觉得这是一个用来操作目录的,事实上,我更愿意把这个目录理解成为JNDI存放对象时使用的格式,也就是说,JNDI以目录的方式存储对象的属性。例如,用户通过JNDI存储一个汽车对象,那么,汽车就是根目录,汽车的轮子、引擎之类的子对象就算是子目录,而属性,比如说汽车的牌子、重量之类,就算是汽车目录下的文件。

JNDI的功能既然就是根据一个字符串键值就可以取得一个想要得到的对象,我一开始就觉得这不是跟COM或CORBA一样吗?SUN也是有野心的企业啊,JNDI应该就是它要努力推行的JAVA下的分布式开发的标准吧。

JNDI的出现应该就是为了分步式开发服务的,有人负责开发这种分布式对象,有人只需要使用这些分布式对象就可以了,这两组人不必属于同一个公司,而且这种开发通常应该是不并行的,也不必是会了同一个项目服务。就如果数据源对象,它放在JNDI中,只要想要用的人,直接通过JNDI服务取来用就可以了,至于当初是谁把它放进JNDI中的,还是不用操这份心了吧。而我一直没有使用JNDI,也就是这个原因,项目中的所有对象都在我控制之下,我不去使用别人的对象,也没打算把我的对象贡献出来给别人使用,那自然也就没必要去跟JNDI打交道。我觉得是否使用JNDI,这应该是关键原因,至于什么方便性、安全性之类的考虑,应该不是JNDI的主要目的,就如同你可以用JAVA来做网站,但JAVA并不是专门用来做网站的。

可能有人觉得这种功能跟IoC也很象,这个我倒不觉得,虽然对于对象的使用人员来说的确是这种感觉,且不说IoC需要为对象定义接口,而JNDI并无此限制,先说这里有一个使用环境问题,我觉得IoC是用来解决并行开发问题的,也就是说IoC主要是用于明确设计人员与实现/使用人员的分工,无论是设计的,还是使用的,通常是一个项目组里的人,使用IoC,可以使得设计人员专注于设计,加快设计速度。因此,IoC的用途要比JNDI广泛的多,现在大型系统中,不使用IoC的,几稀矣。

以上废话是为题记。

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/lldwolf/archive/2008/04/14/2290788.aspx

 

JNDI 笔记(二) J2EE下使用JNDI 收藏

 

在J2EE环境下使用JNDI是非常简单的事,因为所有的J2EE容器都要实现JNDI服务,所以,在J2EE环境下使用JNDI,与使用Hashtable也没有什么太大区别。只有一点限制,那就是绑定对象时,对象所属的类必须实现java.io.Serializable接口,这一点也实在一点也不困难,几乎所有用到的Java类都实现了这个接口,对于自定义的类,在接口实现列表里把这个接口加进去也就是了。

下面,我将演示一下如何在J2EE环境下使用JNDI,为了保证代码的通用性,我不使用struts之类的框架,而是直接使用标准JSP和Servlet实现。我将该项目的名称定为jndi_test

要使用JNDI,需要先到SUN的网站上去下载jndi.jar。

 2.1 JSP
本项目包括5个JSP,功能说明如下:

index.jsp:首页
bind.jsp:用于在JNDI中绑定对象
bind_result.jsp:绑定对象后的返回页面
lookup.jsp:用于在JNDI中检索对象
lookup_result.jsp:用于显示检索对象
本节中用到的JSP代码如下,代码都简单地很,就不多做解释了。

2.1.1 index.jsp
<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>JNDI Test</title>
</head>
<body>
<a href="bind.jsp" target="_blank">bind.jsp</a>
<br />
<a href="lookup.jsp" target="_blank">lookup.jsp</a>
</body>
</html>

2.1.2 bind.jsp
<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>JNDI Test - Bind</title>
</head>
<body>
<a href="bind.do">bind an object</a>
</body>
</html>

2.1.3 bind_result.jsp
<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>JNDI Test - Bind result</title>
</head>
<body>
<p>Binded successfully!</p>
</body>
</html>

2.1.4 lookup.jsp
<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>JNDI Test - lookup</title>
</head>
<body>
<a href="lookup.do">lookup the binded object</a>
</body>
</html>

2.1.5 lookup_result.jsp
<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>JNDI Test - Lookup result</title>
</head>
<body>
<%...
    Object o = request.getAttribute("found_jndi_obj");
    out.println(o);
%>
</body>
</html>

2.2 Servlet
本例包括两个Servlet,功能说明如下:

BindServlet:用于在JNDI服务中绑定一个对象
LookupServlet:用于在JNDI服务中取出一个对象
2.2.1 BindServlet.java
package lld.test.jndi;

import java.io.IOException;
import java.util.Date;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.*;

public class BindServlet extends HttpServlet
...{

    private static final long serialVersionUID = 5219969790998794367L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        try
        ...{
            Context jndi_ctx = new InitialContext();
            String key = "jndi_object";
            jndi_ctx.rebind(key, new Date());
        }catch(Exception ex)
        ...{
            ex.printStackTrace();
        }
       
        ServletContext context = this.getServletContext();
        RequestDispatcher dispatcher = context.getRequestDispatcher("/bind_result.jsp");
        dispatcher.forward(req, resp);
    }
   
}

使用rebind而不是bind绑定对象是因为,使用bind时,如果已经有对象绑定到该键值上,则会抛出异常。

因为只是示例代码,所以我只是绑定了一个最简单的日期对象。

2.2.2 LookupServlet.java
package lld.test.jndi;

import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LookupServlet extends HttpServlet
...{
    private static final long serialVersionUID = 6677219828267184673L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        try
        ...{
            Context jndi_ctx = new InitialContext();
            String key = "jndi_object";
            Object o = jndi_ctx.lookup(key);
            req.setAttribute("found_jndi_obj", o);
        }catch(Exception ex)
        ...{
            ex.printStackTrace();
        }
       
        ServletContext context = this.getServletContext();
        RequestDispatcher dispatcher = context.getRequestDispatcher("/lookup_result.jsp");
        dispatcher.forward(req, resp);
    }
   
}

2.3 web.xml
在web.xml中,加入了servlet映射

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>jndi_test</display-name>
   
    <servlet>
        <servlet-name>BindServlet</servlet-name>
        <servlet-class>lld.test.jndi.BindServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>BindServlet</servlet-name>
        <url-pattern>/bind.do</url-pattern>
    </servlet-mapping>
   
    <servlet>
        <servlet-name>LookupServlet</servlet-name>
        <servlet-class>lld.test.jndi.LookupServlet</servlet-class>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>LookupServlet</servlet-name>
        <url-pattern>/lookup.do</url-pattern>
    </servlet-mapping>
   
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
OK,所有的代码都在这里了,部署到Tomcat下运行即可。


2.4 示例下载
嗯, 我不晓得如何上传文件, 谁想要发我邮箱

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/lldwolf/archive/2008/04/16/2295938.aspx

  JNDI 笔记(三) J2SE下使用JNDI 收藏
在J2SE下使用JNDI下就显得困难一些,首先,我们没有单独的JNDI服务器可以用,JBoss提供了一个免费的JNP服务,通过配置可以作为单独的JNDI服务器启用。不过这里就不这么麻烦了,如何使用JBOSS作为JNDI服务器,以后将单独撰文讲述,这里我使用sun提供的com.sun.jndi.fscontext.RefFSContextFactory作为JNDI服务器,其实这是使用文件系统来存储JNDI对象。至于如何存储后文还将专门描述。

为了在J2SE下使用JNDI,我们首先得到sun的网站上下载3个包,jndi.jar、fscontext.jar和providerutil.jar,前者提供了JNDI服务的接口,后两者是我们要使用的文件系统作为JNDI服务器的支持包。

使用RefFSContextFactory,要求绑定的对象必须实现javax.naming.Referencable接口,否则在绑定时将报如下错误:

Can only bind References or Referenceable objects

各个JDBC驱动提供商提供的DataSource类都实现了Referencable接口,可以直接使用。不过本着学习的态度,我还是在这里演示一下如何实现Referencable接口。

这个如何实现将在后文结合代码详细介绍。本例包括4个类,说明如下:

BindedClass:自定义的实现Referenceable接口的类
BindedClassFactory:工厂类,能够把一个Reference对象转换为BindedClass对象
Bind:测试类,用于在JNDI中绑定对象
Loopup:测试类,用于从JNDI中获取对象
3.1 BindedClass和BindedClassFactory
3.1.1 BindedClass
package lld.test.jndi;

import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;

public class BindedClass implements Referenceable
...{
    public String value;
   
    public BindedClass()
    ...{
    }
   
    @Override
    public Reference getReference() throws NamingException
    ...{
        Reference r = new Reference(this.getClass().getName(), BindedClassFactory.class.getName(), null);
        r.add(new StringRefAddr("value", this.getValue()));
        return r;
    }

    public String getValue()
    ...{
        return value;
    }

    public void setValue(String value)
    ...{
        this.value = value;
    }

}

3.1.2 BindedClassFactory
package lld.test.jndi;

import java.util.Hashtable;

import javax.naming.*;
import javax.naming.spi.*;

public class BindedClassFactory implements ObjectFactory
...{
    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
            Hashtable<?, ?> environment) throws Exception
    ...{
        if(obj instanceof Reference)
        ...{
            Reference ref = (Reference)obj;
            String val = (String)ref.get("value").getContent();
            BindedClass o = new BindedClass();
            o.setValue(val);
            return o;
           
        }
        return null;
    }
}

3.1.3 代码解释
Referenable接口只有一个方法,就是getReference(),返回一个Reference对象,BindedClass只设了一个示例成员变量Value,存储一个字符串值,在创建Refernce对象时,要指定它引用的类名以及创建该类的工厂对象,JNDI Context在绑定该对象时就会将这些信息都存到文件中,将来从JNDI中取对象时可就全靠工厂对象根据文件中的内容重建BindedClass对象了。我这里提前把绑定后生成的文件内容说一下,大家会更有一个直观的印象,其内容如下所示:

bind1/RefAddr/0/Type=valuebind1/ClassName=lld.test.jndi.BindedClassbind1/RefAddr/0/Encoding=Stringbind1/FactoryName=lld.test.jndi.BindedClassFactorybind1/RefAddr/0/Content=abcdefg大家看到了,前面在BindedClass.getReference()方法中使用了如下语句:

r.add(new StringRefAddr("value", this.getValue()));

就是定义要将这些信息存储到JNDI中呢,至于最后的“bind1/RefAddr/0/Content=abcdefg”,那是因为我在后面的示例Bind.java中将其值设成了“abcdefg”而已,呵呵。而BindedClassFactory.getObjectInstance()方法中

String val = (String)ref.get("value").getContent();

就是用来取到存储的值呢。

3.2 Bind.java
本例用来绑定一个BindedClass对象 package lld.test.jndi;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class Bind
...{
    public static void main(String[] args) throws Exception
    ...{
        Properties ps = new Properties();
        ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
        ps.setProperty(Context.PROVIDER_URL, "file:JNDI_REF");
        DirContext ctx = new InitialDirContext(ps);
        String key = "bind1";

        BindedClass b = new BindedClass();
        b.setValue("abcdefg");
        ctx.rebind(key, b);

        System.out.println("Binded successfully!");
        ctx.close();
    }
}

3.3 Lookup.java
本例用来从JNDI中获取绑定的BindedClass对象

package lld.test.jndi;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class Lookup
...{
    public static void main(String[] args) throws Exception
    ...{
        Properties ps = new Properties();
        ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
        ps.setProperty(Context.PROVIDER_URL, "file:JNDI_REF");
        DirContext ctx = new InitialDirContext(ps);
        String key = "bind1";
        BindedClass o = (BindedClass)ctx.lookup(key);
        System.out.println(o.getValue());   
       
        ctx.close();
    }

}

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/lldwolf/archive/2008/04/17/2299622.aspx

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是与HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,与RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法与创新点。1.1研究背景与意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法与创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论与技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述与后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计与实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计与实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试与优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法与步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论与展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望与改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户与权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋与房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋与房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置与完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间与原因) 3. 住宿分配与调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修与安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值