Servlet入门

 

目录

Servlet

1、简介

2、创建一个Servlet项目

2.0 创建一个Maven项目

2.1在Pom.xml安装servlet依赖

2.2编写Servlet

2.3在Web.xml文件编写Servlet的映射

2.4配置Tomcat

2.5 运行

3、Servlet原理

3.1UML类图

3.2Servlet访问URL映射

4.Servlet-context 对象

4.1新建子工程

4.2 Servlet-context

5.下载功能

6.绘制验证码

7.页面重定向SentRedirection

8.HttpServletRequest

8.1获取表单信息

9.COOKIE

9.1 保存用户上一次访问的时间

9.2 cookie的一些参数

10.session(重点)

10.1 session的方法

10.2 session注销的两种方式

11.JSP

11.1 JSP -- JAVA Server Page

11.2 JSP项目构建

11.3 JSP基础语法

11.4 JSP指令

11.5 自定义错误页面

12.JavaBean

13.MVC三层架构

14.Filter

15.Listen

16.用户登录实例

登录界面 login.jsp

成功登录界面 inner/success.jsp

未登录成功的错误页面 error/error.jsp

过滤器 logincheck.java

登录请求业务实现 Login.java

注销请求业务实现 Logout.java

17.上传文件 -- Mark

17.1 前端表单要求

17.2 导入Jar包


1、简介


  • 用于动态web

  • Servlet是一个接口

    • 编写一个类、实现借口

    • 部署到服务器中

2、创建一个Servlet项目


2.0 创建一个Maven项目

 

2.1在Pom.xml安装servlet依赖

在Pom.xml中进行添加依赖

  • javax.servlet-api

  • javax.servlet.jsp-api

 <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
 <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>4.0.1</version>
     <scope>provided</scope>
 </dependency>

 <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
 <dependency>
     <groupId>javax.servlet.jsp</groupId>
     <artifactId>javax.servlet.jsp-api</artifactId>
     <version>2.3.3</version>
     <scope>provided</scope>
 </dependency>
 ​

2.2编写Servlet

1.创建一个包

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

2.实现Servlet接口

有两个默认实现类 HttpServlet 、GenericServlet (可以去看看源码)

我们继承HttpServlet 然后重写DoGet 和 DoPost 方法

 public class helloServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         PrintWriter writer = resp.getWriter();
         writer.println("hello world");
     }
 ​
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req,resp);
     }
 }

2.3在Web.xml文件编写Servlet的映射

 <web-app>
   <display-name>Archetype Created Web Application</display-name>
 <!--  注册Servlet-->
   <servlet>
     <servlet-name>hello</servlet-name>
     <servlet-class>com.sakura.helloServlet</servlet-class>
   </servlet>
 <!--  Servlet的请求路径-->
   <servlet-mapping>
     <servlet-name>hello</servlet-name>
     <url-pattern>/hello</url-pattern>
   </servlet-mapping>
 </web-app>

2.4配置Tomcat

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

2.5 运行

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

3、Servlet原理


3.1UML类图

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

1.抽象类HttpServlet继承抽象类GenericServlet,其有两个比较关键的方法,doGet()和doPost()

2.GenericServlet实现接口Servlet,ServletConfig,Serializable

3.MyServlet(用户自定义Servlet类)继承HttpServlet,重写抽象类HttpServlet的doGet()和doPost()方法

注:任何一个用户自定义Servlet,只需重写抽象类HttpServlet的doPost()和doGet()即可,如上图的MyServlet

3.2Servlet访问URL映射

由于客户端是通过URL地址访问Web服务器中的资源,所以Servlet程序若想被外界访问,必须把Servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素<servlet>和元素<servlet-mapping>完成。

<servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

在请求http://localhost:8080/servlet2_war/hello的时候会去web.xml 的Servlet-mapping中找

   <servlet-mapping>
     <servlet-name>hello</servlet-name>
     <url-pattern>/hello</url-pattern>
   </servlet-mapping>

找到Servlet-name=hello ,接着在Servlet中找

   <servlet>
     <servlet-name>hello</servlet-name>
     <servlet-class>com.sakura.helloServlet</servlet-class>
   </servlet>

找到了Servlet -class

4.Servlet-context 对象


4.1新建子工程

  • 新建一个模块 WebApp

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

  • 补全结构

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

创建包

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

 

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

4.2 Servlet-context

note: 在 IDEA中 ctrl + alt + v 可以自动补全变量类型及其取名

web容器在启动时,会为每一个web程序都创建一个对应的Servlet-context对象,代表了当前的Web应用

