1、Servlet
1.1、开发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 HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //响应类型 resp.setContentType("text/html"); //设置字符编码 resp.setCharacterEncoding("utf-8"); //获取响应输出流 PrintWriter writer = resp.getWriter(); //输出HelloServlet! writer.print("HelloServlet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
-
把类部署到web服务器
<?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_3_1.xsd" version="3.1" metadata-complete="true"> <!--注册servlet--> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.servlet.HelloServlet</servlet-class> </servlet> <!--servlet映射--> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <!--请求路径--> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
1.2、Servlet原理
1.3、Context对象
1、数据共享
//Servlet1,放置信息
public class Context extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String user = "Tom";
//获取ServletContext对象
ServletContext context = req.getServletContext();
//将数据保存在ServletContext对象中:设置键值对
context.setAttribute("user",user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
//Servlet2,读取信息
public class GetContext extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = req.getServletContext();
String user = (String) context.getAttribute("user");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print(user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
2、获取默认参数
ServletContext context = req.getServletContext();
String url = context.getInitParameter("url");
<context-param>
<param-name>url</param-name>
<param-value>aaa</param-value>
</context-param>
3、请求转发
url 地址栏路径不改变
ServletContext context = req.getServletContext();
context.getRequestDispatcher("/hello").forward(req, resp);
4、读取资源文件
ServletContext context = req.getServletContext();
//获得文件流
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
//读取Properties文件
prop.load(is);
String name = prop.getProperty("name");
String pwd = prop.getProperty("pwd");
1.4、Response
服务器的响应
1、文件下载
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取下载文件的路径,此处为绝对路径
String realPath = "G:\\Servlet\\src\\main\\resources\\图.jpg";
//2.设置下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3.使浏览器支持下载,URLEncoder.encode(filename,"UTF-8")改成中文编码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
//4.获取下载文件输入流
FileInputStream fis = new FileInputStream(realPath);
//5.创建buffer缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6.获取OutputStream对象
ServletOutputStream os = resp.getOutputStream();
//7.将FileOutputStream流写入到缓冲区
while ((len=fis.read(buffer))>0){
//8.使用OutputStream将缓冲区数据输出到客户端
os.write(buffer,0,len);
}
//9.关闭流
os.close();
fis.close();
}
2、验证码生成
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//在内存中创建图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到笔
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.white); //设置画笔颜色
graphics.fillRect(0, 0, 80, 20); //填充背景颜色
graphics.setColor(Color.black); //设置画笔颜色
graphics.setFont(new Font(null, Font.BOLD, 20)); //设置画笔字体样式
graphics.drawString(makenum(), 0, 20); //写字
//让浏览器使用图片方式打开
resp.setContentType("image/jpeg");
//使浏览器5秒刷新一次
resp.setHeader("refresh", "2");
//禁止浏览器缓存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("pragma", "no-cache");
//把图片写给浏览器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成随机数
private String makenum() {
Random random = new Random();
//用0填充,保证随机数是4位数
String num = random.nextInt(9999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4 - num.length(); i++) {
sb.append("0");
}
return num += sb.toString();
}
3、重定向
一个web资源收到客户端的请求后,让客户端访问另一个资源。
重定向和转发的区别:重定向会改变url地址栏,转发不会。
resp.sendRedirect("/重定向路径");
利用重定向实现 jsp 页面跳转
<!--index.jsp-->
<form action="/rediret">
<input type="submit">
</form>
<!--success.jsp-->
<h1>success!</h1>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/success.jsp");
}
<servlet>
<servlet-name>rediret</servlet-name>
<servlet-class>com.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>rediret</servlet-name>
<url-pattern>/rediret</url-pattern>
</servlet-mapping>
1.5、Request
客户端的请求
1、获取客户端数据参数(登录功能)
<!--index.jsp-->
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>登录</title>
</head>
<body>
<div>
<form action="/login" method="post">
用户名:<input type="text" name="name"><br>
密码:<input type="password" name="pwd"><br>
<input type="submit">
</form>
</div>
</body>
</html>
<!--success.jsp-->
<!--error.jsp-->
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置接收的数据参数编码为utf-8
req.setCharacterEncoding("utf-8");
//接收的数据参数
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
//判断后跳转
if (name.equals("a") && pwd.equals("123")) {
resp.sendRedirect("/success.jsp");
} else {
resp.sendRedirect("/error.jsp");
}
}
2、Cookie
Cookie是由服务器端生成,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器。
Cookie的处理分为:
- 服务器像客户端发送cookie
- 浏览器将cookie保存
- 之后每次http请求浏览器都会将cookie发送给服务器端
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//创建输出流
PrintWriter out = resp.getWriter();
//从客户端获取Cookies
//Cookie[] cookies = req.getCookies();
//判断Cookie是否存在
/*if(cookies!=null){
for (Cookie cookie : cookies) {
out.write(cookie.getName());
out.write(cookie.getValue());
}
}else {
out.write("第一次访问");
}*/
//服务器给客户端响应cookie
Cookie cookie = new Cookie("name", "aaa");
resp.addCookie(cookie);
out.write(cookie.getName());
out.write(cookie.getValue());
//设置有效期
cookie.setMaxAge(60*60);
//关闭流
out.close();
}
- 一个cookie只能保存一个信息
- 一个web站点可以发送多个cookie,最多存放20个cookie
- cookie最大4kb
- 浏览器上限300个cookie
- 不设置有效期的cookie,关闭浏览器就失效
3、session
当访问服务器某个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的。
- 打开客户端,Session便存在,关闭客户端,Session便注销。
- Session不仅仅存储信息,还能够储存对象等其他数据。
- Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//获取Session
HttpSession session = req.getSession();
//判断Session是否新建
if(session.isNew()){
out.write("New session");
}else {
out.write("Old session");
}
/*//存数据到Session
session.setAttribute("name","name");
//获取Session数据
String name = (String) session.getAttribute("name");
out.write(name);
//删除Session数据
session.removeAttribute("name");
//手动注销Session
session.invalidate();*/
}
可以再web.xml设置Session过期时间
<session-config>
<session-timeout>60</session-timeout>
</session-config>
4、JSP
Java Server Pages:java服务器端页面。可以在jsp中嵌入java,为用户提供动态数据。
jsp本质是servlet
4.1、JSP流程
4.2、JSP基础语法
- JSP支持Java所有语法
- JSP在<% %>中写Java
- JSP声明会被编译到生成的java类中,其他的生成到_jspService方法
4.3、JSP指令
1、page
<%@ page
errorPage="error.jsp" //错误跳转页面
import="java.util.Date" //导包
%>
一般也可以在 web.xml 配置错误页面
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
2、include
<%@ include file="/common/header.jsp"%> //包含的公有文件显示,一般写在body中
<jsp:include page="common/header.jsp"/> //标签写法
4.4、JSP内置对象
- PageContext
- Request
- Response
- Session
- Applicatio【ServletContext】
- config 【ServletConfig】
- out
- page
- exception
<body>
<%
pageContext.setAttribute("a","1"); //保存的数据只在一个页面有效
request.setAttribute("b","2"); //只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("c","3"); //只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("d","4"); //只在服务器有效,从打开服务器到关闭服务器
%>
<%
String a = (String) pageContext.getAttribute("a");
String b = (String) pageContext.findAttribute("b");
String c = (String) pageContext.findAttribute("c");
String d = (String) pageContext.findAttribute("d");
%>
<%=a%>
<%out.print(b);%>
<%--EL表达式取值--%>
${c}
${d}
</body>
4.5~7都需要导包:jstl-api,standard
4.5、EL表达式
-
获取数据
-
执行运算
-
获取web开发中的常用对象
${param.参数名}
4.6、JSP标签
<jsp:include page="jsp1.jsp"/> //包含该页面
<jsp:forward page="jsp2.jsp"> //转发到该页面
<jsp:param name="name" value="value"/> //传递值
</jsp:forward>
4.7、JSTL标签
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
使用JSTL需要在tomcat中也添加jstl-api,standard
5、JavaBean
实体类
- 一般要有无参构造
- 属性私有
- get,set方法
- 和数据库字段做映射
6、MVC
Model:模型层
- 业务处理:Service
- 数据库持久层:Dao
- 实体类:JavaBean,pojo,entity
View:视图层(Html,Jsp)
Controller:控制层(Servlet)
7、过滤器
注意过滤器导包是:import javax.servlet.Filter;
-
编写过滤器
public class CharacterEncodingFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletResponse.setContentType("text/html"); servletResponse.setCharacterEncoding("utf-8"); servletRequest.setCharacterEncoding("utf-8"); filterChain.doFilter(servletRequest,servletResponse);//使请求往下交接,必写 } //初始化 @Override public void init(FilterConfig filterConfig) throws ServletException {} //销毁 @Override public void destroy() {} }
-
注册过滤器
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <!--指定请求经过过滤器--> <servlet-name>helloServlet</servlet-name> <!--servlet下所有请求都要经过过滤器--> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
过滤器实现拦截直接进入登录成功页面
//判断是否登录成功
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
if(name.equals("admin")){
//登陆成功设置Session信息
req.getSession().setAttribute("id",req.getSession().getId());
resp.sendRedirect("/sys/first.jsp");
}else {
resp.sendRedirect("/error.jsp");
}
}
//登出移除Session信息
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
if (session.getAttribute("id")!=null) {
session.removeAttribute("id");
resp.sendRedirect("/login.jsp");
}else {
resp.sendRedirect("/login.jsp");
}
}
//过滤器
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//因为ServletRequest没有getSession方法,所以先进行强制转换
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//拦截未经过登录进入其他页面的操作
if(request.getSession().getAttribute("id")==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(servletRequest, servletResponse);
}
<!--过滤器拦截直接进入sys目录下的所有请求-->
<filter>
<filter-name>filter</filter-name>
<filter-class>com.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
tpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//拦截未经过登录进入其他页面的操作
if(request.getSession().getAttribute(“id”)==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(servletRequest, servletResponse);
}
```xml
<!--过滤器拦截直接进入sys目录下的所有请求-->
<filter>
<filter-name>filter</filter-name>
<filter-class>com.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>