javaWeb学习路线
一、Maven是什么?
在Java开发中,经常会用到各种的jar包,而Maven就是实现自动导包、自动配置的工具
二、Maven的核心思想
核心思想:约定大于配置
Maven会规定好Java代码规范,在开发中不能违反(有约束,不要去违反)
三、Maven的下载
四、修改Maven配置环境
1. 解压文件夹
2.新建环境变量
在Path中新建
3.验证Maven是否安装好
win+r,输入cmd,再输入mvn -version
4.添加阿里云镜像
打开maven文件->conf->settings.xml,在其中添加代码
<mirror>
<id>nexus-aliyun</id>
<mirror0f>*,!jeecg,!jeecg-snapshots</mirrorof>
<name>Nexus aliyun</name>
<ur1>http://maven.aliyun,com/nexus/content/groups/pub1ic</url>
</mirror>
5.新建本地仓库
在Maven文件夹下新建子文件夹maven-repo,再打开maven文件->conf->settings.xml,在…中添加代码
<localRepository>新建的maven-repo文件夹的地址</localRepository>
五、在IDEA中使用Maven
1.新建MavenWeb项目
模板可不勾选,若不勾选则为干净的Maven项目
2.等待IDEA自动下载Maven包
3.注意点
六、在IDEA中配置tomcat
七、一些说明
1.注意点
由于Maven的核心思想,可能会导致我们编写的配置文件无法被导出或无法生效,解决办法:在build中配置resources,来防止我们资源导出失败的问题
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
2.替换web.xml的内容
将Maven项目中的web.xml的内容替换
<?xml version="1.0" encoding="utf-8" ?>
<web-app
version="4.0"
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">
</web-app>
3.添加Maven依赖
从Maven库中搜索想要的库添加即可
Maven库地址:https://mvnrepository.com,如:
<!--项目依赖-->
<dependencies>
<!--junit依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<!--spring框架依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
<!--jsp-servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp-api依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!--资源导出-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
4.将项目的maven环境配好
该有的包都准备好
一、Servelet是什么?
Servlet是开发动态web的一门技术
是API中的一个接口,是实现了Servlet的Java程序
新建一个空的Maven项目,删除src目录,新建Module即可创建子项目
二、使用步骤
1.编写一个Servlet程序
1、在java资源包下新建servlet包
2、在该包下新建类并让该类继承HttpServlet
3、重写doGet()、doPost()方法
4、给新建的类实现servlet映射
或者对着包名右键new Servlet即可自动创建(注意要取消掉Create Java EE 6 annotated class的勾选)
2.编写Servlet映射
因为我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以需要在web服务中注册我们写的Servlet,还需给他一一个浏览器能够访问的路径(在web.xml中添加)
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.veterlemon.servlet.HelloServlet</servlet-class>
</servlet>
<!--一个servlet对应一个mapping:映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--映射的请求路径: http://ip:port/工程路径/hello-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
3.配置tomcat
见Maven设置篇
https://blog.csdn.net/weixin_42431775/article/details/122872077
4.防止中文乱码
设置客户端和服务器的编码格式
//doGet()或doPost()方法中加入
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html;charset=utf-8");
5.启动测试
三、Servlet的继承关系
四、Servlet访问原理
浏览器发送请求至web容器并访问Servlet,调用service方法通过request拿到请求、response响应请求,最后返回至web容器从而响应客户端
一个Servlet可以指定多个通用映射路径(servlet-mapping)
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
五、原始继承了Servlet类的写法
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HelloServlet implements Servlet {
//构造器
public HelloServlet() { System.out.println("1"); }
@Override
public void init(ServletConfig servletConfig) throws ServletException { System.out.println("2"); }
@Override
public ServletConfig getServletConfig() { return null; }
//处理请求和响应
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//分发请求
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if ("GET".equals(method))
doGet();
else if("POST".equals(method))
doPost();
}
//分发请求处理:GET
public void doPost(){ System.out.println("get请求"); }
//分发请求处理:POST
public void doGet(){ System.out.println("post请求"); }
@Override
public String getServletInfo() { return null; }
@Override
public void destroy() { System.out.println("4"); }
}
1.ServletConfig类
是servlet程序的配置信息类(Servlet程序和ServletConfig由Tomcat创建),作用:
1、可以获取Servlet程序的别名servlet-name的值
//init方法内
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
2、获取初始化参数init-param(得现在web.xml的servlet标签中配置init-param)
//web.xml中
<!--init-param是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>
//init方法内
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数value的值是:" + servletConfig.getInitParameter("value"));
3、获取ServletContext对象
//init方法内
//获取ServletContext对象
System.out.println(servletConfig.getServletContext());
2.ServletContext类
ServletContext是一个接口,代表servlet上下文对象(域对象,一个web项目共用一个对象),不常用,作用:
域对象:是可以像Map一样存取数据的对象(域指的是存取数据的操作范围)
存数据,取数据,删除数据
setAttribute(),getAttribute(),removeAttribute()
//web.xml文件中配置context-param
<!--上下文参数,可多组-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
//方法中
public class HelloServlet extends HelloServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//防止中文乱码
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
//获取servlet对象内容,作用:1.设置或获取共享数据,2.获取初始化参数,3.请求转发,4.读取资源文件
ServletContext context = this.getServletContext();
String name = "张三";
//作用1:设置共享值,其它servlet可以通过getAttribute获取到共享值
context.setAttribute("name", name);
//作用2:获取初始化参数
String url = context.getInitParameter("url");
resp.getWriter().print(url);
//作用3:请求转发(原本请求A页面,A页面转发给B页面,故最后访问到B页面)
context.getRequestDispatcher("/helloServlet").forward(req, resp);
//作用4:读取资源文件(/WEB-INF相当于打开target目录,在target目录下找文件),后面常用于读数据库文件
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String mysqlUrl = properties.getProperty("url");
System.out.println("数据库的地址为:" + mysqlUrl);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
六、HttpServletRequest类
通过HttpServletRequest对象,可以获取所有请求信息
1.常用方法:
获取前端传递的参数
//获取请求的统一资源定位符(绝对路径)
System.out.println("URI=" + request.getRequestURI());
//获取客户端的ip地址
System.out.println("URL=" + request.getRequestURL());
//获取请求头
System.out.println("客户ip=" + request.getRemoteHost());
//获取请求的参数
System.out.println("请求头的User-Agent" + request.getHeader("User-Agent"));
//获取请求的方式GET或POST
System.out.println("请求的方式" + request.getMethod());
//获取请求的参数(多个值的时候使用)
String username = request.getParameter("username");
String password = request.getParameter("password");
String[] hobby = request.getParameterValues("hobby");
System.out.println("获取请求的参数-用户名:" + username +
",获取请求的参数-密码:" + password + ",获取 请求的参数-爱好:" + Arrays.asList(hobby));
3.请求转发的实现
本质上是一次HTTP请求(相当于请求的递归)
浏览器的地址不变,Servlet_01和Servlet_02共享Request域的数据
//Servlet_01类
//获取请求参数
String username = request.getParameter("username");
System.out.println("在servlet1中查看参数:" + username);
//设置域值
request.setAttribute("key", "柜台1的章");
//转发,转发的地址为servlet-mapping的url-pattern
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet_02");
requestDispatcher.forward(request, response);
//Servlet_02类
//获取请求参数
String username = request.getParameter("username");
System.out.println("在servlet2中查看参数:" + username);
//查看servlet1是否有”盖章“
Object key = request.getAttribute("key");
System.out.println("servlet1是否有“盖章”:" + key);
//处理自己的业务
System.out.println("servlet2的业务");
七、HttpServletResponse类
通过HttpServletResponse对象,可以设置响应信息
1.简单使用
字节流:getOutputStream(),常用于下载(传递二进制数据)
字符流:getWriter(),常用于回传字符串(最常用)
二者只能用其一
//防止乱码
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html;charset=utf-8");
//往客户端回传数据
PrintWriter writer = response.getWriter();
writer.write("这是回传的数据");
2.常见应用
下载文件
//1.要获取下载文件的路径
String path = this.getServletContext().getRealPath("位置");
System.out.println("文件路径为:" + path);
//2.下载的文件名是
String fileName = path.substring(path.lastIndexOf("\\") + 1);
//3.设置浏览器行为(设置想办法让浏览器能够支持下载我们需要的东西)
resp.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));
//4.获取下载文件的输入流
FileInputStream in = new FileInputStream(path);
//5.创建缓冲区
int len = 0;
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();
验证码功能
略
3.★★请求重定向★★
服务器端在响应客户端第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。本质上是两次HTTP请求(相当于请求的迭代),对应两个request对象
常用于登录
//response_01的代码
//请求重定向形式一
System.out.println("resopnse01");
//设置响应状态:302请求重定向
response.setStatus(302);
//设置响应头,说明新地址
response.setHeader("Location", "http://localhost:8080/javaWeb_myDemo/response_02");
//请求重定向形式二(推荐)
response.sendRedirect("http://localhost:8080/javaWeb_myDemo/response_02");
//response_02的代码
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html;charset=utf-8");
response.getWriter().write("response2的结果");
一.会话
1.会话的定义
维护客户端和服务器之间关联的一种技术,常用的会话跟踪技术是Cookie与Session。
2.保存会话的技术
Cookie:通过在【客户端】记录信息确定用户身份
★★Session★★:通过在【服务器端】记录信息确定用户身份
可以把信息或数据放在session中(cookie会缓存到本地,相对不安全),常见应用:网站首次登录后第二次可直接进入
3.Cookie
关键代码
//获得cookie
Cookie[] cookies = req.getCookies();
//获取cookie的属性、值,采用键值对形式
cookie.getName();
cookie.getValue();
//新建cookie
new Cookie();
//设置cookie有效期限,若不设置有效期,则关闭浏览器时cookie自动失效
cookie.setMaxAge();
//响应客户端
response.addCookie(cookie);
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
//Cookie,服务器段从客户端获取
Cookie[] cookies = req.getCookies(); //可能有多个Cookie
//判断Cookie是否存在
if (cookies != null){
out.write("您上一次访问网站的的时间是:");
for (Cookie cookie : cookies){
if (cookie.getName().equals("lastLoginTime")){
//因为要求的是时间,cookie是字符串对象,要进行类型转换
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}else {
out.write("这是您第一次访问网站");
}
//服务器响应客户端:发送一个cookie
Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis()));
//设置cookie的有效期
cookie.setMaxAge(60);
resp.addCookie(cookie);
}
4.★★★Seesion★★★
服务器会给每个浏览器创建一个session对象,只要浏览器不关闭,session就存在
使用场景:保存用户登录信息、购物车信息、在整个网站中经常用到的数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
//获得Session
HttpSession session = req.getSession();
//往session存内容
session.setAttribute("name", "张三");
//获取session的id
String sessionId = session.getId();
//判断session是否是新创建的
if (session.isNew()){
resp.getWriter().write("session创建成功,该session的id为:" + sessionId);
}else {
resp.getWriter().write("session已经在服务器中存在,该session的id为:" + sessionId);
}
//获取session存的内容
String name = (String)session.getAttribute("name");
System.out.println(name);
//删除session的内容
session.removeAttribute("name");
//注销session
session.invalidate();
}
//web.xml文件的内容,设置session自动过期
<session-config>
<!--session失效时间:以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
一、JSP
动态网站开发技术,是简化版的servlet,特点:编写方式与html语言类似,可以嵌入Java代码
1.本质:访问jsp页面时,web容器会将jsp页面转化为servlet
//web.xml中需要的依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--jstl表达式-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标准库-->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
2.JSP语法
JSP的特点:整个页面的表达式或脚本片段实际上是一个整体的,变量不能重名
JSP注释
<%--这是JSP注释--%>
2、JSP表达式
将程序输出到客户端
<%= new java.util.Date()%>
3、JSP脚本片段
可以在脚本判断内写原生Java代码
<%
int sum=0;
for(int i=1; i<=10; ++i)
sum += i;
out.println("<h1>sum="+sum+"</h1>");
%>
4、在JSP脚本片段中嵌入HTML标签
<%
for(int i=1; i<=10; ++i){
%>
<p>在jsp脚本片段中嵌入HTML</p>
<%
}
%>
5、JSP声明
类似于java的声明
<%!
private int globalVar = 0;
public void globalFun(){
System.out.println("这是声明的函数");
}
%>
6、自定义错误页面
//在jsp页面
<%@ page errorPage="自定义错误页面的位置" %>
//在错误页面
<%@ page isErrorPage="true" %>
//在web.xml
<error-page>
<error-code>错误代码</error-code>
<location>/error.jsp</location>
</error-page>
7、引入页面
一般用于公共内容的引入,省略页面的编写
方式一:<%@ include file=“页面位置”%>,会将多个页面合成一个
方式二:<jsp:include page=“error.jsp”/>,本质还是多个页面
<%@ include file="公共的header页面位置"%>
<h1>内容</h1>
<%@ include file="公共的footer页面位置"%>
二、EL表达式
格式:${表达式}
1.获取数据
//jsp页面1
<jsp:forward page="jsp-el.jsp">
<jsp:param name="username" value="张三"/>
<jsp:param name="password" value="123"/>
</jsp:forward>
//jsp页面2
//传统jsp标签写法
用户名:<%= request.getParameter("username")%>
密码:<%= request.getParameter("password")%>
//EL表达式写法
用户名:${username}
密码:${password}
2.执行运算
3.获取web开发的常用对象
<%--获取表单内容,形式:${param.参数名}--%>
<form action="jsp-el.jsp" method="get">
<input type="text" name="username" value="${param.username}">
<input type="submit" value="提交">
</form>
<%--判断:提交的内容为“管理员”则显示欢迎,test="条件",(var=""存储test的结果,scope=""表示范围)非必要--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="欢迎!"/>
</c:if>
<%--显示test的判断结果--%>
<c:out value="${isAdmin}"/>
三、JSTL表达式
JSTL标签库就是为了弥补HTML的不足,它自定义许多标签,这些标签的功能和java代码一样
1.使用步骤
//1.引入jstl核心标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2.常用标签
<%--进行判断:c:if--%>
<%--test="条件",(var=""存储test的结果,scope=""表示范围)非必要--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="欢迎!"/>
</c:if>
<%--输出:c:out--%>
<%--value内填变量名,一般于el表达式合用--%>
<c:out value="${isAdmin}"/>
<%--设置变量:c:set--%>
<c:set var="score" value="100"/>
<%--选择:c:choose--%>
<%--choose相当于switch,when相当于case--%>
<c:choose>
<c:when test="${score>=90}">
你的成绩为优秀!
</c:when>
<c:when test="${score>=80 && score<90}">
你的成绩为良好!
</c:when>
<c:when test="${score>=60 && score<80}">
你的成绩为及格!
</c:when>
</c:choose>
<%
ArrayList<String> student = new ArrayList<>();
student.add(0, "张三");
student.add(1, "李四");
student.add(2, "王五");
student.add(3, "赵六");
request.setAttribute("list", student);
%>
<%--遍历:c:forEach--%>
<%--var表示遍历名,items表示遍历的对象来源,加上begin,end,step即为普通for循环--%>
<c:forEach var="stu" items="${list}">
<c:out value="${stu}"/>
</c:forEach>
一、JavaBean
一般是指实体类,必须包含无参构造、属性私有化、属性对应的get/set方法,一般放于pojo包下
一般用来和数据库的字段做映射(类对应数据库的表,属性对应数据库的字段,对象对应数据库的行记录),如
一个Student数据库,格式为
id name age address
1 张三 18 广州
2 李四 21 湖南
3 王五 43 云南
则它对应的实体类为
public class Student {
private int id;
private String name;
private int age;
private String address;
public Student() {}
public Student(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
一、MVC三层架构
MVC(Model、View、Contraller),是一个框架,是为了降低代码的耦合度(解耦合),方便项目后期的维护和升级
对着项目鼠标右键点击Add Framework Support,选中Web Application即可创建web包
一般先写Dao层,再写Service层,再写Servlet层,最后写前端
1.Model模型层
也叫业务层
主要作用:连接数据库进行业务操作CRUD
2.View视图层
经典代表:JSP
主要作用:1.展示后台数据,2.展示页面,3.
3.Controller控制器层
经典代表:Servlet
主要作用:1.接收用户请求,2.请求业务层做出响应,3.重定向或转发
4.一个web项目应该有的包
一、Filter过滤器
主要用来过滤网站数据,如处理中文乱码、垃圾请求
使用步骤如下
1.导包
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--jstl表达式-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标准库-->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
<scope>runtime</scope>
</dependency>
<!--mysql数据库包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
</dependencies>
2.编写过滤器
import javax.servlet.*;
import java.io.IOException;
public class CharsetEncodingFilter implements Filter {
//初始化,服务器开启时自动执行
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharsetEncodingFilter初始化");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/html;charset=UTF-8");
System.out.println("CharsetEncodingFilter执行前");
//放行Filter,否则程序会卡在这
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("CharsetEncodingFilter执行后");
}
//销毁,在服务器关闭时自动执行
public void destroy() {
System.out.println("CharsetEncodingFilter销毁");
}
}
3.在web.xml中为要过滤的包添加过滤声明
<!--配置过滤器,设定过滤条件-->
<!--servlet-mapping的多重性刚好配合过滤器,可以有选择的使用过滤器,可以写多个filter-mapping去过滤应该过滤的-->
<filter>
<filter-name>CharsetEncodingFilter</filter-name>
<filter-class>com.veterlemon.filter.CharsetEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<!--表示只要是 /servlet包下的任何请求都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
4.Filter实现权限拦截
用户登录后才能进入主页,用户注销后不能进入主页
思路:用servlet来获取表单用户信息,根据条件判断数据是否正确;若正确,则创建一个session(因为会多处用到这个session,故抽象做成常量),存放该session的键和值;再进行页面跳转
用户登录后才能进入主页,思路:
先获取表单提交的用户信息,然后进行条件判断;若符合条件,则创建一个session,存放该session的键和值;最后通过Filter判断session的值来判断是否应该阻止进入主页
用户注销后不能进入主页,思路:
获取页面session并判断其值是否为空,若不为空则移除session的键,然后进行页面重定向
success.jsp与error.jsp放于web项目的sys包下
//login.jsp
<h1>登录</h1>
<form action="/servlet/login" method="post">
姓名:
<input type="text" name="username" id="name">
<input type="submit" name="sub-btn" value="提交">
</form>
//success.jsp
<h1>登录成功,进入主页啦!</h1>
<p><a href="/servlet/logout">注销</a></p>
//error.jsp
<h1>登录出错啦!</h1>
<p><a href="login.jsp">返回登录页</a></p>
//LoginServlet页面
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
if (username.equals("admin")){
//使其在多个页面可以被取到,从而进行页面状态判断
req.getSession().setAttribute(Constant.USER_SESSION, req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else {
resp.sendRedirect("/sys/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
//LogOutServlet页面
public class LogOutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute(Constant.USER_SESSION);
if (user_session != null){
req.getSession().removeAttribute(Constant.USER_SESSION);
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
//LoginFilter页面
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Object userSession = request.getSession().getAttribute(Constant.USER_SESSION);
if (userSession == null){
response.sendRedirect("/sys/error.jsp");
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
//web.xml
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.veterlemon.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/logintest</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogOutServlet</servlet-name>
<servlet-class>com.veterlemon.servlet.LogOutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogOutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogOutServlet</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.veterlemon.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!--表示只要是 /servlet下的任何请求都会经过这个过滤器-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
一、监听器
实现一个监听接口
使用步骤如下
1.创建一个监听器并实现监听器的接口
public class OnlineCountListener implements HttpSessionListener {
//一旦创建session就会触发
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext sct = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) sct.getAttribute("OnlineCount");
if (onlineCount == null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
sct.setAttribute("OnlineCount", onlineCount);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext sct = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) sct.getAttribute("OnlineCount");
if (onlineCount == null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count--);
}
sct.setAttribute("OnlineCount", onlineCount);
//手动销毁session
//httpSessionEvent.getSession().invalidate();
}
}
2.配置web.xml
<!--注册监听器-->
<listener>
<listener-class>com.veterlemon.listener.OnlineCountListener</listener-class>
</listener>
<!--配置session销毁时间-->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
3.在jsp页面中使用
如:获取在线人数
<h1>当前有<%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%>人在线</h1>
4.过滤器、监听器的常见应用
GUI编程