4.2.1 共享数据

我在这个Servlet中保存的数据 可以在另外一个Servlet应用中获取

整体框架图

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

4.2.2 源码

 // 上传端
 public class helloServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         ServletContext servletContext = this.getServletContext();
         String name="Sakura";
         servletContext.setAttribute("hello",name);
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }
 //get端
 public class getServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         ServletContext servletContext = this.getServletContext();
         String hello = (String) servletContext.getAttribute("hello");
         resp.getWriter().println(hello);
     }
 ​
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }
 <!--  web.xml-->
 <!--  注册Servlet-->
 <servlet>
     <servlet-name>hello</servlet-name>
     <servlet-class>com.sakura.helloServlet</servlet-class>
 </servlet>
 ​
 <servlet>
     <servlet-name>getc</servlet-name>
     <servlet-class>com.sakura.getServlet</servlet-class>
 </servlet>
 ​
 <!--  Servlet的请求路径-->
 <servlet-mapping>
     <servlet-name>hello</servlet-name>
     <url-pattern>/hello</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
     <servlet-name>getc</servlet-name>
     <url-pattern>/getc</url-pattern>
 </servlet-mapping>

4.2.3 运行结果

我们可以看到 /getc这个页面获取到了/hello的数据

4.2.4 测试 重启tomcat

我们可以看到 由于/hello 没有向Servlet-context发送数据 所以/getc 获取不到这个String对象

4.2.5 ServerletContext 的一些API

 ServletContext servletContext = getServletContext();
 //1.获取web.xml里面的参数信息
 /*
 <context-param>
     <param-name>name</param-name>
     <param-value>sakuara</param-value>
 </context-param>
 */
 String initParameter = servletContext.getInitParameter("name");
 ​
 //2.设置上下文属性与获取上下文属性 不同应用中是同一个context
 servletContext.setAttribute("add","nanjing");
 String add = (String) servletContext.getAttribute("add");
 //public void removeAttribute(String name);移除一个属性
 ​
 //把资源当做流获取
 //public InputStream getResourceAsStream(String path);
 //可以用文件IO来实现
 ​
 //获取重定向
 public RequestDispatcher getRequestDispatcher(String path);

4.2.6 Servletconfig & ServletContext

 

 

  • 每个Servlet一个ServletConfig

  • 每个Web应用一个ServletContext

5.下载功能


  1. 获取下载文件的路径

  2. 获取下载文件名

  3. 修改response 头信息 使其支持下载

  4. 获取文件的输入流

  5. 创建缓冲区

  6. 获取响应的输出流

  7. 把输入流写入输出流

 ​
 public class DownServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //1. 获取下载文件的路径
         String respath="/media/yqx/软件/Java/Java_web_Project/Servlet2/src/main/resources/姚谦祥.png";
         //2.获取下载的文件名
         String fileName=respath.substring(respath.lastIndexOf("/")+1);
         //3. 修改response 头信息 使文件以下载的形式下载下来;
         resp.setHeader("content-disposition","attachement;filename="+ URLEncoder.encode(fileName,"UTF-8"));
         //4.把资源转化成输入流
         FileInputStream in=new FileInputStream(respath);
         //5.获取输出流
         ServletOutputStream out=resp.getOutputStream();
         //6.创建缓冲区
         int len=0;
         byte[] buffer = new byte[1024];
         //7. 输出资源流
         while ((len=in.read(buffer))>0){
             out.write(buffer,00,len);
         }
     }
 ​
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }

 

6.绘制验证码


  1. 生成验证码

    1. 生成一张图片

    2. 生成一串随机数

    3. 把随机数写入图片

  2. 输出验证码

    1. 设置header不去缓存该图片

    2. 让浏览器5秒刷新一次

    3. 把图片写入输出流

 ​
 public class pictureServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 //      在内存中创建一张图片
         BufferedImage image=new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
         Graphics2D g=(Graphics2D)image.getGraphics();
 //      绘制图片底色
         g.setColor(Color.white);
         g.drawRect(0,0,80,20);
         //把生成的随机数写入图片
         g.setColor(Color.BLUE);        
         g.drawString(made_random(),20,10);
 //      输出验证码        
         //2秒刷新
         resp.setHeader("Refresh","2");
         //设置头信息内容形式
         resp.setContentType("image/jpeg");
         //设置头信息缓存控制 - 不缓存
         resp.setHeader("Catch-Control","no-catch");
 //      把图片写入输出流
         ImageIO.write(image, "jpg",resp.getOutputStream());
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
     //生成随机数
     public static String made_random(){
         Random r=new Random();
         String num=r.nextInt(9999)+"";
         StringBuffer buf=new StringBuffer();
         for (int i=0;i<4-num.length();i++){
             buf.append("0");
         }
         String s=buf.toString()+num;
         return  s;
     }
 }

