毛哥的快乐生活(20) 使用Servlet打造多版本通知网站

本章源码:Github

html版

html版本极其简单,顶部标题栏,左侧菜单栏,右侧具体内容。例如:

点击全体通知跳转到的nav.html网页

<body>
    <div id="head">
        <img src="bank.png"" alt=" 山南银行">
        山南银行讯息
    </div>
    <div id="left">
        <ul>
            <li><a href="nav.html">全体通知</a></li>
            <li><a href="company.html">公司业务</a></li>
            <li><a>个人业务</a></li>
            <li><a>文体活动</a></li>
        </ul>
    </div>
    <div id="content">
        <table>
            <tr>
                <td>2019-02-04 10:00</td>
                <td>祝大家新春愉快</td>
            </tr>
        </table>
    </div>
</body>

点击公司业务跳转到的company.html网页

<body>
    <div id="head">
        <img src="bank.png"" alt=" 山南银行">
        山南银行讯息
    </div>
    <div id="left">
        <ul>
            <li><a href="nav.html">全体通知</a></li>
            <li><a href="company.html">公司业务</a></li>
            <li><a>个人业务</a></li>
            <li><a>文体活动</a></li>
        </ul>
    </div>
    <div id="content">
        <table>
            <tr>
                <td>2019-02-04 10:00</td>
                <td>公司业务部今天晚上聚餐</td>
            </tr>
        </table>
    </div>
</body>

html版的业务逻辑就是,点击菜单后,直接跳到另外一个网页,看似顶部标题栏和左侧菜单栏没有变化,实际上根本就不是一个网页了。只不过这几个网页顶部和左侧内容一模一样(仅替换了右侧内容区域的代码),显得好像没变而已。

Servlet第一版,这个版本有点傻

分析需求,其实很简单,就是点击全体通知菜单,显示全体通知内容;点击公司业务菜单,显示公司业务内容。

那就做2个Servlet就好了啊,分别输出这两种内容的网页。核心代码如下:(注意此处为了便于演示,CSS等代码没有列出,如果想看完整的请参考Github)

代码结构:
图片描述

//全体通知页Servlet
@WebServlet("/NavServlet")
public class NavServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解决上篇遗留的中文乱码问题
		resp.setContentType("text/html;charset=utf-8");
		PrintWriter out = resp.getWriter();
		//输出全体通知页面内容
		out.println("<body>" + 
				"    <div id='head'>" + 
				"        <img src='bank.png'' alt=' 山南银行'>" + 
				"        山南银行讯息" + 
				"    </div>" + 
				"    <div id='left'>" + 
				"        <ul>" + 
				"            <li><a href='/NoticeSite/NavServlet'>全体通知</a></li>" + 
				"            <li><a href='/NoticeSite/CompanyServlet'>公司业务</a></li>" + 
				"            <li><a>个人业务</a></li>" + 
				"            <li><a>文体活动</a></li>" + 
				"        </ul>" + 
				"    </div>" + 
				"    <div id='content'>" + 
				"        <table>" + 
				"            <tr>" + 
				"                <td>2019-02-04 10:00</td>" + 
				"                <td>祝大家新春愉快</td>" + 
				"            </tr>" + 
				"        </table>" + 
				"    </div>" + 
				"</body>");
	}
}
//公司通知页Servlet
@WebServlet("/CompanyServlet")
public class CompanyServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解决上篇遗留的中文乱码问题
		resp.setContentType("text/html;charset=utf-8");
		PrintWriter out = resp.getWriter();
		//输出全体通知页面内容
		out.println("<body>" + 
				"    <div id='head'>" + 
				"        <img src='bank.png'' alt=' 山南银行'>" + 
				"        山南银行讯息" + 
				"    </div>" + 
				"    <div id='left'>" + 
				"        <ul>" + 
				"            <li><a href='/NoticeSite/NavServlet'>全体通知</a></li>" + 
				"            <li><a href='/NoticeSite/CompanyServlet'>公司业务</a></li>" + 
				"            <li><a>个人业务</a></li>" + 
				"            <li><a>文体活动</a></li>" + 
				"        </ul>" + 
				"    </div>" + 
				"    <div id='content'>" + 
				"        <table>" + 
				"            <tr>" + 
				"                <td>2019-02-04 10:00</td>" + 
				"                <td>公司业务部今天晚上聚餐</td>" + 
				"            </tr>" + 
				"        </table>" + 
				"    </div>" + 
				"</body>");
	}
}

这两段代码需要注意几点:

  1. 因为网页要作为字符串输出,而字符串需要用双引号包裹,恰好网页中也有需要用到双引号。为了区分双引号是表示字符串开始结束标记还是真实的字符串内容,需要使用转义字符。上面的代码为了简单,直接将表示实际内容的双引号转换为了单引号,因为html一样可以识别单引号。这样的好处是代码看起来比较干净整洁,不信你用转义字符试试,绝对丑爆了。
  2. 注意<a href='/NoticeSite/NavServlet'>全体通知</a>,表示点击这个超级链接跳转到/NoticeSite/NavServlet,其中NoticeSite是项目名,NavServlet是Servlet访问名,所以点击该超链接就跳转到NavServlet动态生成的网页了。同理点击公司业务就会跳转到CompanyServlet生成网页。

这个代码看起来很傻,因为重复的代码实在太多,相比html也没看到任何好处?臃肿的代码,着实令人心碎。

Servlet第二版 对重复代码进行封装

经过分析就可以发现一个问题,实际上这两个网页绝大多数内容都是相同的,只不过是内容部分不同罢了。

所以我们可以定义一个静态字符串保存相同部分的内容,然后每次只需要替换掉内容不同的部分就是了。

