目录

1. Jsp标签字典开发_基于Spring+Hibernate

  1.1. 简述

  1.2. 定义DictItem实体

  1.3. 定义字典的@interface

  1.4. 定义字典缓存类

  1.5. 定义tld标签

  1.6. 持久层实体使用注解

  1.7. 页面调用jsp标签

2. 补充点

  2.1. Hibernate设置属性成功后扫描字典

  2.2. Annotation注解

  2.2.1. 简述

  2.2.2. 元注解

  2.2.3. 自定义注解

1. Jsp标签字典开发_基于Spring+Hibernate

1.1. 简述

最近在项目中,发现一个很不错的jsp字典缓存开发。不过是基于Spring+Hibernate技术的,记录下来方便以后有个参考。

主要流程是这样的:

1、创建tdl,以及对应的后来处理类;

2、定义字典相关的@interface;

3、当项目创建启动开始创建sessionFactory时,扫描entity时候获取到已定义的字典@interface,然后存入到系统缓存(一般是定义一个静态的map存放)中;

4、页面使用定义的标签调用,去系统缓存里面取值。

1.2. 定义DictItem实体

一般来说,字典都是key-value的方式,这里的key就是group,value是DictItem.包含有一个text和value属性,text表示显示的值,value表示数据库的值。举个简单的例子说明:

假设表a有一个status字段,当status=1的时候,text为“成功”;当status=2的时候,text为“失败”。这样我们可以把表a的status作为一个字典。key可以是“status”,value为DictItem(简单表示为[{”value”:1,”text”:”成功”},{”value”:2,”text”:”失败”}])。

DictItem实体可以简单定义如下:

//显示值

private String text;

//值

private String value;

public String getText() {

return text;

}

public void setText(String text) {

this.text = text;

}

public String getValue() {

return value;

}

public void setValue(String value) {

this.value = value;

}

1.3. 定义字典的@interface

在这里主要有DictDefine、DictGroup、DictItem几个注解定义,下面一一介绍具体的定义。

