Web项目基础(2)

servlet2

1.servlet是否线程安全 (线程特性)

线程安全的指标
//1.是否有共享数据
//2.多线程对共享数据做写操作

servlet中 不要创建成员变量

servlet是单实例的 所以成员变量(不加static) 就会在多线程间共享
如果service()方法中 对成员变量有写操作 则线程不安全
servlet中非特殊情况 不要加锁 (直接降级为单线程 效率大大降低)    

2.servlet中提供的域对象

javaEE j2EE java企业级应用 (web应用程序)

核心对象servlet servlet中还包含其他的对象 还有隐含的对象

域对象 是servlet中隐含的对象

域对象 是空的map (在程序运行时 共享数据使用)

通用的api

域对象.setAttribute("key",value);
域对象.getAttribute("key")
域的生效时机 和失效时机
1请求域 request域

![image-20241120100116402](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120100116402.png

request读+写

package com.javasm.controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //request域  service方法中的第一个参数 req
        req.setAttribute("reqKey","reqVal");

        //读取对象的格式 读到之后强转为实际类型
        String reqKey =(String) req.getAttribute("reqKey");

        System.out.println("demo1中读取:"+reqKey);
        //调用指定路径servlet的service方法
        req.getRequestDispatcher("requestDemo2").forward(req,resp);

    }
}

request 只读取

package com.javasm.controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/requestDemo2")
public class RequestDemo2 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //request域  service方法中的第一个参数 req
        //req.setAttribute("reqKey","reqVal");

        //读取对象的格式 读到之后强转为实际类型
        String reqKey =(String) req.getAttribute("reqKey");

        System.out.println("demo2中读取:"+reqKey);

    }
}
2会话域 session域
    可以在多次请求间生效  
    对不同的浏览器进程 数据分开存储

![image-20241120100850350](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120100850350.png

session读+写

package com.javasm.controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //session域  多次请求间共享数据使用
        //如果需要使用session对象 需要通过代码主动触发
        HttpSession session = req.getSession();

        session.setAttribute("sesKey","sesVal");

        String sesKey =(String) session.getAttribute("sesKey");

        System.out.println("demo1中读取:"+sesKey);

    }
}

session只读取

package com.javasm.controller;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //session域  多次请求间共享数据使用
        //如果需要使用session对象 需要通过代码主动触发
        HttpSession session = req.getSession();

        String sesKey =(String) session.getAttribute("sesKey");

        System.out.println("demo2中读取:"+sesKey);

    }
}
3服务器域 servletContext域
    全局共享 写入之后 所有请求 所有浏览器都可以使用

![image-20241120101141506](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120101141506.png

servletContext读+写

package com.javasm.controller;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/ServletContextDemo1")
public class ServletContextDemo1 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletContext 服务器对象

        ServletContext servletContext = req.getServletContext();
        //ServletContext servletContext1 = this.getServletContext();

        servletContext.setAttribute("sckey","scval");
        String sckey =(String) servletContext.getAttribute("sckey");
        System.out.println("demo1中读取:"+sckey);

    }
}

servletContext只读取

package com.javasm.controller;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo1
 * @descriptioin:
 * @date 2024/11/20 10:37
 * @since jdk11
 */
@WebServlet("/ServletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletContext 服务器对象

        ServletContext servletContext = req.getServletContext();
        //ServletContext servletContext1 = this.getServletContext();

        String sckey =(String) servletContext.getAttribute("sckey");
        System.out.println("demo2中读取:"+sckey);

    }
}

3servlet中常用对象

3.1servletContext对象

servletContext对象 也叫application 是服务器对象

这是一个全局共享的对象 一般用来存放和共享服务器级别的全局参数

常用方法:
        * getContextPath()  获取服务入口路径          /day10 方便拼路径使用
        * getRealPath("/")  获取服务器实际代码路径     做本地IO操作时使用
        * getInitParameter("charset")   通过web.xml 读取自定义公共参数