7.页面重定向SentRedirection


 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     //获取到提交的表单信息 getParameter
     String usr = req.getParameter("usr");
     String pwd = req.getParameter("pwd");
     System.out.println("success!"+usr+":"+pwd);
     /*重定向等价于如下两行代码
     *resp.setStatus(302);  //302 重定向
     *resp.setHeader("Location","./img");  //重定向的地址
     * */
     resp.sendRedirect("./img");
 }

jsp 页面代码

 <form action="./red" method="post">
     用户名:<input type="text" name="usr"“”“”></br>
     密码:<input type="password" name="pwd"></br>
     <input type="submit">
 </form>

8.HttpServletRequest


HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器

我们可以拿到request请求的数据信息

 req.getParameter(String s); //String
 req.getParameterValues(String s); //String[] 

8.1获取表单信息

 //点击登录后调用/lg的方法
 <form action="./lg" method="post">
     用户名:<input type="text" name="usr"“”“”></br>
     密码:<input type="password" name="pwd"></br>
     <input type="checkbox" name="like" value="a">a
     <input type="checkbox" name="like" value="b">b
     <input type="checkbox" name="like" value="c">c
     <input type="checkbox" name="like" value="d">d
     <input type="checkbox" name="like" value="e">e
     <input type="submit">
 </form>

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

 // 用户点击登录 控制台输出用户的登录信息
 public class login extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         String pwd = req.getParameter("pwd");
         String usr = req.getParameter("usr");
         String[] like=req.getParameterValues("like");
         System.out.println(usr+" "+pwd);
         System.out.println(Arrays.toString(like));
         //登录成功后重定向到其他界面
         resp.sendRedirect("./lg.jsp");
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }

控制台会输出用户提交的信息

 

9.COOKIE


9.1 保存用户上一次访问的时间

  1. 获取到request的cookie(key,value)

  2. 遍历这些cookie

  3. 如果存在cookie的key与本地的key相等,则输出cookie的value

  4. 更新cookie的值

输出当前时间

Date date=new Date(); System.out.println(“现在的时间是:”+date.toString());

//保存用户上一次访问的时间
//1. 获取到request的cookie(key,value)
//2. 遍历这些cookie
//3. 如果存在cookie的key与本地的key相等,则输出cookie的value
//4. 更新cookie的值
public class COOKIEdemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        保存
        req.setCharacterEncoding("UTF-8");
//        存在多个cookie
        Cookie[] cookies = req.getCookies();

        if(cookies!=null){
            for (Cookie c:cookies) {
                String cName = c.getName();
                if(cName.equals("last_time")){
                    //输出cookie中的value
                    resp.getOutputStream().println("你上一次访问的时间为:"+c.getValue());
                }
            }
        }
        else {
            resp.getOutputStream().println("这是你第一次访问");
        }
//        更新cookie
        Date date=new Date();
        Cookie cookie = new Cookie("last_time", date.toString());
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

可以看到我们现在遇到了一个500服务器错误

经过排查在更新cookie这里

Date date=new Date();
Cookie cookie = new Cookie("last_time", date.toString());

存在一点问题

Cookie cookie = new Cookie("last_time", System.currentTimeMillis()+"");

改成这样就正确了

在这里 对于java获取当前时间的API我们有两种获取方式

  • System.currentTimeMillis()

  • Date date=new Date();

System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数

Date()其实就是相当于Date(System.currentTimeMillis());

9.2 cookie的一些参数

setMaxAge(int);				//设置cookie的存活时间 单位秒
setDomain(String domain);	//设置cookie可见域
setPath(String uri);		//通常的cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。
//可在同一应用服务器内共享方法:设置cookie.setPath("/App_File/");
//跨域共享cookie的方法:设置cookie.setDomain(".jszx .com");

10.session(重点)


  • 服务器会给每个用户创建一个session

  • 只要浏览器没有关闭,这个Session就存在

  • 用户登录后,整个网站都可以访问

10.1 session的方法

  • 实例

1.得到session

HttpSession session = req.getSession();

2.往session中写东西(Key,Value) Value 可以是一个对象

Person sakura = new Person(21, "Sakura");
session.setAttribute("name",sakura);

