单机时代:桌面应用
桌面应用俗称单机应用,软件所有数据都保存在电脑本地硬盘中。
优点:易于使用,结构简单。
缺点:数据难以共享、安全性差、更新不及时。
联机时代:Client-Server模式
典型应用:QQ,微信,支付宝。
互联网时代:Browser-Server模式
典型应用:百度,淘宝,京东
B/S模式执行流程
用户写上网址baidu.com后,浏览器根据DNS服务器得知该网址对应的ip地址,然后通过http协议将其发送到远程的服务器主机,服务器主机的服务器程序动态地生成了html文档。
html文档会返回给浏览器。浏览器对html进行解析,用户就能看到他想看到的了。
请求与相应
请求和响应必须成对出现。
J2EE
13个模块如下:
要重点学习的:
Apache Tomcat
一个Web应用服务器程序。
J2EE与Tomcat的关系
Servlet
我们可以把Tomcat看成服务器主机,Servlet看成服务器程序。
这是我们的第一个Servlet:
//一定要继承HttpServlet
public class FirstServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收请求发来的参数
String name=request.getParameter("name");
String html="hi,"
+name+"!";
System.out.println("返回给浏览器的html为:");
PrintWriter out=response.getWriter();
//将html发送回浏览器
out.println(html);
}
}
要在工程的WEB-INF中配置web.xml:
这是我们添加的xml。
<servlet>
<servlet-name>firstservlet-name>
<servlet-class>com.servlet.FirstServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>firstservlet-name>
<url-pattern>/hiurl-pattern>
servlet-mapping>
然后点击debug,然后:
在浏览器中输入:localhost:8080
——这是Tomcat;
输入:localhost:8080/FirstServlet/hi
,这是我们刚刚写的:
可以打一个?表示参数:
图解执行流程
输入的是/hi,url-pattern为/hi对应的servlet-name为first,servlet-name为first对应的servlet-class为com.imooc.servlet.FirstServlet,这就是我们写java代码的地方。
举个例子
我们刚刚发布了一个FirstServlet。
我们在Tomcat的文件夹中能发现:
点开FirstServlet会看到META-INF和WEB-INF。
WEB-INF下会有classes、lib、和web.xml:
web.xml就是我们刚刚配置xml的文件。
把classes一直往下点,会看到FirstServlet.class,就是我们刚刚写java的地方。
lib保存的是第三方的jar包,不过现在还没有。
Eclipse会和Tomcat整合在一起。
默认首页
在webapp下创建一个index.html:
这就是我们FirstServlet的默认首页:在浏览器中输入:localhost:8080/FirstServlet/
举个例子
前两步:
//创建Servlet类,继承HttpServlet
public class SampleServlet extends HttpServlet {
// 重写service方法,编写程序代码
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 向浏览器输出的数据流
PrintWriter out = response.getWriter();// 这里有一个异常,我们这里抛出
out.println("My Blog");
}
}
第三步:
<servlet>
<servlet-name>sampleservlet-name>
<servlet-class>com.servlet.SampleServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>sampleservlet-name>
<url-pattern>/sampleurl-pattern>
servlet-mapping>
Servlet访问方法
按照上面提过的方法把工程添加到Server中,点击debug,然后在浏览器中输入http://localhost:8080/FirstServlet/sample
点进去后就是我的博客了。
参数名1=值1&参数名2=值2&...
,可以用&
连接多个参数举个例子
我们在webapp下新增一个html文件:
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学生信息登记表title>
head>
<body>
<h1>学生信息登记表h1>
<form action="http://localhost:8080/FirstServlet/sample">
姓名:<input name="name" /> <br/>
电话:<input name="mobile" /> <br/>
性别:
<select name="sex" style="width: 100px; padding: 5px;">
<option value="male">男option>
<option value="female">女option>
select>
特长:
<input type="checkbox" name="spec" value="English"/>英语
<input type="checkbox" name="spec" value="Program"/>编程
<input type="checkbox" name="spec" value="Speech"/>演讲
<input type="checkbox" name="spec" value="Swimming"/>游泳
<br/>
<input type="submit" value="提交">
<br/>
form>
body>
html>
我们这样填写:
点击提交后,页面跳转到:“http://localhost:8080/FirstServlet/sample”
我们可以看到它的参数是:name=Tom&mobile=12345678&sex=male&spec=English&spec=Program
就是我们填的参数,且键与值用=连接,键值对之间用&连接。
这就是请求参数。
实际上:
<form action="http://localhost:8080/FirstServlet/sample">
可以简化成如下,因为http://localhost:8080
是默认地址。
<form action="/FirstServlet/sample">
Servlet接收请求参数
request.getParameter()
- 接受单个参数(一般用这个)request.getParameterValues()
- 接收多个同名参数(复选框可以用这个)public class SampleServlet extends HttpServlet {
// 重写service方法,编写程序代码
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
//获取单个请求参数
String name=request.getParameter("name");
// 向浏览器输出的数据流
PrintWriter out = response.getWriter();// 这里有一个异常,我们这里抛出
out.println("name:"
+name+"");
}
}
我们在表单中填入姓名Tom。
则:
举一反三,把其他信息全部输出:
//创建servlet类,继承HttpServlet
public class SampleServlet extends HttpServlet {
// 重写service方法,编写程序代码
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取单个请求参数
String name = request.getParameter("name");
String mobile = request.getParameter("mobile");
String sex = request.getParameter("sex");
String[] specs = request.getParameterValues("spec");
// 向浏览器输出的数据流
PrintWriter out = response.getWriter();// 这里有一个异常,我们这里抛出
out.println("name:"
+ name + "");
out.println("mobile:"
+ mobile + "");
out.println("sex:"
+ sex + "");
out.println("specs:");
for (int i = 0; i < specs.length; i++) {
out.print(specs[i] + " ");
}
}
}
把所有都填上:
则:
且网址如下:
http://localhost:8080/FirstServlet/sample?name=Tom&mobile=123456789&sex=male&spec=English&spec=Program&spec=Speech&spec=Swimming
也可以通过地址栏传递参数:
Get方式是将数据通过在URL附加数据显性向服务器发送数据。
如:http://localhost:8080/FirstServlet/sample ?name=Tom
Post方式会将数据存放在"请求体"中隐性向服务器发送数据。
如:
http://localhost:8080/FirstServlet/sample
请求体:name=Tom
表单提交默认是get方法,我们可以用post方法:
<form action="/FirstServlet/sample" method="post">
URL后没有参数了。
在浏览器F12:点击NetWork,点击sample,点击Response,可以看到:
Get和Post传递的数据格式完全相同(都是键=值&键=值
),只是存放的地址不同。
与service方法的关系
service()
是请求处理的核心方法,无论是get还是post都会被service()
方法处理request.getMethod()
方法得知是用get方法还是post方法用于专门处理get和post——get和post是可以分别进行处理的
代码:我们让get方法写绿色,post方法写红色。
public class RequestMethodServlet extends HttpServlet{
//处理get请求
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException {
String name=request.getParameter("name");
response.getWriter().println(""
+name+"");
}
//处理post请求
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException {
String name=request.getParameter("name");
response.getWriter().println(""
+name+"");
}
}
配置xml:一般url中都小写,单词间用_连接
<servlet>
<servlet-name>requestMethodservlet-name>
<servlet-class>com.servlet.RequestMethodServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>requestMethodservlet-name>
<url-pattern>/request_methodurl-pattern>
servlet-mapping>
get时:
<form action="/FirstServlet/request_method" method="get">
看url,很明显这是get:
post时:
Get和Post处理方式小总结
如果没有将service重写,那么它就相当于get和post的分发器:若这是一个get,它就把它交给doGet处理,反之亦然。
应用场景:
用代码演示一下:
public class FirstServlet extends HttpServlet {
public FirstServlet() {
System.out.println("正在 创建 Servlet对象");
}
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("正在 初始化 Servlet对象");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接收请求发来的参数
String name = request.getParameter("name");
String html = "hi,"
+ name + "!";
System.out.println("返回给浏览器的html为:");
PrintWriter out = response.getWriter();
// 将html发送回浏览器
out.println(html);
}
@Override
public void destroy() {
System.out.println("正在 销毁 Servlet对象");
}
}
启动Servlet,访问网址:http://localhost:8080/FirstServlet/hi
则控制台:
正在 创建 Servlet对象
正在 初始化 Servlet对象
返回给浏览器的html为:
随便修改一下代码内容再保存,则就销毁:
PS:我刷新了几次页面,所以返回给浏览器的html为:
不止一个。
因为我们保存以后Tomcat会自动销毁对象,然后重新加载一个新的对象。此时如果再刷新,就会再创建一个新的对象。
对于每一个Servlet来说,在运行时有且只有一个Servlet对象在服务。
举个例子
//注解,参数是绑定的url-pattern
@WebServlet("/anno")
public class AnnotationServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("I am annotation servlet!");
}
}
则:
设置启动时加载0~9999
举个例子
假设现在我们开发一个系统,在系统启动的时候要自动完成初始化数据库、导入数据、统计分析这三个工作。
我们希望CreateServlet负责创建数据库,在程序启动的时候自动完成这个工作。
java:
public class CreateServlet extends HttpServlet{
//要重写init
@Override
public void init() throws ServletException{
System.out.println("正在创建数据库");
}
}
web.xml配置:
<servlet>
<servlet-name>createservlet-name>
<servlet-class>com.servlet.CreateServletservlet-class>
<load-on-startup>0load-on-startup>
servlet>
控制台:
我们再创建一个ImportServlet,用来自动导入数据。代码与上面相似,只是xml的
是1.
控制台:
再创建一个分析结果的:用注解的时候一定要绑定一个url。
@WebServlet(urlPatterns="/unused",loadOnStartup=2)
public class AnalysisServlet extends HttpServlet{
//要重写init
@Override
public void init() throws ServletException{
System.out.println("正在分析结果");
}
}
运行后控制台: