专栏首页java架构学习交流Java web开发,在一个jsp里放太多java代码的后果,摘自 java web轻量级开发面试教程

Java web开发,在一个jsp里放太多java代码的后果,摘自 java web轻量级开发面试教程

现要做一个简单的登录页面,如果用户通过验证,会显示Welcome用户名的欢迎词,反之则返回登录页面让用户再次输入

这部分的完整代码是JSPDemo项目里的login.jsp,下面来分析一下关键代码。

代码位置

视频位置

code/第3章/JSPDemo

视频/第3章/JSP案例的讲解

根据JSP的语法,可以通过@import来导入需要的jar包。这里需要导入支持MySQL的库文件,这部分的代码如下所示。

1   <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
2   <%@ page import="java.sql.*"%>
3   <%@ page import="com.mysql.jdbc.Driver" %>

JSP相当于在HTML页面加上Java代码,一般在<body>标签里放入主要代码。

首先来分析一下业务,当进入这个页面的时候,需要判断是否有用户名和密码信息输入,以此来做不同的动作,所以在开始部分,需要用一个内嵌对象request来完成这个功能,主要代码如下。

4   <body>
5   <%
6        if(request.getParameter("username") == null)
7        {
8    %>
9   <form method="post" action="login.jsp" name="userInfo" id="userInfo">
10  <table>
11       <tr>
12           <td>User Name</td>
13           <td><input type="text" name="username" id="username" /></td>
14       </tr>
15       <tr>
16           <td>Password </td>
17           <td><input type="password" name="password" id="password" /></td>
18       </tr>
19       <tr>
20           <td colospan="2" align="center">
21  <input type="submit" name="logon" value="Login" />&nbsp;&nbsp;
22       <input type="reset" name="reset" value="Reset" />
23           </td>
24       </tr>
25  </table>
26  </form>

我们看到,在JSP里是用<%...%>把Java代码包含起来的,这里用request.getParameter来读取是否有username这个信息。request是个内嵌对象,可以不用定义就能直接使用,这里用到它的获取参数的方法。

在JSP里有不少内嵌对象,在项目里经常用到的是request、response、Session、out等,关于内嵌对象的知识大家不用硬记,可以在用到的时候查现成的API。

一旦发现没有用户名的信息输入,那么就需要用一个HTML的form来显示供用户输入的窗口。

如果request.getParameter("username")不是null,即用户已经输入了用户名,那么就需要获取用户名和密码信息,并到数据库进行验证,代码如下所示。

27   <%
28      }
29      else
30      {
31          String username = request.getParameter("username").toString();
32          String pwd = "";
33          if(request.getParameter("password") != null)
34          {
35              pwd = request.getParameter("password").toString();
36          }       
37          //connect to DB
38          Class.forName("com.mysql.jdbc.Driver");       
39       Connection connection = null;
40       connection = DriverManager.getConnection(
41                   "jdbc:mysql://localhost:3306/book", "root", "123456");
42          String sql = "select username from users where UserName = ?and Pwd = ?";
43       PreparedStatement pst = connection.prepareStatement(sql);
44       pst.setString(1, username);
45       pst.setString(2, pwd);
46           ResultSet rs=pst.executeQuery();
47       //can login
48       if(rs.next())
49       {
50  %>
51          Welcome,<%= rs.getString("username") %>

从上述代码中的第31和35行得到了用户名和密码之后,用第38行的Class.forName载入了JDBC的驱动程序,然后在第43行定义了一个PreparedStatement来执行SQL语句,并在第46行用一个ResultSet来接收运行结果。

请大家注意,这里用到的PreparedStatement是为了避免SQL注入,这部分的知识点大家可以看本书的数据库相关的内容。

一旦通过第48行的if语句判断rs.next()有返回对象,那么就需要先在第50行用%>结束Java部分的JDBC访问数据库的代码,随后在第51行显示Welcome的字样。这里能看到JSP的另外一个语法,用<%=%>来显示变量的结果。

如果第48行里rs.next没有返回,也就是说,在数据库里找不到匹配的用户信息,那么就需要返回到登录页面,让用户再次输入登录信息,这部分的代码如下。

52   <%     
53       }
54       else
55       {
56  %>
57  <form method="post" action="login.jsp" name="userInfo" id="userInfo">
58  <table>
59       <tr>
60           <td>User Name</td>
61           <td><input type="text" name="username" id="username" /></td>
62       </tr>
63       <tr>
64           <td>Password </td>
65           <td><input type="password" name="password" id="password" /></td>
66       </tr>
67       <tr>
68           <td colospan="2" align="center">
69  <input type="submit" name="logon" value="Login" />&nbsp;&nbsp;
70           <input type="reset" name="reset" value="Reset" />
71           </td>
72       </tr>
73  </table>
74  </form>
75  <%      
76       }
77      }  
78  %>
79  </body>
80  </html>