3.修改session

session.removeAttribute("name");

IDEA快捷键 Alt+Insert 快速构建一个类 包括构造 Setter Getter ToString 等等

10.2 session注销的两种方式

  1. 直接注销session (类似于用户退出登陆)

session.invalidate();//注销该session
  1. 在web.xml 配置文件中修改session的存活时间timeout

<session-config>
	<!--    15分钟后 session自动失效-->
	<session-timeout>15</session-timeout>
</session-config>

11.JSP


11.1 JSP -- JAVA Server Page

JSP是如何执行的?

这个是我们的index.jsp转化成的java文件和源文件对比

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

原JSP的内容如下

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

我们可以看到这样一个对象HttpJspBase 它就是继承了HttpServlet的

我们分析一下由jsp转化过来的Java文件

public void _jspInit() {//初始化一个JSP
}
public void _jspDestroy() {//销毁一个JSP
}
//req 和 resq
public void _jspService(HttpServletRequest request, HttpServletResponse response)
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null;	//session
final javax.servlet.ServletContext application;	//applicationContext
final javax.servlet.ServletConfig config;		//config 配置文件
javax.servlet.jsp.JspWriter out = null;			//out输出
final java.lang.Object page = this;				//当前页面.
HttpServletRequest request;
HttpServletResponse response;

结论!!!JSP本质就是一个Servlet 每当一个页面被访问的时候 就会生成这么一个Java文件

我们可以在JSP的Java代码中直接使用这么几个常量和变量

在Jsp文件中 只要是Java代码就会被原封不动的转化,而HTML代码则会被转化成这样的代码

out.write("<h2>Hello World!</h2>\n");

11.2 JSP项目构建

  • 创建一个Web项目方法二

    • 先创建一个Maven新的空项目

    • 在项目目录右键添加新的框架支持

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

我们可以把这个新建的web文件夹移到src文件下 但是要修改JSP-Project.xml

<webroots>
    <root url="file://$MODULE_DIR$//src//web" relative="/" />
</webroots>

最终的文件目录关系如下uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

在JSP的依赖中 我们要在pom.xml中新增两个依赖包

<!-- JSTL表达式依赖包 -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
</dependency>

<!-- 标签库依赖包-->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

11.3 JSP基础语法

  • HTML注释

<!-- 实现页面访问计数 -->
  • JSP注释

<%-- 实现页面访问计数 --%>
  • 变量的声明

<%! 
int visit1 = 1; //声明变量visit1,初始值为1
int visit2 = 1; //声明变量visit2,初始值为1
%>
  • 表达式的实现 (直接输出变量)

你是本页面第<%= visit1++ %>个访客(JSP表达式实现)<br>
  • JSP Scriptlets实现(通过Java输出变量)

你是本页面第<% out.println(visit2++); %>个访客

11.4 JSP指令

  • page

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*" %>
  • include (公共页面)

<%@include file="common/header.jsp"%>
<%= new java.util.Date()%>
<%@include file="common/foot.jsp"%>
  • jsp标签

<jsp:include page="common/header.jsp"></jsp:include>
<%= new java.util.Date()%>
<jsp:include page="common/foot.jsp"></jsp:include>

尽量用jsp标签 不要用include (虽然两个的实现是一样的)

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

我们可以分析一下源码有什么不一样

  • 这是jsp标签的转化代码

static {
    _jspx_dependants = new java.util.HashMap<java.lang.String,java.lang.Long>(2);
    _jspx_dependants.put("/common/header.jsp", Long.valueOf(1582294308000L));
    _jspx_dependants.put("/common/foot.jsp", Long.valueOf(1582294308000L));
}
...
//调用
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "common/header.jsp", out, false);
...
out.print( new java.util.Date());
...
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "common/foot.jsp", out, false);
  • 这是include的代码

...
out.write("<h1>this is header</h1>");
out.write('\n');
out.write(' ');
out.write(' ');
out.print( new java.util.Date());
...
out.write("<h1>this is foot</h1>\n");

可以看到 include是直接把引用的页面复制到源码中

这样在两个页面中使用同名变量就会报错!!!所以还是使用jsp标签

11.5 自定义错误页面

在web.xml中进行配置

<error-page>
    <error-code>404</error-code>
    <location>/error/404.jsp</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/error/500.jsp</location>
</error-page>

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

12.JavaBean


也叫作实体类entity

Javabean有特定的写法

  • 必须要有一个无参构造

  • 属性必须私有

  • 必须有相应的Get、set写法