1、DictDefine的创建

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target({ElementType.FIELD,ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

public @interface DictDefine {

public DictGroup[] value();

}

2、DictGroup的创建

public @interface DictGroup{

public String name();

public DictItem[] items();

}

3、DictItem的创建

public @interface DictItem{

public String value();//值

public String text();//显示值

}

1.4. 定义字典缓存类

这里可以定义一个简单的字典缓存变量,一般是静态的map。如:

private static Map<String,List<DictItem>> cache = new HashMap<String, List<DictItem>>();

这个java类(如SysDictCache)需要提供一个设置值和取值的方法。一般情况下,存值根据组(group)和字典(DictItem);取值的话,根据组(group)和值(value),具体的实现根据项目需求自行发挥,这里只是提供一个思路。

1.5. 定义tld标签

我们需要有jsp的tld文件,一般是放在项目的WEB-INF包下面的。举个简单的例子如下:

<?xml version="1.0" encoding="UTF-8" ?>

<taglib 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-jsptaglibrary_2_0.xsd"

    version="2.0">

<description>xmq自定义标签,扩展jstl标签</description>

<display-name>xmq tag</display-name>

<tlib-version>1.1</tlib-version>

<short-name>xmq</short-name>

<uri>http://com.xmq.tag/tld</uri>

  <validator>

    <description>

        Provides core validation features for JSTL tags.

    </description>

    <validator-class>

        org.apache.taglibs.standard.tlv.JstlCoreTLV

    </validator-class>

  </validator>

<tag>

<description>处理字典</description>

<name>dict</name>

<tag-class>com.xmq.tag.dictTag</tag-class>

<body-content>JSP</body-content>

<attribute>

<description>处理分组</description>

<name>group</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>  

<type>java.lang.String</type>       

</attribute>

<attribute>

<description>值</description>

<name>dict</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue> 

<type>java.lang.String</type>        

</attribute>

</tag>

</taglib>

还需要一个后台处理标签的java类,该类需要继承TagSupport,重写doStartTag方法,根据项目需求自行更改。下面给一个简单的例子:

public class dictTag extends TagSupport {

private static final long serialVersionUID = 1L;

private String group;

private String dict;

public String getGroup() {

return group;

}

public void setGroup(String group) {

this.group = group;

}

public String getdict() {

return dict;

}

public void setdict(String dict) {

this.dict = dict;

}

@Override

public int doStartTag() throws JspException {

//DictItem实体与上述的@interface DictItem要对应

//主要功能就是保存取出的具体字典

DictItem dictItem = SysdictCache.get(group, dict);

if (dictItem != null) {

JspWriter w = pageContext.getOut();

try {

w.write(dictItem.getText());

} catch (IOException e) {

throw new JspException(e.toString(), e);

}

}

return SKIP_BODY;

}

}

1.6. 持久层实体使用注解

接下来需要对@Entity的实体进行字典引用定义,一般是定义在某个字段上的,如下述代码:

@DictDefine({

@DictGroup(name="TEST",items={

@DictItem(text="成功",value="1"),

@DictItem(text="失败",value="2")

})

})

@Column(name = "STATUS" , length = 3)
private String status;

1.7. 页面调用jsp标签

页面引入自定义jsp标签:

<%@ taglib uri="http://com.xmq.tag/tld" prefix="xmq"%>

使用jsp标签:

<xmq:dict group="TEST" dict="1"/>

2. 补充点

2.1. Hibernate设置属性成功后扫描字典

在spring的applicationContext.xml中配置Hibernate的sessionFactory时候,指定一个类来处理字典的扫描工作。如:

<bean id="sessionFactory" class="com.xmq.database.DefaultSessionFactoryBean">

<property name="dataSource" ref="dataSource"></property>

</bean>

后台扫描字典的bean需要继承LocalSessionFactoryBean,并重写afterPropertiesSet()方法。如:

public class DefaultSessionFactoryBean extends LocalSessionFactoryBean{

private static final Log logger = LogFactory.getLog(DefaultSessionFactoryBean.class);

private String[] entityPackage;

private static final String RESOURCE_PATTERN = "/**/*.class";

private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

private TypeFilter entityFilter = new AnnotationTypeFilter(Entity.class , false);

@Override

public void afterPropertiesSet() throws IOException {

super.afterPropertiesSet();

try{

if(this.entityPackage != null){

for (String pkg : entityPackage) {
//entityPackage为spring的applicationContext.xml中的"com.xmq.core":<context:component-scan base-package="com.xmq.core" />
//ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX为classpath*:
//ClassUtils.convertClassNameToResourcePath(pkg)转换为带"/"路径,如:com.xmq.core->com/xmq/core
//pattern变量的值最后为:classpath*:com/hymake/sdic/**/*.class
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN; Resource[] resources = new PathMatchingResourcePatternResolver().getResources(pattern);
//resources变量保存资源文件如:[file[..\classes\com\xmq\core\dbUtil.class],file[..\classes\com\xmq\core\stringUtil.class],file [D:\ec...]
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader reader = readerFactory.getMetadataReader(resource); if(entityFilter.match(reader, readerFactory)){
//过滤出有@Entity注解的pojo
scanEntitydictDefined(reader); } } } } } }catch(Exception e){ throw new SysException(e.getMessage() , e); } } /** * 扫描dictDefined * @param reader * @throws ClassNotFoundException */ private void scanEntityDictDefined(MetadataReader reader) throws ClassNotFoundException{ Class cls = Class.forName(reader.getClassMetadata().getClassName());
//过滤出有@DictDefine的@Entity注解的pojo
DictDefine dd = (DictDefine)cls.getAnnotation(DictDefine.class); if(dd != null){ parseDictDefine(dd); }
//没有就去遍历fileds,查找@DictDefine注解
Field[] fields = cls.getDeclaredFields(); for(Field field : fields){ DictDefine dd2 = (DictDefine)field.getAnnotation(DictDefine.class); if(dd2 != null){ parsedictDefine(dd2); } } } private void parseDictDefine(dictDefine cd) { DictGroup[] groups = cd.value(); for(DictGroup dg : groups){ for(DictItem item : dg.items()){
//字典加入系统缓存
SysDictCache.addToCache(dg.name(), new com.xmq.dict.DictItem(item.value(), item.text())); } } } @Override public void setPackagesToScan(String... packagesToScan) { super.setPackagesToScan(packagesToScan); this.entityPackage = packagesToScan; } }

2.2. Annotation注解

2.2.1. 简述

Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和任何元数据(metadata)的途径和方法。Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据。

2.2.2. 元注解

注解名

取值

备注

@Target

1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型)或enum声明

@Target定义了Annotation所修饰的对象范围

@Retention

1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)

定义了Annotation被保留的时间长短

@Documented

@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员

@Inherited

@Inherited是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

2.2.3. 自定义注解

定义注解时候,会自动继承了java.lang.annotation.Annotation接口,在定义注解时,不能继承其他的注解或接口。

定义注解格式:

public @interface 注解名 {定义体}

示例如下:

public @interface DictItem{

public String value();//值

public String text();//显示值

}

//显示默认值的话,可以采用如下方法:

public @interface DictItem{

public String value() defalut “123”;//值

public String text() defalut “123”;//显示值

}