这里其实是代码复制,又写了一遍提供用户名和密码输入的form。

JSP的语法不算简单,但大家可以有选择性地了解,从而把学习时间用到更重要的知识点(比如框架思想、优化思想)的学习上。

在上述代码给出的例子中,能看到如下的缺陷:

①出现了代码复制,把供用户输入的form复制了两次。

②频繁地切换JSP和HTML的逻辑,导致阅读上和开发上的困扰,日后如果别人来维护这部分代码,会很困难。

刚开始开发的时候这种缺陷还不明显,当深入开发的时候,这种缺陷就会爆发。

①修改点一:我们需要调整供用户验证身份的Form代码,加入验证码的输入框。

我们不得不修改两个重复且相同的代码,这样不仅会增加工作量,而且一个疏忽就会导致忘记修改其中一个,增加代码维护的难度。

②修改点二:要改成Oracle数据库,而且数据表名和字段都变了。

我们不仅需要修改JDBC的代码,而且还要修改Welcome xxx这部分的显示代码,也就是说,数据库方面的修改会直接牵涉其他类型的业务代码。

③修改点三:需要实现“三次验证不过就要锁用户”功能。

我们需要在JDBC部分的代码计数,如果登录次数小于3,那么就需要重复性地复制Form的代码。如果超过三次,则还需要在Java代码里夹杂一个“提示锁屏”的显示页面,这会导致JSP更加混乱。

不是危言耸听,我们见过不少页面数量小于10的小项目,开发人员为了省事,直接在JSP里放入所有的功能,就像前面给出的例子一样,交货两三个月后,当完成用户提出若干改进意见后,这些个JSP代码就变得像天书一样,阅读性很差。

在提面试问题的时候,如果发现候选人使用“大而全”的开发方式,我们会让面试者说出理由,如果理由类似“项目紧,缺人手,权衡下来宁可牺牲代码的质量”,那么说明面试者至少和MVC开发模式比较过,可以接受。如果面试者直接不知道MVC的开发模式,甚至不知道“大而全”的缺点,那么我们的评价至少是“没架构意识”。

如何改进?分解业务,用分层的方式来分解不同类型的业务。

具体来说,在JSP页面里,剥离与显示无关的代码,一个好的JSP页面里,应该少见甚至不用<%%>包含起来的Java代码。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 机器人批改作文 你觉得它能胜任吗?

    都市快报消息,一篇200字不到的作文,机器人用几十秒时间找出了8处语法和用词错误。最近,在浙江外国语学院国际学院,来自俄罗斯、韩国、赞比亚等6个国家的11位外国...

    企鹅号小编
  • 浅谈神经网络发展史:从莫克罗-彼特氏神经模型到深层神经网络

    2016年,随着AlphaGo战胜了李世石,人工智能与深度学习达到了一个空前火热的状态。很多人也是第一次开始接触到了深度神经网络这个概念,但是其实神经网络的历史...

    chaibubble
  • abaqus中python脚本的应用

    abaqus提供了很丰富的功能,然而有时候操作起来并不方便或者没有我们想要的基本功能。此外,在工作中经常会处理一些重复性的操作,这时候用python脚本处理将会...

    企鹅号小编
  • GAN提高人体重识别准确率

    论文地址https://arxiv.org/abs/1701.07717内容简介 这篇文章的主要贡献是只使用原始数据集进行半监督学习,提高行人重识别的Basel...

    企鹅号小编
  • 刚刚,国家科技部联手腾讯重磅宣布!癌症患者的春天终于来了!

    220万!280万!290万! 这些数字不是钱,而是2014、2015、2016过去3年中国癌症死亡人数!多么触目惊心!在中国,特别是农村,一得癌症必死无疑! ...

    企鹅号小编
  • 盘点机器学习中那些神奇的损失函数

    盘点机器学习中那些神奇的损失函数 这周深圳真的变冷,以前读书的时候,只要天气变到我会冷到哆嗦就知道,快过年了,算算,还有21天,2017就过去了,我在2016年...

    企鹅号小编
  • Hinge loss

    原文链接:Hinge loss Hinge loss 在机器学习中,hinge loss常作为分类器训练时的损失函数。hinge loss用于“最大间隔”分类,...

    chaibubble
  • 如何用神经网络“寻找威利”

    作者:Tadej Magajna 编译:Bing 《威利在哪里?》(Where’s Wally)是由英国插画家马丁·汉德福特(Martin Handford)创...

    企鹅号小编
  • 行人重识别 Person Re-identification知识资料全集

    【导读】主题荟萃知识是专知的核心功能之一,为用户提供AI领域系统性的知识学习服务。主题荟萃为用户提供全网关于该主题的精华(Awesome)知识资料收录整理,使得...

    企鹅号小编
  • TensorFlow 深度学习笔记 Logistic Classification

    Logistic Classification Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎sta...

    梦里茶

扫码关注云+社区

领取腾讯云代金券