JavaWeb的发展小梳理

一、从静态HTML到Servlet
解决问题:
1、动态数据
最初的网站都是静态HTML,但很快我们就不满足于这样了。想要做真正的动态网页,也就是页面上的数据要真正动态变化。
Servlet就是实现该目的的技术之一。
Servlet主要动态功能就是吐出Java代码,然后用out一点一点输出HTML代码,数据的动态功能当然也就实现了。当然代码无比丑陋,且美工人员几乎不能理解这样的代码。

out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<title>首页</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("Hello, " + new Date().toLocalString
out.write("</body>\r\n");
out.write("</html>\r\n");

二、从Servlet到Jsp
对于所有的页面输出,都要针对性的改写,都要去修改Servlet对应的java文件,对于复杂的页面,就会很麻烦。因此自然而然就会想到将表现层一定程度从Servlet中剥离出来。
JSP很像是正常的HTML代码中,藏了一些Java代码。
解决问题:
一定程度剥离表示层

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>首页</title>
</head>
<body>
    <ss:a label="首页" href="/index.jsp" />
    <ss:a label="登入" href="/login.jsp" />
    <ss:a label="注册" href="/register.jsp" />
    <ss:a label="登出" href="/logout.do" />
    <hr/>
    <jsp:include page="/include/jsp/datetime.jsp" />
    <%
        String user = (String) session.getAttribute("user");
        if (user != null && user.length() > 0) {
            out.println("Welcome, <b>" + user + "</b>! You are logged in.");
        }
    %>
</body>
</html>

遇到的问题:
维护成本
随着实际Web应用的使用越来越广泛,Web应用的规模也越来越大,开发人员发现动态Web应用的维护成本也越来越大,即使只需要修改该页面的一个简单按钮文本,或者一段静态的文本内容,也不得不打开混杂的动态脚本的页面源文件进行修改——这是一种很大的风险,完全有可能引入新的错误。
三、MVC编程模式
人们意识到:单纯使用JSP页面充当过多角色是相当失败的选择,这对于后期的维护相当不利,慢慢地开发人员开始在Web开发中使用MVC模式。
使用JSP作为视图,Servlet作为控制器,JavaBean作为模型。通过合理的分层,使得Java程序员更能驾驭大型网站的开发。
这里写图片描述
解决的问题:
分层,简化
细节问题:
1、Servlet中获取到的数据如何传递到视图层

//一般采取这种办法
//在Servlet中将结果设置到request对象当中。
request.setAttribute("result", result);
//在JSP中通过request对象来获取。
<% Object result = request.getAttribute("result"); %>

2、JSP丢掉JAVA代码
JSP既然是视图层,如果嵌入太多JAVA代码的话,对于美工的工作相当不利。
一般来说视图层是不允许使用<% %>来嵌入JAVA代码的。可是视图层也确实需要负责进行一些逻辑判断,来动态输出页面。
Java提供了一个办法,使用自定义标签,和EL表达式

<table>
    <th>
      <td>序号</td>
      <td>姓名</td>
      <td>性别</td>
      <td>年龄</td>
      <td>电话</td>
    </th>
  <c:forEach var="item" items="${request.list}">
    <tr>
      <td>${item.id}</td>
      <td>${item.name}</td>
      <td>${item.sex}</td>
      <td>${item.age}</td>
      <td>${item.phone}</td>
    </tr>
  </c:forEach>
</table>

3、Servlet控制层写法
首先,你需要在Web.xml中进行配置

<servlet>
  <servlet-name>LoginServlet</servlet-name>
  <servlet-class>com.tee.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>LoginServlet</servlet-name>
  <url-pattern>/Login</url-pattern>
</servlet-mapping>

然后,需要编写一个继承自HttpServlet类的Servlet。

package com.tee.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RegisterServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (UserDao.validate(username, password)) {
            request.getSession.setAttribute("user", username);
            response.setContentType("text/html; charset=utf-8");
            response.sendRedirect("/index.jsp");
        } else {
            ServletContext sc = getServletContext();
            RequestDispatcher rd = sc.getRequestDispatcher("/login.jsp");
            request.setAttribute("errMsg", "login failure");
            rd.forward(request, response);
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        doGet(request,response);
    }
}

遇到的问题:
得陇望蜀,想更加简单,更加傻瓜
1、Web.xml会越来越大
首先Web.xml会越来越大,越来越难以维护。且修改Web.xml的风险很大,只要一个错误,整个网站都有可能无法访问。
2、参数的检验
上面的例子没有进行传入参数的检验,如是否为空,是否有是规定长度,是否是规定的字符。也没有涉及到参数转换,如转换成Date类型,转换成int类型。一旦发生错误又该如何传递给前端,前端又该如何接受错误信息,如何展示出来。
其实是属于额外的除业务逻辑外的架构层次的工作。
3、Servlet耦合度过高
因为Servlet必须继承自HttpServlet,且内部与Servlet Api高度耦合,不但难以测试,而且难以重用。更不要说我们总是需要书写大量与业务逻辑无关的代码。其实就是不想编写过多与框架有关的代码。仅仅写逻辑代码。
三、MVC框架
上述所描述的得陇望蜀的问题,MVC框架都提供了一站式解决。
MVC框架能帮我们做什么?
框架和普通库的几点区别里,个人认为最重要的一点是控制反转。
框架规定了开发者写哪些代码/不写哪些代码,怎么写代码——这就是框架主要解决的问题。
MVC框架实现了MVC模式。什么意思?
意思是只要你根据框架的要求填充代码,你就能够很简单的实现MVC模式。
谁来响应用户请求?
框架可能告诉你,Action(Struts)就是用来响应用户请求的。
不用再继承HttpServlet,代码中也可以完全脱离ServletApi。复用度高,可单元测试。(其实本质上Action或者Controller(Spring)都是对Servlet进行了封装,本质上还是由Servlet进行控制层的工作)
谁负责生成响应界面?
框架可能告诉你,可以用一个JSP文件来生成界面。
也可以用其他视图技术,JfreeChart,FreeMarke,JasperReports,JSF,Tiles,Vlocit等。
如何将网址匹配到Action?
框架可能告诉你,在XML文件中配置,且可以分模块配置。
如何确定该返回那个JSP?框架可能告诉你,在XML文件中配置好了,Action返回SUCCESS,INPUT,LOGIN等等即可。
Action如何接受参数?
框架可能告诉你,写个Setter方法,就可以接受相应参数。不用再从request获取,且类型可自动转换。根据配置处理编码问题。
Action如何与视图交互?
框架可能告诉你,Action自动与视图绑定,在Action写一个Getter方法,试图层就可以用自定义标签获取其值。
输入校验如何进行?
写个validate方法,有错误就调用addActionError方法,自动返回配置中,INPUT指定的页面,页面用<s:actionerrors/>标签就可以自动输出错误信息。
也可以使用addFieldError方法添加特定field的错误,使用<s:fielderror/>输出特定field的错误信息。
甚至使用<s:textfield>方法生成的输入框,可以自动显示该字段的错误信息。
业务流程的处理?
仍旧是我们前面提到的JavaBean,JavaBean其实就是符合一定标准的Java类,不同与Servlet,其不需要继承特殊的父类,只是对业务方法进行封装。方便在Servlet中进行调用。对于JavaBean的具体说明,可以参考JavaBean简单及使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值