为了账号安全,请及时绑定邮箱和手机立即绑定

毛哥的快乐生活 二十章 使用Servlet打造多版本通知网站

标签:
职场生活

本章源码:Github

html版

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

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

<body>
    <div id="head">
        <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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中的模板就好了啦。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
软件工程师
手记
粉丝
1.5万
获赞与收藏
1523

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消