ORM 对象关系映射

  • 表--类

  • 字段--属性

  • 行记录--对象

13.MVC三层架构


model - view - controluploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

View

  • 负责页面数据的展示

  • 提供用户操作

  • 发起Servlet请求

Control (Servlet)

  • 接收用户消息

  • 提供页面跳转

  • 具体业务的逻辑实现交给Service model层

Model

  • 业务处理:实现具体的逻辑(service)

  • 数据持久层:操作数据库(Dao)

 

14.Filter


  • 过滤信息

  • 解决乱码

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.getWriter().write("你好呀!");
}

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

可以看到 这里是乱码的 我们需要给response设置编码

resp.setCharacterEncoding("utf-8");//只有这样设置才不会乱码

但是如果每一个页面的每一条消息都这样处理 难免会很繁杂

我们可以新建一个类 实现过滤器接口

import javax.servlet.*;//导包不要导错了
public class FilterServlet implements Filter {
    //初始化
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    //过滤
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        
        //在这里设置编码
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        System.out.println("before");
        chain.doFilter(request,response);//让我们的请求继续走因为可能不止一个过滤器
        System.out.println("after");
    }
    //销毁
    public void destroy() {

    }
}

然后再在web.xml里面配置过滤器

<filter>
    <filter-name>encode</filter-name>
    <filter-class>com.sakura.FilterServlet</filter-class>
</filter>
<filter-mapping>
    <filter-name>encode</filter-name>
    <url-pattern>/filter/*</url-pattern>
</filter-mapping>

这样所有/filter/下面的页面呢都会以UTF-8进行编码

 

15.Listen


  • 实现监听器接口

 

 

  • 在web.xml中注册监听器

 

 

16.用户登录实例

  • 利用Filter和Session验证用户是否已经登录

  • 如果没有登录 禁止访问xx页面

  • 注销后也不让进入页面

登录界面 login.jsp

就是一个很简单的表单 跳转向/login (是login.java 在web.xml中的映射路径)

<form action="./login" method="post">
    <input name="username">
    <input type="submit">
</form>

成功登录界面 inner/success.jsp

包括一个注销按钮 跳转向../logout (是logout.java 在web.xml中的映射路径)

<body>
<h1>成功登录</h1>
<a href="../logout">退出登录</a>
</body>

未登录成功的错误页面 error/error.jsp

<body>
<h1>您未登录</h1>
<a href="../login.jsp">登录</a>
</body>

过滤器 logincheck.java

public class logincheck implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {}

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //HttpServletRequest 继承自ServletRequest 可以进行强转化
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        //获取到请求的Session
        HttpSession reqSession = req.getSession();
        //获取到Session的‘USER’属性
        String username = (String) reqSession.getAttribute("USER");
        //若username 为null或 不为‘Admin’的时候 跳转向错误页面 
        if(username==null||!username.equals("Admin")) {
            //注意错误页面的路径 当前路径为/inner/*  错误页面在同级的/error/下,所以要返回上一级
            resp.sendRedirect("../error/error.jsp");
        }
        else {
            System.out.println("login Success!!!");
        }
        chain.doFilter(request,response);
    }
    public void destroy() {}
}

登录请求业务实现 Login.java

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取到请求参数
    String username = req.getParameter("username");
    //在这里我们写死了 这里就是验证用户
    if(username.equals("Admin")) {//验证成功
        //写入到Session中
        req.getSession().setAttribute("USER", username);
        //重定向
        resp.sendRedirect("./inner/success.jsp");
    }
    else//验证失败
        resp.sendRedirect("./error/error.jsp");
}

注销请求业务实现 Logout.java

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = (String) req.getSession().getAttribute("USER");
    if (username!=null){
        //我们不去删除这个Session 而是移除“USER”这个属性
        req.getSession().removeAttribute("USER");
    }
    //重定向到登录界面
    resp.sendRedirect("./login.jsp");
}

17.上传文件 -- Mark

文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。

17.1 前端表单要求

为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

对表单中的 enctype 属性做个详细的说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。

  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。

  • text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。

<form action="" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit">
</form>

一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。

17.2 导入Jar包

  • 方法一 直接在Maven中写入依赖

<!--文件上传-->
<!--Maven会自动帮我们导入他的依赖包 commons-io包-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>
  • 方法二 手动导入jar包

 

 

在IDEA中可以手动导入Jar包,首先建立一个lib文件夹,把所需要的jar包放入lib文件夹中

方法一:右键文件夹,添加到类库

方法二:右上角项目结构,选择类库 选择指定的文件夹

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值