学习字典才联想到要和 JSP 说再见了
最开始只是想让页面能够映射出我的字典值,然而却发现了更大的问题。
假如你自己做一个 demo ,需要前台页面映射出字典数据你会怎么做呢?大致的思路应该是有的,准备字典,准备数据,然后将两部分进行映射。
在做的过程中,我也在思考,该如何保存字典数据呢?有一种比较简单的方法,这种方法也很是巧妙,使用一个工具类,使用枚举法来保存字典值。在该类中还可以加载配置文件。
import java.io.IOException;
import java.util.Properties; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class Keys { private final static Logger logger = LoggerFactory.getLogger(BaseDictUtil.class); public static String project_name; // 加载配置文件
static {
logger.info("======= Start load Properties =====");
Properties webapp_prop = new Properties();
try {
webapp_prop.load(BaseDictUtil.class.getResource("/webapp.properties").openStream());
project_name = webapp_prop.getProperty("webapp_project_name"); logger.info("======= End load Properties =====");
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
} // 配置性别字典
public enum Gender {
Gender_1("男生", 1), Gender_2("女生", 2); public static String getName(int index) {
for (Gender c : Gender.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
} private Gender(String name, int index) {
this.name = name;
this.index = index;
} private String name; private int index; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getIndex() {
return index;
} public void setIndex(int index) {
this.index = index;
}
}
}
上面这种方式,在字典很少的情况下,用起来方便快捷,但是有个问题很明显,若是需要新添加一个字典还要改动代码,很是麻烦。
下面看一下另外一种方式,也是用的比较多的一种,这种方法就需要使用数据库了,把字典统一保存保存在一张表中,当项目启动的时候加载到一个 Map 中。
Map 中的值有一定的规律,map 的就 key 怎么定义看你自己,一般是将字典先分组再取对应关系。比方说城市组的代号是 city,在 city 下的 001 代表的是北京。那 Map 的结构可以是 city 为主键 value 是一个子 Map。子 Map 中存放的就是城市编号和具体城市的映射。
我在网上看到另一种分组的,拿过来和大家分享一下。一条 dict 记录可以分为哪个表下的哪个字段什么值,表示的什么值,对应到数据库和 Map 中我们可以这样设计。
而 Map 中的 key 为 tableName_fieldName_fieldValue 值为 field_detail 。同样的在这里我们可以加载配置文件到 Map 中,这里可以选择加载一些系统级的配置。
public class BaseDictUtil { @Autowired
private static BaseDictDao dicDao; private static HashMap<String, String> hashMap = new HashMap<>(); private final static Logger logger = LoggerFactory.getLogger(BaseDictUtil.class); // 静态方法在程序启动的时候只加载一次,这样为了让查询方法只去数据库查询一次
static {
// 获取应用上下文对象
@SuppressWarnings("resource")
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext-dao.xml");
// 获取dicDao实例
dicDao = ctx.getBean(BaseDictDao.class);
queryDic();
} // 加载配置文件
static {
logger.info("======= Start load Properties =====");
Properties webapp_prop = new Properties();
Properties base_prop = new Properties();
try {
webapp_prop.load(BaseDictUtil.class.getResource("/webapp.properties").openStream());
hashMap.put("webapp_project_name", webapp_prop.getProperty("webapp_project_name")); base_prop.load(BaseDictUtil.class.getResource("/base_dict.properties").openStream());
hashMap.put("base_dict.dict_type_code.001", base_prop.getProperty("base_dict.dict_type_code.001")); logger.info("======= End load Properties =====");
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
} // 从数据库中取值放入到HashMap中
public static void queryDic() {
List<BaseDict> dics = dicDao.selectAll();
for (int i = 0; i < dics.size(); i++) {
BaseDict dic = dics.get(i);
String tableName = dic.getTable_name();
String fieldName = dic.getField_name();
String fieldValue = dic.getField_value();
String key = tableName + "_" + fieldName + "_" + fieldValue;
String value = dic.getField_detail();
logger.info(key + " ---> " + value);
hashMap.put(key, value);
}
} public static String getFieldDetail(String tableName, String fieldName, String fieldValue) {
StringBuilder sb = new StringBuilder();
StringBuilder keySb = sb.append(tableName).append("_").append(fieldName).append("_").append(fieldValue);
String key = keySb.toString();
String value = hashMap.get(key);
return value;
} public static String getProperties(String key) {
return hashMap.get(key);
} public static void main(String[] args) {
String detail = BaseDictUtil.getFieldDetail("customer", "cust_level", "2");
System.out.println(detail); System.out.println(getProperties("webapp_project_name"));
}
}
到上面为止,我们已经把字典处理好了,获取实体中的数据很简单,但是现在来了一个问题,我们该如何将两者结合起来,是先在后台处理好数据传到前台还是分别传到前台再由前台处理映射关系呢?
这个问题可真的难为我了,有一个很蠢的办法,获取实体数据的时候我们一条一条的映射,最终返回给前台处理好的结果。可作为一个后台工程师,这不是我想的,然而,处理前台我功力又不行。唉
功能的事到此就结束了,后面主要想谈谈关于前后端分离的事,之前前后台不分家,后端工程师是又当爹又当妈。既要处理数据又要处理页面,很恶心。
但是曙光来了,现在提倡前后台分离,作为后端工程师的我来说,那真的是高兴呀。随之而来的就是 JSP 页面被抛弃了,改用 HTML + JS 或是前段框架 + JS 。
为什么要抛弃 JSP 呢 ?
1、数据和静态资源都放在一起,各种请求 CSS、JS、图片的请求会增加服务器的压力。
2、JSP 必须要在支持Java 的 web 容器中运行(类如 tomcat),无法使用 nginx。
3、第一次请求 JSP 必须在 web 容器中将 JSP 转化为 Servlet,所以首次访问比较慢。
4、JSP 页面中内容比较杂,有 html、各种标签、JS ,给前端看前端头疼,给后端看后端头疼,不易分工。
5、如果 JSP 中的内容很多,页面响应会很慢,因为是同步加载。
以前开发步骤是这样
1、客户端发出请求。
2、服务端的 Servlet 或 Controller 接收请求(路由规则由后端制定,整个项目开发的权重大部分在后端)。
3、调用 service、dao 代码完成业务逻辑。
4、返回 JSP。
5、JSP 展现一些动态的代码。
前后端分离之后是这样
1、浏览器发送请求。
2、直接到达 html 页面(路由规则由前端制定,整个项目开发的权重前移)。
3、html 页面负责调用服务端接口产生数据(通过 ajax 等等)。
4、填充 html,展现动态效果。
而前后端更多的是采用 JSON 来进行数据交互,通过 ajax 来异步加载数据,所以一个项目不管数据量多么复杂,都可以轻松的访问,不像以前那样通过一个请求一股脑的把所有的数据都返回。
说了这么多前后端分离的好,然,我自己写的 demo 并没有前台来照顾,不说了,默默的搬砖去了……
学习字典才联想到要和 JSP 说再见了的更多相关文章
- springboot学习入门之五---开发Web应用之JSP篇
转载:http://tengj.top/2017/03/13/springboot5/ 1整体结构 整体的框架结构,跟前面介绍Thymeleaf的时候差不多,只是多了webapp这个用来存放jsp的目 ...
- Servlet和JSP学习指导与实践(三):JSP助阵
前言: JSP(Java Server Page)虽然作为一门服务端的语言,但它并没有创新新的语言标准.有些人一接触jsp之后发现易学易懂.实际上,jsp的内部原理仍然是基于Servlet,它是Ser ...
- .Net程序员之Python基础教程学习----字典的使用 [Third Day]
今天学习了字典的使用, 所谓的字典其实就是键值对数据, 一个字典里面有唯一的Key对应一个value,Key是唯一的,Value不唯一. 在.net添加相同的Key会报错,在Python,若出现相 ...
- JavaEE学习总结(十三)—JavaWeb、JSP、Servlet与DVD管理系统
一.JSP基础知识 1.0.创建数据库与表 /* Navicat MySQL Data Transfer Source Server : 127.0.0.1 Source Server Version ...
- javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...
- Python学习--字典
在Python中通过名字来引用值的数据结构称为映射(mapping).字典是Python中唯一内建(Python解释器本身支持,不需要import)的映射类型.字典中的值没有特殊的顺序,都存储在一个特 ...
- Python基础学习----字典常用操作
字典的常见操作: # 字典: # 格式:{键值对,键值对} dict_demo={"name":"bai-boy","age":17} # ...
- redis学习-字典
1.字典作用 实现数据库键空间(key space): 用作 Hash 类型键的底层实现之一: 2.字典实现的数据结构 typedef struct dict { // 特定于类型的处理函数 dict ...
- Python学习——字典
字典 字典是另一种可变容器模型,且可存储任意类型对象. 1.创建字典 字典由键和对应值成对组成.每个键与值之间用:隔开,每对之间逗号隔开. 每个键应当互不相同,值可以相同.若同时出现两个相同的键,则后 ...
随机推荐
- springboot的日志框架slf4j (使用logback输出日志以及使用)
1.为什么使用logback? ——在开发中不建议使用System.out因为大量的使用会增加资源的消耗.因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序. ...
- Java基础-类加载机制与自定义类Java类加载器(ClassLoader)
Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...
- Hadoop基础-MapReduce的Combiner用法案例
Hadoop基础-MapReduce的Combiner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编写年度最高气温统计 如上图说所示:有一个temp的文件,里面存放 ...
- bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机
http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...
- Matrix67|自由职业者,数学爱好者
Matrix67|自由职业者,数学爱好者 介绍一下你自己和所做的工作. 我叫顾森,网名 Matrix67,长住北京的重庆人,目前没有固定的职业.一会儿当当码农,一会儿做做编辑,一会儿教教数学,一会儿写 ...
- 编写安全的API接口
HTTPS接口参数加密签名设计思路 数名 类型 必选 描述 _appid string 是 调用方身份ID,接口提供方用此来识别调不同的调用者,该参数是API基本规范的一部分,请详见API公共规范. ...
- flask基础之LocalProxy代理对象(八)
前言 flask框架自带的代理对象有四个,分别是request,session,g和current_app,各自的含义我们在前面已经详细分析过.使用代理而不是显式的对象的主要目的在于这四个对象使用太过 ...
- House Robber I & II & III
House Robber You are a professional robber planning to rob houses along a street. Each house has a c ...
- React-Native 之 ListView使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- 一个无锁消息队列引发的血案(五)——RingQueue(中) 休眠的艺术
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...