示例代码:
package com.javasm.controller2;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/scDemo")
public class ServletContextDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //servletContext对象 application 服务器对象
        //全局共享的对象 全局数据
        /*
        * getContextPath()  获取服务入口路径          /day10 方便拼路径使用
        * getRealPath("/")  获取服务器实际代码路径     做本地IO操作时使用
        * getInitParameter("charset")   通过web.xml 读取自定义公共参数
        * */
        // 获取服务入口路径          /day10 方便拼路径使用
        ServletContext servletContext = req.getServletContext();
        System.out.println(servletContext.getContextPath());

         // 获取服务器实际代码路径
        //D:\develop\workspace\two\day10_servlet2\target
        //                  \day10_servlet2-1.0-SNAPSHOT\  做本地IO操作时使用
        System.out.println(servletContext.getRealPath("/"));

        //通过web.xml 读取自定义公共参数
        String initParameter = servletContext.getInitParameter("charset");
        System.out.println(initParameter);
    }
}

3.2servletConfig对象(了解)

servlet配置参数对象 可以获取servlet名称 等配置参数 现在的开发中基本用不到

3.3request对象(***)

HttpServletRequest 请求对象

两个作用:

1.解析请求报文 包含请求报文中的各种参数
2.做request域对象
常用方法:
        //域对象 设置键值对
          req.setAttribute("reqKey","reqVal");
        //域对象读取键值对 注意要强转类型
          String reqKey =(String) req.getAttribute("reqKey");
        //指定字符编码 处理post请求时的请求乱码
        req.setCharacterEncoding("utf-8");
        //取请求参数
        String 参数值 = req.getParameter("参数key");
        //取请求同key参数  ?hobby=1&hobby=2&hobby=3 取出字符串数组
        String[] hobbies = req.getParameterValues("hobby");
获取参数map 获取参数输入流 (了解)
        //tomcat解析参数时 会把键值对存入map<String, String[]>
        //单个参数也会存入数组
        Map<String, String[]> parameterMap = req.getParameterMap();

        //tomcat中允许 自己读取请求体中的数据 可以自己解析数据
        //获得请求体部分的输入流
        ServletInputStream inputStream = req.getInputStream();
获取请求头 (了解)
      //自定义请求头 取自定义请求头(需搭配ajax使用)
      String headerKey = req.getHeader("headerKey");
获取请求报文中的各种路径
        //获取报文中路径中的数据
        //获取协议
        System.out.println(req.getScheme());
        //获取主机名
        System.out.println(req.getServerName());
        //获取端口
        System.out.println(req.getServerPort());
        //获取服务器入口的根路径
        System.out.println(req.getContextPath());
        //URL 与 URI
        //URL 统一资源定位符 http://localhost:8080/day10/reqDemo
        System.out.println(req.getRequestURL()); 
        //URI 统一资源标识符  /day10/reqDemo
        System.out.println(req.getRequestURI());
        //servlet配置的路径 匹配路径 /reqDemo
        System.out.println(req.getServletPath());
请求转发
    可以在servlet之间跳转 先执行servlet1 --->  servlet2

    //请求转发 同一次请求 访问多个servlet时使用 可以让请求跳转
        //请求跳转时 配合request域做数据共享  提供机制  一般搭配jsp使用
    req.getRequestDispatcher("servlet2的路径").forward(req,resp);
示例代码:
package com.javasm.controller2;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * @author gfs
 * @version 0.1
 * @className RequestDemo
 * @descriptioin:
 * @date 2024/11/20 11:11
 * @since jdk11
 */
