文章目录
Servlet工程创建
-
在idea初始界面点击Create new Project开始创建项目
-
在菜单栏中选择Java Enterprise。勾选Web Application,并选中Create web.xml让idea自动生成web.xml文件。(若没有配置JDK与Tomcat可点击对应菜单后的new添加相关环境)
-
编写完成后,配置Tomcat,点击Add Configuration增加Tomcat配置
-
点击“+”添加Tomcat Server选择Local。在Server界面填写必要信息。
-
切换到Deployment界面,添加发布任务。点击“+”选择Artifact…并在下方修改上下文路径,修改Application context后Server界面中的URL会自动改变。
-
完成配置后,点击debug运行程序,在浏览器中输入地址即可访问该项目
Servlet响应流程
- 浏览器通过访问地址向服务端(Tomcat)发起请求(request)
- 服务端(Tomcat)通过解析web.xml文件中的
servlet-name
找到对应的需要执行的类 - 执行
service()
方法,将结果返回(response)给浏览器并展示
标准Java Web工程结构
Servlet工程示例
- 创建Servlet类
package com.servlet;
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.io.PrintWriter;
public class Demo extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取浏览器请求中的name参数
String name = req.getParameter("name");
String html = "<h1 style='color:red'>Hi," + name + "!</h1><hr />";
System.out.println(html);
// 调用HttpServletResponse类中的getWriter()方法将内容返回给浏览器
PrintWriter out = resp.getWriter();
out.println(html);
}
}
- 配置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>
<!-- 创建servlet别名,用于标记该servlet -->
<servlet-name>ServletDemo</servlet-name>
<!-- 填写servlet类的路径 -->
<servlet-class>com.servlet.Demo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo</servlet-name>
<!-- 浏览器的访问路径 -->
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
- 浏览器访问地址
浏览器的访问地址按一下规则构成:
http://IP地址:端口/Context-Path/url-mapping
IP地址:如果为本地访问,可以填写
localhost
或127.0.0.1
,若非本地访问需填写服务器所在的真实IP地址
端口:服务端配置的端口,默认为8080
Context-Path:上下文路径,默认为工程名
url-mapping:web.xml中配置的url-mapping
中的路径
- 效果
通过更改地址中的name变量的值,可以获得不同的结果。
Servlet请求参数
参数请求一般是指浏览器向Tomcat提交的数据,一般来说是用户输入提交给Servlet进行处理。在浏览器地址中体现为地址后跟一个"?“接参数名=值,若有多个参数以”&"连接,例如:
http://localhost:8080/ServletDemo/Calculator?add1=13&add2=99
在Servlet类中,一般通过
HttpServletRequest
类的getParameter()
和getParameterValues()
方法获取参数。
getParameter()
用于获取单个参数
getParameterValues()
用来获取多个参数,返回String数组
示例:通过页面输入两个值,计算两值的和
package com.servlet;
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.io.PrintWriter;
public class Calculator extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String add1 = req.getParameter("add1");
String add2 = req.getParameter("add2");
System.out.println("Calculator result:" + (Integer.parseInt(add1) + Integer.parseInt(add2)));
String html = "<p>Addition Calculator:</p>";
html += "<p>Calculator result:" + (Integer.parseInt(add1) + Integer.parseInt(add2)) + "</p>";
PrintWriter writer = resp.getWriter();
writer.println(html);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Calculator</title>
</head>
<body>
<h1>加法计算器</h1>
<form action="/ServletDemo/Calculator">
加数1:<input type="text" name="add1">
加数2:<input type="text" name="add2">
<input type="submit">
</form>
</body>
</html>
省略web.xml文件配置
效果:
在输入栏中填入数值,点击提交,跳转至结果界面
可以看到在地址栏中有Calculator.html中填入的数值,及浏览器向服务端请求的参数。
Get和Post请求
提交表单信息,向服务端发送请求存在两种请求方式:
- Get:将数据通过写在URL中显性的将数据发送给服务端,例如上方示例。
- Post:将数据存放在"请求体"中隐形的向服务器发送数据。
serivce()方法获取参数请求
当form表单的请求方式为Post的时,浏览器地址栏是不带有任何参数信息,而是在请求体中。
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Personal information</title>
</head>
<body>
<form action="/ServletDemo/Information" method="post">
<h3>个人信息</h3>
姓名:<input type="text" name="name"/><br/>
性别:
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女"/>女<br/>
联系方式:<input type="text" name="phone"/><br/>
爱好:
<input type="checkbox" name="hobby" value="游泳"/>游泳
<input type="checkbox" name="hobby" value="乒乓球"/>乒乓球
<input type="checkbox" name="hobby" value="羽毛球"/>羽毛球
<input type="checkbox" name="hobby" value="跑步"/>跑步
<input type="checkbox" name="hobby" value="射箭"/>射箭
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
package com.servlet;
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.io.PrintWriter;
public class Information extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
String name = req.getParameter("name");
String sex = req.getParameter("sex");
String phone = req.getParameter("phone");
String[] hobbys = req.getParameterValues("hobby");
PrintWriter out = resp.getWriter();
out.println("<p>姓名:" + name + "</p>");
out.println("<p>性别:" + sex + "</p>");
out.println("<p>联系方式:" + phone + "</p>");
for (String hobby : hobbys) {
out.println("<p>爱好:" + hobby + "</p>");
}
}
}
若表单中不填写method默认按照Get方法向服务器请求
doGet()和doPost()方法获取请求参数
通过doGet()
和doPost()
方法,可以将两种请求分开处理,doGet()
方法处理Get请求,doPost()
方法处理Post请求。重新编写Information类,用doGet()
和doPost()
方法分别处理参数请求。
package com.servlet;
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.io.PrintWriter;
public class Information extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
PrintWriter out = resp.getWriter();
out.println("<h1 style='color:red'>Hello "+ name +"</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
PrintWriter out = resp.getWriter();
out.println("<h1 style='color:green'>Hello "+ name +"</h1>");
}
}
可以通过返回结果的样式看出,前端通过Post请求向服务器发送参数时,会执行doPost()方法;
在使用Get请求时,会执行doGet()方法。
Get请求常用在不包含敏感信息的查询功能,比如百度的搜索功能
Post请求一般用于安全性要求较高的功能或服务器的写操作,比如用户的登录和注册
Servlet生命周期
示例代码:
package com.servlet;
import javax.servlet.ServletConfig;
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.io.PrintWriter;
public class Demo extends HttpServlet {
public Demo() {
System.out.println("Demo构造方法");
}
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init初始化方法");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String html = "<h1 style='color:red'>Hi," + name + "!</h1><hr />";
System.out.println(html);
PrintWriter out = resp.getWriter();
out.println(html);
}
@Override
public void destroy() {
System.out.println("destroy销毁方法");
}
}
当开始访问页面时,通过web.xml来解析路径,找到对应的Servlet类,再通过类的构造函数创建Servlet类,之后通过Servlet类的init()方法来初始化,之后交由service()方法或doGet(),doPost()方法进行逻辑处理。
在服务停止时,完成Servlet的销毁。
在每个过程中只会产生一个Servlet类
注解配置Servlet
在Servlet3.x之后,引入了"Annotation"特性,简化了通过web.xml来配置Servlet的繁琐操作,可以通过在Servlet类前添加@WebServlet()
来进行配置。
示例:
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = "/Calculator")
public class Calculator extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String add1 = req.getParameter("add1");
String add2 = req.getParameter("add2");
System.out.println("Calculator result:" + (Integer.parseInt(add1) + Integer.parseInt(add2)));
String html = "<p>Addition Calculator:</p>";
html += "<p>Calculator result:" + (Integer.parseInt(add1) + Integer.parseInt(add2)) + "</p>";
PrintWriter writer = resp.getWriter();
writer.println(html);
}
}
启动时加载Servlet
在一些特定情况下,在启动Servlet时就需要执行某些任务时,这时就需要用到启动时加载Servlet。配置有两种方法,一种为配置web.xml文件,在该servlet中添加标签<load-on-startup>
,值为0-9999,数值越小,优先级越高;第二种是通过注解的方法,为Servlet类添加注解@WebServlet(urlPatterns = "/url", loadOnStartup = 0)
。
示例:
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ConnectDB extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("链接数据库");
}
}
<?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>
<servlet-name>ConnectDB</servlet-name>
<servlet-class>com.servlet.ConnectDB</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
</web-app>
注意:在添加注解时一定要添加访问地址,否则Servlet类无法正常加载,而使用web.xml增加配置时,可以不为Servlet绑定地址。