目录
Servlet & Jsp 世界中的MVC 模式:
以Servlet为控制器(control),Jsp 显示视图(view),普通 Java 类为模型(model)。
在每一项服务(请求+响应)的背后,都应该是一套 MVC模式:
更具体一些:
用户从浏览器发出一条请求,通过http协议传输到web服务器,web服务器发现这是一条动态的请求,那么就会将该请求交给tomcat容器处理。tomcat容器找到该条指令对应的servlet的.class文件,启动其service()函数运行。在这个运行过程中会调用Java类模型来实现对传过来的请求处理,处理结果再通过请求传输到一个jsp文件中,最终将这个jsp页面通过tomcat容器返还给用户。
本文将创建一个十分简单的 JavaWeb应用,主要上手熟悉idea开发环境下的 MVC 模式的项目开发。主要注意:在 Tomcat 容器对 Servlet 和 Jsp 组件的管理下,我们应该如何部署一个应用。
注:jsp实际就是再html页面插入了java代码,仅此而已!
一、创建一个JavaWeb项目,完成html页面
1、创建项目
首先,正确地在idea下创建一个全新的JavaWeb项目,名字为JeffChang's Concert。具体操作可以参考 : idea 配置一个 JavaWeb 项目
该项目主要用来查询张信哲第11轮世界巡回演唱会的信息,首页会有一个表单选择年份,用户提交表单后会弹出结果页面,告诉用户该年内用哪些城市的演唱会信息。So cool!
2、编写首页面
修改 index.jsp 文件(这是我们这个项目的默认页面),代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JeffChang's Concert</title>
</head>
<body>
<h1 align="center">Welcome to JeffChang's Concert Page!</h1>
<h2 align="center">Year Select Page</h2>
<form method="POST" action="query.do"> <!-- action即当用户提交这个表单时,将传递给url名为query.do的servlet -->
Select year:
<p>
<!-- 创建一个下拉菜单-->
<select name="year" size="1">
<option value="2018"> 2018 </option>
<option value="2019"> 2019 </option>
<option value="2020"> 2020 </option>
</select>
<br><br>
<div style="text-align: center;">
<input type="SUBMIT">
</div>
</form>
</body>
</html>
写好后,直接运行,看看是否有误。网页应该如下显示:
此时选择一个年份提交表单,会出现404错误❗。因为我们并没有实现表单action属性所指向的servlet,所以当你提交表单时,tomcat会将你的请求传递给action属性所指向的servlet,但是找不到,所以出现404。
二、配置web.xml文件,将url映射到servlet
web.xml文件是tomcat容器的部署文件。用户发出一个请求时,会向web服务器传递一个url,这个url就是要通过tomcat来映射到某一个servlet来做出相应的反应。
web.xml文件代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<!-- 对应mapping中某一个servlet的内部名 -->
<servlet-name>name1</servlet-name>
<!-- 当收到请求时,要调用的Java类的相对路径(相对classes文件) -->
<servlet-class></servlet-class>
</servlet>
<servlet-mapping>
<!-- 为了方便部署,给这个servlet取一个内部名 -->
<servlet-name>name1</servlet-name>
<!-- 在index.jsp页面中对应的某表单action属性 -->
<url-pattern>/query.do</url-pattern>
</servlet-mapping>
</web-app>
注意,此时并没有将servlet-class加入,因为我们还没有写servlet对应——Java类。后面会加入的。
此时,运行一下,随便选择一个时间,提交表单试试:
此时会报错500,但不是之前的404了!因为我们已经部署了url与servlet的映射,只是这个servlet还没有实现一个java类~
三、为servlet实现一个Java类
1、创建该servlet的模型
MVC中 M 即代表模型,是一堆后端的纯Java代码。servlet的Java类通过调用这个模型来实现对用户发来请求的计算,从而得到相应的结果。所以说,要为servlet实现一个Java类,必须先实现一个对应的模型。
在项目的src目录下,新建一个Concert类,并实现一个getConcertList的方法:
import java.util.ArrayList;
import java.util.List;
public class Concert {
private String time; //演唱会的时间
private String region; //演唱会的地区
private int num; //巡演的场次
public Concert() { }
public Concert (int num, String time, String region) {
this.num = num;
this.region = region;
this.time = time;
}
public List getConcertList(String year) {
List concertList = new ArrayList();
if(year.equals("2018")) {
concertList.add(new Concert(1,"2018-10-13","北京-五棵松体育馆"));
concertList.add(new Concert(2,"2018-10-14","北京-五棵松体育馆"));
concertList.add(new Concert(3,"2018-11-02","澳门-金光综艺馆"));
concertList.add(new Concert(4,"2018-12-22","深圳-深圳湾体育中心"));
}
else if(year.equals("2019")) {
concertList.add(new Concert(5,"2019-01-19","成都-成都大魔方"));
concertList.add(new Concert(6,"2019-04-06","台北-小巨蛋"));
concertList.add(new Concert(7,"2019-04-13","广州-广州宝能体育中心"));
concertList.add(new Concert(8,"2019-04-27","南京-青奥体育公园体育馆"));
concertList.add(new Concert(9,"2019-05-11","新加坡-室内体育馆"));
concertList.add(new Concert(10,"2019-6-08","济南-济南奥体中心体育馆"));
concertList.add(new Concert(11,"2019-6-22","苏州-苏州奥体中心体育馆"));
concertList.add(new Concert(12,"2019-6-29","福州-海峡奥体综合体育馆"));
concertList.add(new Concert(13,"2019-7-13","马来西亚-云顶云星剧场"));
concertList.add(new Concert(14,"2019-7-14","马来西亚-云顶云星剧场"));
concertList.add(new Concert(15,"2019-7-26","大连-大连体育中心体育馆"));
concertList.add(new Concert(16,"2019-8-17","重庆-华熙文化体育中心"));
concertList.add(new Concert(17,"2019-11-16","佛山-国际体育文化演艺中心"));
concertList.add(new Concert(18,"2019-11-23","宁波-奥体中心体育馆"));
concertList.add(new Concert(19,"2019-11-30","长沙-国际会展中心"));
concertList.add(new Concert(20,"2019-12-14","上海-梅赛德斯奔驰体育中心"));
concertList.add(new Concert(21,"2019-12-15","上海-梅赛德斯奔驰体育中心"));
concertList.add(new Concert(22,"2019-12-22","沈阳-辽宁省体育馆"));
} else if(year.equals("2020")) {
concertList.add(new Concert(23,"2020-01-01","无锡-无锡市体育馆"));
concertList.add(new Concert(24,"2020-04-28","英国-伦敦皇家阿尔伯特音乐厅"));
}
return concertList;
}
public String toString() {
return "第"+this.num+"场 - " + this.time + " : " + this.region + "\n";
}
}
2、为servlet实现一个Java类
在项目的src目录下,新建一个YearQueryServlet类,必须继承HttpServlet,并且重写doPost方法(不要留下super.doPost(req, resp);这一条语句)。并且从Concert.java模型获取信息,传递到jsp视图页面。
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class YearQueryServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/* 从模型获取答案*/
String year = req.getParameter("year"); //从请求的信息(表单)内,找到name属性为year的表单,并获取用户提交的结果
Concert concert = new Concert();
List ans = concert.getConcertList(year);
/* 将模型组件的贵大增加到请求对象 */
req.setAttribute("styles", ans); //为请求对象增加一个属性,其值为ans,供给jsp使用
RequestDispatcher view = req.getRequestDispatcher("YearQueryResult.jsp"); //为jsp实例化一个请求分派器
view.forward(req, resp); //使用请求分派器要求容器准备好jsp,并向jsp发送请求和响应
}
}
将Servlet对应的继承了HttpServlet的Java类的位置补充到servlet-class:
<!-- 当收到请求时,要调用的Java类的相对路径(相对classes文件) -->
<servlet-class>YearQueryServlet</servlet-class>
注:这里还没有写"YearQueryResult.jsp"的视图文件,仅仅搭建了servlet利用模型得来的结果和jsp文件的传输桥梁。
此时,再运行这个程序,并随便选择一个年份提交表单。可以看到一个404错误,网页中错误的详细描述为:/JeffChang%20Concert/YearQueryResult.jsp,即找不到对应的jsp视图文件。ok,说明我们的桥梁已经搭建成功,只是缺少了jsp视图文件。
四、实现对应的 Jsp 视图文件
在项目的web目录下创建一个jsp文件 —— YearQueryResult.jsp文件。并且将我们需要返回的视图代码写入:
之前有强调:jsp实际就是再html页面插入了java代码。在写入java代码时,我们要写在符号 <% %>内
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JeffChang's Concert</title>
</head>
<body>
<h1 align="center">张信哲第11轮世界巡回演唱会 - 未来式</h1>
<p>
<%
List styles = (List)request.getAttribute("styles"); //从请求对象得到一个属性(就是答案)
/* 将结果显示在网页上 */
Iterator it = styles.iterator();
while (it.hasNext())
out.println(it.next() + "<br>");
%>
</p>
</body>
</html>
本项的文件目录如下:
一个简单的MVC程序就完成了,下面来简单地测试一下:
直接运行,走起——
分别提供2018、2019、2020都表单,结果如下:
yeah!大功告成~
end
欢迎关注个人公众号“ 鸡翅编程 ”,这里是认真且乖巧的码农一枚。
---- 做最乖巧的博客er,做最扎实的程序员 ----
旨在用心写好每一篇文章,平常会把笔记汇总成推送更新~