Jsp标签字典开发_基于Spring+Hibernate的更多相关文章

  1. 团队软件开发_基于windows下截屏软件关于NABC框架的特点

    经过我们小组数次的激烈讨论,就自己的能力和时间而言,我们小组的初步的计划是开发一款基于windows下的截图软件. 关于这个软件的功能,我们初步的想法如下: 1.能在windows下后台运行,有相应的 ...

  2. 浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含自定义扫描组件.自定义导入组件.手动注册组件.自动注入方法和参数.使用Spring容器底层组件等 配置 @Confi ...

  3. GPS部标平台的架构设计(三) 基于struts+spring+hibernate+ibatis+quartz+mina框架开发GPS平台

    注意,此版本是2014年研发的基于Spring2.5和Struts2的版本,此版本的源码仍然销售,但已不再提供源码升级的服务,因为目前我们开发的主流新版本是2015-2016年近一年推出的基于spri ...

  4. 基于Spring的可扩展Schema进行开发自定义配置标签支持

    一.背景 最近和朋友一起想开发一个类似alibaba dubbo的功能的工具,其中就用到了基于Spring的可扩展Schema进行开发自定义配置标签支持,通过上网查资料自己写了一个demo.今天在这里 ...

  5. 转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

    from: http://ybak.iteye.com/blog/1853335 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端 游戏服 ...

  6. 基于Spring MVC的Web应用开发(三) - Resources

    基于Spring MVC的Web应用开发(3) - Resources 上一篇介绍了在基于Spring MVC的Web项目中加入日志,本文介绍Spring MVC如何处理资源文件. 注意到本项目的we ...

  7. Spring MVC第一课:用IDEA构建一个基于Spring MVC, Hibernate, My SQL的Maven项目

    作为一个Spring MVC新手最基本的功夫就是学会如何使用开发工具创建一个完整的Spring MVC项目,本文站在一个新手的角度讲述如何一步一步创建一个基于Spring MVC, Hibernate ...

  8. Weshop基于Spring Cloud开发的小程序商城系统

    WESHOP | 基于微服务的小程序商城系统 Weshop是基于Spring Cloud(Greenwich)开发的小程序商城系统,提供整套公共微服务服务模块,包含用户中心.商品中心.订单中心.营销中 ...

  9. springMVC用法 以及一个简单的基于springMVC hibernate spring的配置

    替代struts 1  web.xml中配置springmvc中央控制器 <?xml version="1.0" encoding="UTF-8"?> ...

随机推荐

  1. Java语法基础-final关键字

    final关键字主要用在三个地方:变量.方法.类. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改: 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一 ...

  2. R in action读书笔记(8)-第八章:回归(上)

    8.1回归的多面性 8.2 OLS回归 OLS回归拟合模型形式: 为了能够恰当地解释oLs模型的系数,数据必须满足以下统计假设. 口正态性对于固定的自变量值,因变量值成正态分布. 口独立性Yi值之间相 ...

  3. asterisk-java ami5 分机状态,挂机原因之类的

    这些东西网上随便一找一大堆,也只是记录下自己找的.方便以后自己复制粘贴用. 最后为啦实现分机状态在web的实时更新,我选择啦使用websocket. //获得分机状态 public static St ...

  4. C++ class、struct区别

    一.默认访问控制不同(最主要) struct默认为public,class默认为private.这个访问控制既是指成员的默认访问属性,又指继承时默认的继承属性. 二.定义template时不同 在模版 ...

  5. leetcode_894. All Possible Full Binary Trees

    https://leetcode.com/problems/all-possible-full-binary-trees/ 给定节点个数,求所有可能二叉树,该二叉树所有节点要么有0个子节点要么有两个子 ...

  6. H5 canvas 之乱画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. window10换系统为windows7

    第一步 第二步 第三步 下载系统:http://www.dnxtc.net 1.GHO镜像安装器和WIN7,GHO文件必须一起放在除C盘外的其他盘的根目录 2.“GHO镜像安装器“工具上右键管理员方式 ...

  8. Kotlin – CharSequence IsNullOrBlank() vs IsNullOrEmpty()

    本文摘自:http://blog.farifam.com/2018/01/28/kotlin-charsequence-isnullorblank-vs-isnullorempty/ Koltin p ...

  9. Ubuntu中update-grub2与update-grub的区别

    没有区别. Ubuntu 9.10及更高版本已安装GRUB2,但sudo update-grub仍然以标准命令为准. sudo update-grub和sudo update-grub2是等同的,所以 ...

  10. python 调用exe程序

    #!/usr/bin/python #-*- coding:utf-8 -*- import os, subprocess import tkMessageBox import msg_box def ...