此处需要注意因为静态字符串全局共享,实际上是内存中独立的一个空间,在任何类中访问它都是访问的同一个内容。

代码结构:

图片描述

HtmlData类用来保存网页模板字符串,需要注意我们用 @content 作为占位符,占据了各个网页内容不同的部分。

package com.maoge.notice.version2;
//用来保存Html模板
public class HtmlData {
	public static String template=
			"<!--导航页,作者:毛哥-->" + 
			"<html>" + 
			"<head>" + 
			"    <meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />" + 
			"    <title>山南银行讯息</title>" + 
			"    <style>" + 
			"        /* 星号表示全部 */" + 
			"        * {" + 
			"            margin: 0;" + 
			"            /*外边距为0*/" + 
			"            padding: 0;" + 
			"            /*内边距为0*/" + 
			"        }" + 
			"        #head {" + 
			"            background: linear-gradient(to right, #FFFFFF, #D0E1FF);" + 
			"            height: 64px;" + 
			"            line-height: 64px;" + 
			"            /*通过设置line-height等于height实现文字垂直居中*/" + 
			"            color: #247398;" + 
			"            /*头部文本颜色*/" + 
			"        }" + 
			"        #head img {" + 
			"            vertical-align: middle;" + 
			"            /*图片垂直居中*/" + 
			"            height: 48px;" + 
			"        }" + 
			"        #left {" + 
			"            width: 186px;" + 
			"            float: left;" + 
			"            /*靠左浮动*/" + 
			"            height: 100%;" + 
			"            /*高度铺满浏览器*/" + 
			"            border: 4px solid #89B5E9;" + 
			"            /*边框,颜色是取色器取得哦*/" + 
			"            background-color: #EAF0F6;" + 
			"            /*背景,颜色是取色器取得哦*/" + 
			"            border-radius: 12px;" + 
			"            /*圆角边框*/" + 
			"            padding-left: 8px;" + 
			"            /*设置左侧内边距*/" + 
			"            color: #247398;" + 
			"            /*字体颜色*/" + 
			"            font-size: 1.3em;" + 
			"            /*字体大小*/" + 
			"            font-family: 'STKaiti';" + 
			"            /*百度找了一种楷体*/" + 
			"        }" + 
			"        #left ul li" + 
			"" + 
			"        /*设置列表项样式*/" + 
			"            {" + 
			"            margin-top: 12px;" + 
			"            /*列表项的上边距*/" + 
			"        }" + 
			"        #content table{" + 
			"            margin-top:24px;" + 
			"            margin-left:224px;/*注意此处因为左侧浮动,设置的是到窗口左边沿的宽度*/" + 
			"        }" + 
			"        #content table tr{" + 
			"            height:48px;" + 
			"        }" + 
			"      " + 
			"    </style>" + 
			"</head>" + 
			"<body>" + 
			"    <div id='head'>" + 
			"        <img src='bank.png'' alt=' 山南银行'>" + 
			"        山南银行讯息" + 
			"    </div>" + 
			"    <div id='left'>" + 
			"        <ul>" + 
			"            <li><a href='/NoticeSite/NavServlet2'>全体通知</a></li>" + 
			"            <li><a href='/NoticeSite/CompanyServlet2'>公司业务</a></li>" + 
			"            <li><a>个人业务</a></li>" + 
			"            <li><a>文体活动</a></li>" + 
			"        </ul>" + 
			"    </div>" + 
			"    <div id='content'>" + 
			"        @content"+
			"    </div>" + 
			"</body>" + 
			"</html>";
}

然后各Servlet只需要把占位符替换为各自想要展示的内容即可:

//全体通知页Servlet
@WebServlet("/NavServlet2")
public class NavServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解决上篇遗留的中文乱码问题
		resp.setContentType("text/html;charset=utf-8");
		PrintWriter out = resp.getWriter();
		//本页内容
		String myContent=
				"        <table>" + 
				"            <tr>" + 
				"                <td>2019-02-04 10:00</td>" + 
				"                <td>祝大家新春愉快</td>" + 
				"            </tr>" + 
				"        </table>";
		//替换模板字符串占位符为本页内容
		String html=HtmlData.template.replace("@content", myContent);
		out.println(html);
	}
}
//公司通知页Servlet
@WebServlet("/CompanyServlet2")
public class CompanyServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解决上篇遗留的中文乱码问题
		resp.setContentType("text/html;charset=utf-8");
		PrintWriter out = resp.getWriter();
		//本页内容
		String myContent=
				"        <table>" + 
				"            <tr>" + 
				"                <td>2019-02-04 10:00</td>" + 
				"                <td>公司业务部今天晚上聚餐</td>" + 
				"            </tr>" + 
				"        </table>";
		//替换模板字符串占位符为本页内容
		String html=HtmlData.template.replace("@content", myContent);
		out.println(html);
	}
}

第二版依然需要注意一些问题:

  1. 因为已经有访问路径/NavServlet/CompanyServlet,所以第二版的Servlet访问路径改为/NavServlet2/CompanyServlet2。如果重复了服务器就不知道该让哪个Servlet响应了。
  2. 类名重复无所谓,以为包名不同。

OK,这个版本才开始有点动态网页的意思,起码不像之前html版本有大量重复的代码了。

毛哥想起很久以前听过一个代码设计基本原则,那就是消灭重复,因为重复的代码不好维护啊。举个最简单的例子,如果要修改顶部标题栏的字体颜色,在html版本时就要逐一修改每个html页面,而现在的Servlet版本只需要修改HtmlData中的模板就好了啦。


如有问题请扫码联系我
在这里插入图片描述

已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页