从无到有
上世纪90年代,随着Internet和浏览器的飞速发展,基于浏览器的B/S模式随之火爆发展起来。
最初,用户使用浏览器向WEB服务器发送的请求都是请求静态的资源,比如html、css等。
不过随着web技术的发展:根据用户请求,进行动态处理,并返回资源逐渐成为理所当然的必须要求。
Servlet
java 为了应对上述需求,就必然推出一种技术来支持动态需求,因此servlet技术诞生
在Sun公司刚刚推出JavaEE(Java企业版)时,推出了Servlet这个东西,命名就是Service+Applet,即服务小程序。在Servlet中可以通过挨着行输出Html等语句来实现页面的样式和输出,表现、逻辑、控制、业务全部混在Servlet类中,最多把模型层单独写出来。大概如下面这样:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorld extends HttpServlet {
//收到get请求时处理方法
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
这样就动态的生成了一个内容为Hello World!的HTML页面在浏览器上显示。
Servlet诞生后,Sun公司很快发现servlet编程很繁琐
- servlet代码有大量冗余代码,out输出就得写上百遍;
- 开发servlet必须精通网页前端和美工,你得非常不直观的在Servlet中写前端代码,这使得实现各种页面效果和风格非常困难。
JSP
所以,sun公司借鉴 微软的ASP,正式推出了JSP(Servlet1.1)
JSP技术,全称是Java Server Page,JSP中采用HTML语言直接生成界面,可以在界面中使用<% %>脚本标识嵌入Java代码,究其本质也是最终生成一个Servlet类来编译解析。如果要开发具有大量网页内容的网站,可以先使用网页编辑工具编写网页,然后在网页中嵌入处理代码即可。再来一个简单的例子:
一个简单的jsp例子:
<html>
<head><title>测试</title></head>
<body>
第一阶段<% String str = “test” ; out.println(str); %>
</body>
</html>
JSP就是在HTML页面,用<%%>嵌入Java代码,而不像Servlet用Java生成整个HTML页面。这样的好处其实显而易见,首先,前台工程师至少可以修改页面的样式了。
但是,虽然有这一点好处,并且开发比Servlet简单、方便得多(自动生成HTML文件,在其中添加Java代码就好),缺点依然是显而易见的:
- 前端开发人员需要看大量他看不懂的后端代码;
- 同样,后端开发人员也需要在复杂的前端代码中找到其能写<%JAVA代码%>的地方
例如:
<html>
<head>
<title>处理任务添加页面</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String age = request.getParameter("age");
int sex = Integer.parseInt(request.getParameter("sex"));
%>
<%
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_mvc_demo","root","root");
String sql = "INSERT INTO t_person(name,age,sex) VALUES(?,?,?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1,name);
ps.setString(2,age);
ps.setInt(3,sex);
ps.execute();
request.getRequestDispatcher("index.jsp").forward(request,response);
%>
</body>
</html>
JSP Model1第一代
JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。
JSP Model1第二代
JSP Model1第二代有所改进,把业务逻辑的内容放到了JavaBean中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。
JSP Model2
JSP Model2模式已经可以清晰的看到MVC完整的结构了。
- JSP:视图层,用来与用户打交道。负责接收用来的数据,以及显示数据给用户;
- Servlet:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;
- JavaBean:模型层,完成具体的业务工作,例如:开启、转账等。
JSP Model2适合多人合作开发大型的Web项目,各司其职,互不干涉,有利于开发中的分工,有利于组件的重用。但是,Web项目的开发难度加大,同时对开发人员的技术要求也提高了。
JavaWeb经典三层框架
我们常说的三层框架是由JavaWeb提出的,也就是说这是JavaWeb独有的!
所谓三层是表述层(WEB层)、业务逻辑层(Business Logic),以及数据访问层(Data Access)。
- WEB层:包含JSP和Servlet等与WEB相关的内容;
- 业务层:业务层中不包含JavaWeb API,它只关心业务逻辑;
- 数据层:封装了对数据库的访问细节;
注意,在业务层中不能出现JavaWeb API,例如request、response等。也就是说,业务层代码是可重用的,甚至可以应用到非Web环境中。业务层的每个方法可以理解成一个万能,例如转账业务方法。业务层依赖数据层,而Web层依赖业务层!
框架阶段
倡导了MVC思想的jsp+javabean+servlet出现,也存在问题:
- jsp页面中嵌入了很多java代码,使得结构很乱;
- 对于大型项目,servlet过多,转向频繁,流程,配置等不易集中管理
因而出现了struts框架
Struts
2001年6月,struts1.0出现,struts针对jsp推出了一套struts标签,从而使得jsp中没有了Java代码,结构清晰,功能强大。针对servlet,它提供了Action类来代替了servlet,这个Action类具有servlet的功能,并且能够进行一些请求过滤和自动转码的功能。
Spring
原本已经开起来很完美了,但是又有一个问题,就是我们在Action调用DAO、Java bean等对象的时候都需要在自身代码中构建它们的对象来使用,这样增加了程序的耦合性,这与我们:“高内聚、松耦合”的思想不符合,那么怎么解决这个问题呢?因而出现了Spring框架。
Spring框架有两大功能:IOC(控制反转)和AOP(面向切面的编程),其中IOC就是说:当一个类中想要调用另外一个类的对象时,不需要再通过new 关键字来创建,而是由Spring框架来负责:创建、分配和管理,从而降低了程序中的耦合性。而AOP可以用来做一些日志的打印和输出,用于提示程序执行过程中的一些具体信息等。
SpringMVC
最后struts和Spring的整合,由于每一个bean都要在Spring中注册,每一个URL都要在struts配置文件中配置。当bean很多和URL对应的请求很多的时候,配置文件无疑会是很庞大的,这个就会使得配置起来很麻烦的费力。那么还有没有更好的办法使得能够结合Spring的功能和struts的功能,但是又可以使配置文件不会批量的增加?因而SpringMVC出现了
SpringMVC通过“基于注解”的方式代替了struts,并且通过Controller类来代替和实现了Action的功能。由于是基于注解的,所以很多的配置信息放在了Controller类中配置,从而降低了.xml文件的配置复杂度。