@WebServlet("/reqDemo")
public class RequestDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //req   HttpServletRequest
        //1.解析请求报文 包含请求报文中的各种参数
        //2.做request域对象
        /*
        //域对象 设置键值对
          req.setAttribute("reqKey","reqVal");
        //域对象读取键值对 注意要强转类型
          String reqKey =(String) req.getAttribute("reqKey");

        //取参数相关
        //指定字符编码 处理post请求时的请求乱码
        req.setCharacterEncoding("utf-8");
        //取请求参数
        String 参数值 = req.getParameter("参数key");
        //取请求同key参数  ?hobby=1&hobby=2&hobby=3 取出字符串数组
        String[] hobbies = req.getParameterValues("hobby");

        //tomcat解析参数时 会把键值对存入map<String, String[]>
        //单个参数也会存入数组
        Map<String, String[]> parameterMap = req.getParameterMap();

        //tomcat中允许 自己读取请求体中的数据 可以自己解析数据
        //获得请求体部分的输入流
        ServletInputStream inputStream = req.getInputStream();

        //自定义请求头 取自定义请求头
        String headerKey = req.getHeader("headerKey");

        *
        *
        * */
//        //tomcat解析参数时 会把键值对存入map<String, String[]>
//        //单个参数也会存入数组
//        Map<String, String[]> parameterMap = req.getParameterMap();
//        System.out.println(parameterMap.get("name")[0]);

/*      获取参数的请求体输入流
        可以自己解析请求体数据 配合其他工具 也可以直接解析为对象
        与tomcat解析流数据互斥 流只能读一次
        ServletInputStream inputStream = req.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);

        String username = req.getParameter("username");
        System.out.println(username);
*
*
* */
        //读请求报文 只能读请求体 可以读post方式的请求体
        //字符
        //字节
        //流只能读一次
        ServletInputStream inputStream = req.getInputStream();

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);

        String username = req.getParameter("username");
        System.out.println(username);
        //获取报文中路径中的数据
        //获取协议
        System.out.println(req.getScheme());
        //获取主机名
        System.out.println(req.getServerName());
        //获取端口
        System.out.println(req.getServerPort());
        //获取服务器入口的根路径
        System.out.println(req.getContextPath());
        //URL 与 URI
        System.out.println(req.getRequestURL());//URL 统一资源定位符  http://localhost:8080/day10/reqDemo
        System.out.println(req.getRequestURI());//URI 统一资源标识符  /day10/reqDemo
        //servlet配置的路径 匹配路径 /reqDemo
        System.out.println(req.getServletPath());
        //请求转发 同一次请求 访问多个servlet时使用 可以让请求跳转
        //请求跳转时 配合request域做数据共享  提供机制  一般搭配jsp使用
        // req.getRequestDispatcher("地址").forward(req,resp);

    }
}

3.4response对象(***)

HttpServletResponse 响应对象 控制响应报文相关的内容

常用方法
//设置返回数据格式
//resp.setContentType("application/json;charset=utf-8"); //返json
//resp.setContentType("text/html;charset=utf-8");        //返页面标签
resp.setContentType("text/html;charset=utf-8");

//获得输出流
//动态网页技术 数据是否动态生成
PrintWriter writer = resp.getWriter();
writer.print("这是一个动态页面<br>");
writer.print("<input type='text'>");
//        writer.write();
//        writer.println();
示例代码
package com.javasm.controller2;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author gfs
 * @version 0.1
 * @className ResponseDemo
 * @descriptioin:
 * @date 2024/11/20 14:32
 * @since jdk11
 */
@WebServlet("/respDemo")
public class ResponseDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("触发运行了....");
        //返回页面标签
        //设置返回数据格式
        //resp.setContentType("application/json;charset=utf-8");
        //resp.setContentType("text/html;charset=utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获得输出流
        //动态网页技术 数据是否动态生成
        PrintWriter writer = resp.getWriter();
        writer.print("这是一个动态页面<br>");
        writer.print("<input type='text'>&quot;);
//        writer.write();
//        writer.println();
        writer.close();
    }
}

3.5session对象(***)

HttpSession 会话对象 做域对象(缓存数据) 在同一个用户(浏览器)多次访问间共享数据

