一、Servlet
1、Servlet简介
-
Servlet是sun公司开发动态web的一门技术
-
sun在这些API中提供一个接口叫做:Servlet, 开发Servlet程序只需完成两个步骤:
-
编写一个类,实现Servlet接口。
-
把开发好的java类部署到web服务器中。
-
把实现了Servlet接口的Java程序叫做Servlet。
2、HelloServlet
Servlet接口在Sun公司有两个默认的实现类:HttpServlet, GenericServlet
1.构建一个普通的Maven项目,删掉里面的src目录,在这里建立Moudel;这个空的工程就是Maven的主工程。
2.关于Maven父子项目的理解:
-
父项目中会有:
-
子项目会有:
父项目的jar包子项目可以直接使用。
3、Maven环境优化
-
修改web.xml为最新的
-
将Maven的结构搭建完整
4、编写一个Servlet程序
-
编写一个普通类
-
实现一个Servlet接口,可以直接继承HttpServlet
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//相应流
writer.print("HelloServlet!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.编写Servlet的映射
为什么需要映射:我们写的java程序需要通过浏览器访问,而浏览器需要连接web服务器,,所以我们需要在web服务中注册我们的servlet,还需要给它配置一个路径(web.xml)。
<!-- 注册Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.hl.servlet.HelloServlet</servlet-class> </servlet> <!-- servlet的请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
4.配置Tomcat服务
注意项目发布的路径
5.测试
5、Mapping问题
-
一个Servlet可以指定一个映射路径
-
一个Servlet可以指定多个映射路径
-
一个Servlet可以指定通用映射路径
-
默认请求路径
-
指定一些后缀或前缀等等......
-
优先级问题
指定了固有的映射优先级最高,如果找不到会走默认的处理请求;
6、ServletContext
web容器在启动的时候,它会为每个web程序创建一个对应的ServletContext对象,它代表了当前的web应用;
1、共享数据
一个servlet的数据可以在另一个servlet中使用
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = "李白!";
context.setAttribute("user",username);//将一个数据保存在了这个ServletContext中
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String obj = (String) context.getAttribute("user");
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().print("user="+obj);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、获取初始化参数
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
<!-- 配置一些web应用初始化参数--> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:8080/mybatis</param-value> </context-param>
3、请求转发
访问路径不发生改变
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//请求转发
context.getRequestDispatcher("/gp").forward(req,resp);
}
4、读取资源文件
Properties
-
在java目录下新建properties
-
在resources目录下新建properties
发现:都被打包在同一个路径下:classes, 我们俗称这个路径为classpath;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(stream);
String username = prop.getProperty("username");
String password = prop.getProperty("password");
resp.getWriter().print(username+" : "+password);
}
7、Response
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRquest对象,代表响应的一个HttpServletResponse;
-
如果要获取请求过来的参数:找HttpServletRquest;
-
如果要获取响应的参数:HttpServletResponse;
常见应用
-
向浏览器输出数据。
-
下载文件
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取文件的下载路径
String realPath = this.getServletContext().getRealPath("/img.png");
System.out.println("下载文件的路径:"+realPath);
//2.下载文件名是啥
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3.让浏览器支持下载我们需要的东西,设置编码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//4.获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5.创建缓冲区
int len;
byte[] buffer = new byte[1024];
//6.获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7.让FileOutputStream流写入到buffer区,使用OutputStream写出
while ((len=in.read(buffer)) > 0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
验证码功能
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器3秒刷新一次;
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
//设置图片背景
g.setColor(Color.WHITE);
g.fillRect(0,0,80,20);
//给图片写数据,生成随机数
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String s = random.nextInt(9999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i <4-s.length() ; i++) {
sb.append("0");
}
s=sb.toString()+s;
return s;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.请求重定向( sendRedirect() )
一个web资源收到客户端请求后,他会通知客户端去访问另一个web资源,这个过程较重定向。
常见场景:
-
用户登录
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/r/img");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5.请求重定向Demo
<%--${pageContext.request.contextPath} 代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/re/success.jsp");
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
6.请求转发Demo
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="跳舞">跳舞
<input type="checkbox" name="hobbys" value="看书">看书
<input type="checkbox" name="hobbys" value="跑步">跑步
<br>
<input type="submit">
</form>
</div>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("===================");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("===================");
//请求转发
System.out.println(req.getContextPath());
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
重定向和转发的区别:
相同点:
-
页面都会实现跳转
不同的:
-
请求转发url不会改变:307
-
重定向地址发生改变:302
8、Request
HttpServletRequest代表用户端的请求,用户通过http协议访问服务器,Http中所有的请求信息会被封装到HttpServletRequest,通过其方法可以获取客户端的多有信息。
二、Cookie、Session
1、 会话
-
用户打开了一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。
-
有状态会话:每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。
3、保存会话的两种技术
cookie
-
客户端技术(响应、请求)
session
-
服务器技术,利用这个技术可以保存用户的会话信息。我们可以把信息放到Session中.
网站登录后,第二次就不需要重新登录了。
4、cookie
-
从请求中拿到cookie信息
-
服务器响应诶客户端cookie
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//获取Cookie的值
Cookie[] cookies = req.getCookies();
if (cookies!=null){//判断Cookie是否有值
out.write("您上一次访问的时间是:");
for (Cookie cookie : cookies) {
if (cookie.getName().equals("LastLoginTime")){
long l = Long.parseLong(cookie.getValue());
Date date = new Date(l);
out.write(date.toLocaleString());
}
}
}else {
out.write("这是第一次访问!");
}
//服务器给客户端响应一个Cookie
Cookie cookie = new Cookie("LastLoginTime", System.currentTimeMillis() + "");
cookie.setMaxAge(60*60);//设置cookie存在时间
resp.addCookie(cookie);
}
关于cookie的细节:
-
一个cookie只能保存一个信息;
-
一个web站可以给浏览器发送多个cookie,最多存放20个cookie;
-
cookie大小限制4kb;
-
浏览器上线为300个cookie。
删除cookie的方式:
-
不设置有效期,关闭浏览器删除cookie。
5、session
什么是session:
-
服务器会给每一个浏览器创建一个session对象。
-
一个session独占一个浏览器。
-
用户登录后,整个网站都已经登录。
session和cookie的区别:
-
Cookie是把用户的数据写给浏览器保存。
-
Session是把用户订单数据写到独占的服务器端保存。
-
Session对象由服务器创建。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//给session中存东西
session.setAttribute("user", new Person("李白",1));
//获取session的ID
String id = session.getId();
//判断是不是新的session
if (session.isNew()){
resp.getWriter().write("创建成功,session的ID为:"+id);
}else {
resp.getWriter().write("已经存在,session的ID为:"+id);
}
}
HttpSession session = req.getSession();
Person person = (Person)session.getAttribute("name");
System.out.println(person.toString());
//手动注销session
session.invalidate();
会话自动过期,在web.xml中配置
<!-- 设置session默认过期时间-->
<session-config>
<!-- 一分钟后过期-->
<session-timeout>1</session-timeout>
</session-config>
387

被折叠的 条评论
为什么被折叠?



