JavaWeb-3、Servlet
JavaWeb-3、Servlet1、Servlet简介Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于
JavaWeb-3、Servlet
1、Servlet简介
Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
2、HelloServlet
好了,废话不多说,我们先写一个简单的小DEMO看看Servlet如何使用!
首先我们创建maven一个项目,模板选择webapp模板。
稍微标记一下各个文件夹!
导入一下jsp和servlet的相关依赖。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
现在我们创建一个类,此类继承一下HttpServlet类。
在上文中我们提到,一个类实现servlet接口即可成为一个广义的Servlet类。
我们点开httpservlet的源码康康,我们可以发现httpservlet又继承了GenericServlet,GenericServlet又实现了servlet接口。
所以我们的类结构是这样的:
我们在我们的实现类上实现下doget和dopost方法。
一般表单是使用post方法进行提交,这里我们使用doget方法即可!
以下是具体代码。
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//拿一下输出流
PrintWriter writer = resp.getWriter();
//在网页上打一个hello servlet!
writer.println("hello servlet!");
}
//这个暂时不用
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
之后我们要在相关的web.xml上配置servlet
<servlet>
<!-- 名字-->
<servlet-name>hello-servlet</servlet-name>
<!-- servlet对应的类-->
<servlet-class>helloServlet</servlet-class>
</servlet>
<!-- 映射标签-->
<servlet-mapping>
<!-- 对应的servlet名字-->
<servlet-name>hello-servlet</servlet-name>
<!-- 项目url-->
<url-pattern>/jj</url-pattern>
</servlet-mapping>
这里我们把这个servlet类命名为hello-servlet,他要访问项目下的jj来访问。
配置下tomcat,把项目访问目录设为/jj,启动运行下!
完美无瑕!
3、servlet原理
下面引用b站狂神老师的一张图结合着聊一聊
当我们的浏览器给web容器发送请求时,主要进行了以下的步骤操作:
- 判断是否为首次访问,如是首次访问则创建相关servlet类
- 将网页的请求以及相应交给我们编写的servlet类
- 执行类中的方法
- web容器读取响应的信息,然后返回给客户端。
4、mapping问题
在这里我们可以创建以下几种映射
1、单映射
这种就是我们平时最常用的,一个页面对应一个映射的写法
<servlet-mapping>
<servlet-name>hello-servlet</servlet-name>
<url-pattern>/jj</url-pattern>
</servlet-mapping>
2、多映射
我们可以为一个页面设置多个映射,比如说我们把/jj2也设置为hello-servlet的映射,这种方式也是可以的。
<servlet-mapping>
<servlet-name>hello-servlet</servlet-name>
<url-pattern>/jj</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello-servlet</servlet-name>
<url-pattern>/jj2</url-pattern>
</servlet-mapping>
3、全局映射
我们可以通过正则表达式设置全局映射。
<servlet-mapping>
<servlet-name>hello-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
4、后缀映射
<servlet-mapping>
<servlet-name>hello-servlet</servlet-name>
<url-pattern>*.jj</url-pattern>
</servlet-mapping>
我们可以以.jj结尾的方式映射hello–servlet,注意这种写法前面不能加路径,比如说不能/*.jj这种写法。
5、servletContext
ServletContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。
也就是说,不管我们项目里拥有多少servlet的类,但是项目中却只有一个servletContext,servletContext一般可以用来执行以下操作。
(1)数据共享
我们平常可以使用servletContext进行数据共享的操作,下面我们来举一个例子。
首先先写两个servlet类,并将其注册到web.xml中。
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取servletContext
ServletContext servletContext = this.getServletContext();
// 在其中设置username属性
servletContext.setAttribute("username","dirtyLily");
System.out.println("设置ok");
}
}
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
//获取servletContext中的username属性
String username = (String) servletContext.getAttribute("username");
//设置一下页面格式以及编码等信息
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().println("名字是:"+username);
}
}
配置tomcat,依次运行二者。
最后发现第二个servlet可以调取第一个servlet中设置的属性,这就是二者传值的一些操作。
(2)获取初始参数
这里我们先在web.xml中定义一个参数
<context-param>
<param-name>user</param-name>
<param-value>zjj</param-value>
</context-param>
之后编写一个servlet类
public class ThirdServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
//获取名字叫user的初始化参数
String user = servletContext.getInitParameter("user");
resp.getWriter().println(user);
}
}
注册下servlet,我们运行一下发现,可以取到相关参数。
(3)请求转发
在servlet中如果我们希望在访问一个界面时自动跳转到另一个界面,我们可以使用servlet中请求转发的功能。
我们可以使用servlet中的getRequestDispatcher方法来定义转发的地址,之后调用forward完成跳转,具体代码如下:
public class FourthServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
//跳转到third
servletContext.getRequestDispatcher("/third").forward(req,resp);
}
}
注册下,运行结果为
我们发现上面的url地址依然是fourth,但是内容是third的内容。
(4)获取资源文件
我们首先在resource文件夹里定义一个properties文件,里面写一个属性。
handSomeboy=zjj
编写一个servlet类来读取这个properties
public class FifthServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
//读取流文件
InputStream resourceAsStream = servletContext.getResourceAsStream("/WEB-INF/classes/jj.properties");
Properties prop = new Properties();
//载入
prop.load(resourceAsStream);
String handSomeboy = prop.getProperty("handSomeboy");
resp.getWriter().println(handSomeboy);
}
}
最后输出的结果
ok的!
6、HttpServletResponse
在servlet中主要分为请求HttpServletRequest,以及HttpServletResponse两种。
在Response中,我们在其中执行一些操作。
(1)使用response下载文件
使用response可以对我们电脑中的资源进行下载。主要步骤以及代码如下:
首先先创建一个servlet类
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
// 1、获取下载文件路径
String path = "E:\\code\\servlet\\3Responce\\src\\main\\resource\\xjn.jpg";
System.out.println(path);
//2、获取文件名
//最后一个\后面开始就是文件名
String name = path.substring(path.lastIndexOf("\\") + 1);
//3、设置浏览器支持
resp.setHeader("Content-Disposition", "attachment;filename="+name);
//4、获取输入流
FileInputStream inputStream = new FileInputStream(path);
//5、创建缓冲区
byte[] buffer = new byte[1024];
//6、获取outputstream
ServletOutputStream os = resp.getOutputStream();
//7、写入
int len;
while((len=(inputStream.read(buffer)))!=-1){
os.write(buffer,0,len);
}
inputStream.close();
os.close();
}
弹出了下载窗口!
下载出来还真是小俊男!
太猛了!!
(2)使用response实现验证码功能
我们平常在进行登录的时候,经常需要输入相关的验证码,我们使用response也可以大概模拟出这种效果,来写一下看看:
还是新创建一个servlet类,命名为imageservlet,代码及相关注释如下:
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器每三秒刷新一次
resp.setHeader("refresh","3");
//初始化图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
//画个白背景
g.setColor(Color.white);
g.fillRect(0,0,80,20);
g.setColor(Color.black);
//画字体
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(getString(),0,20);
//请求使用图片方式打开
resp.setContentType("image/jpeg");
//不让网站使用缓存机制
resp.setDateHeader("expire",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//获取随机数的类
private String getString() {
Random random = new Random();
int i = random.nextInt(9999999);
String num = String.valueOf(i);
StringBuilder stringBuilder = new StringBuilder(i);
//保持获取数字的位数为7位
for(int q =0;q<7-num.length();q++){
stringBuilder.append(0);
}
num = num+stringBuilder.toString();
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册后运行看一下:
浏览器还真是每三秒刷新一组新数字啊!
(3)实现重定向
实现重定向主要要使用response中的sendRedirect方法,这里我们写一个登录的小demo看看。
这里我们还是创建一个servlet。
首先我们把index界面改成一个表单
<html>
<body>
<h2>Hello World!</h2>
<%--action中语句的意思是拿到当前目录,以后会学到--%>
<form action="${pageContext.request.contextPath}/l" method="get">
用户名:<input name="username" type="text">
密码:<input name="password" type="password">
<button type="submit">提交</button>
</form>
</body>
</html>
在servlet类中处理相关请求
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了方法");
//拿到两个属性
System.out.println(req.getParameter("username"));
System.out.println(req.getParameter("password"));.
//重定向到一个新写的success界面
resp.sendRedirect("/r/success.jsp");
}
}
注册,部署运行下!我们可以发现方法成功拿到了我们设置的类,并且重定向到了相关页面
所以说转发和重定向的异同在哪儿呢?
相同点:
- 都实现了页面的跳转
不同点:
- 转发的页面url没有变化,而重定向的页面url会产生改变
7、HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
这里我们还是还是通过一个小demo来看看如何使用他!!
我们先修改下之前的index页面,使其中添加相关的多选框,然后把action修改下,这次我们使用post方式进行接收,所以方法也变成post
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<%--action中语句的意思是拿到当前目录,以后会学到--%>
<form action="${pageContext.request.contextPath}/t" method="post">
用户名:<input name="username" type="text">
密码:<input name="password" type="password">
<input name="hobby" type="checkbox" value="学习">学习
<input name="hobby" type="checkbox" value="游泳">游泳
<input name="hobby" type="checkbox" value="吃饭">吃饭
<input name="hobby" type="checkbox" value="打游戏">打游戏
<button type="submit">提交</button>
</form>
</body>
</html>
这里我们创建一个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.lang.reflect.Array;
import java.util.Arrays;
public class RequestTest extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//获取相关属性
System.out.println(req.getParameter("username"));
System.out.println(req.getParameter("password"));
//这个getParameterValues可以获取多个值,返回String类型数组
String[] hobbies = req.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies));
//使用req转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
注册,启动tomcat看下。
发现可以正常取得相关参数,页面也完成跳转。
更多推荐
所有评论(0)