常用方法
        //域对象 设置键值对
          req.setAttribute(&quot;sesKey&quot;,&quot;sesVal&quot;);
        //域对象读取键值对 注意要强转类型
          String reqKey =(String) req.getAttribute(&quot;sesKey&quot;);
        //删除键值对
          req.removeAttribute(&quot;sesKey&quot;);
        //获得session编号 用来检查是否同一个session对象
        session.getId()
        //设置session访问间隔 单位秒 超过间隔会重新创建session
        session.setMaxInactiveInterval(5);    
        //直接设置session失效
        session.invalidate();
示例代码
package com.javasm.controller2;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className HttpSessionDemo
 * @descriptioin:
 * @date 2024/11/20 14:40
 * @since jdk11
 */
@WebServlet(&quot;/sesDemo&quot;)
public class HttpSessionDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获得session对象 req.getSession()
        HttpSession session = req.getSession();
        //session编号 C03DDD56DF31BAB3EB6A41DB728815CF
        //每个session都会起编号 如过session对象相同 编号是相同的
        System.out.println(session.getId());
        //MaxInactiveInterval 最大非活动周期  两次访问的间隔
        //
        //session.setMaxInactiveInterval(5);
        session.invalidate();
        /*
        * session三种失效方式
        * 1.浏览器关闭
        * 2.超过访问间隔
        * 3.直接设置session失效
        *
        * */
        //session对象保留 但是sesison中的数据可以清除掉
        //session.removeAttribute(&quot;key&quot;);

        /*
        * session使用场景
        * 1.当缓存使用 把一些常用的数据存入session 服务端需要使用时 直接使用共享的数据
        * 2.做访问控制
        *        登录访问控制
        *
        * */

    }
}
session常用场景
* session使用场景
* 1.当缓存使用 把一些常用的数据存入session 服务端需要使用时 直接使用共享的数据
* 2.做访问控制
*        登录访问控制

登录访问控制场景:

![image-20241120152954172](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120152954172.png

示例代码

登录服务 LoginServlet

package com.javasm.controller3;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className LoginServlet
 * @descriptioin:
 * @date 2024/11/20 15:03
 * @since jdk11
 */
@WebServlet(&quot;/login&quot;)
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //做登录....
        System.out.println(&quot;登录代码执行了......&quot;);

        HttpSession session = req.getSession();
        session.setAttribute(&quot;loginUser&quot;,&quot;用户信息....&quot;);

    }
}

用户服务 UserServlet

package com.javasm.controller3;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className LoginServlet
 * @descriptioin:
 * @date 2024/11/20 15:03
 * @since jdk11
 */
@WebServlet(&quot;/user&quot;)
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //查用户信息 必须登录后使用

        HttpSession session = req.getSession();
        String loginUser =(String) session.getAttribute(&quot;loginUser&quot;);
        if(loginUser!=null){
            System.out.println(&quot;查询用户代码执行了......&quot;);
        }else{
            System.out.println(&quot;请先登录......&quot;);
        }

    }
}

商品服务 ProdServlet

package com.javasm.controller3;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className LoginServlet
 * @descriptioin:
 * @date 2024/11/20 15:03
 * @since jdk11
 */
@WebServlet(&quot;/prod&quot;)
public class ProdServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //查商品信息 不需要登录
        System.out.println(&quot;查询商品代码执行了......&quot;);

    }
}

登出服务 LogoutServlet

package com.javasm.controller3;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @author gfs
 * @version 0.1
 * @className LoginServlet
 * @descriptioin:
 * @date 2024/11/20 15:03
 * @since jdk11
 */
@WebServlet(&quot;/logout&quot;)
public class LogoutServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //做登出....
        System.out.println(&quot;登出代码执行了......&quot;);

        HttpSession session = req.getSession();
        //session.setAttribute(&quot;loginUser&quot;,&quot;用户信息....&quot;);
        //session.invalidate();
        session.removeAttribute(&quot;loginUser&quot;);
    }
}

![image-20241120154126511](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120154126511.png

![image-20241120171518464](https://www.neet0316.com/wp-content/uploads/2025/12/image-20241120171518464.png

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