Servlet - 2part


servlet 分为两部分, 前半部分

1. ServletConfig对象

1.1 简介

  • 作用:通过此对象可以读取web.xml中配置的初始化参数。
  • Servlet 程序 和 ServletConfig 对象是由 Tomcat 负责创建的。Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个Servlet 程序创建时,就会创建一个ServletConfig对象。

1.2 操作演示:

  1. 为demo这个Servlet 配置一个参数,参数名为username,值为zouxiaopang。
<servlet>
    <servlet-name>demo</servlet-name>
    <servlet-class>demo</servlet-class>
    <!-- 初始化参数名 -->
    <init-param>
        <!-- 参数名 -->
        <param-name>username</param-name>
        <!-- 参数值 -->
        <param-value>zouxiaopang</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>demo</servlet-name>
    <url-pattern>/demo</url-pattern>
</servlet-mapping>
  1. demo.java文件中 获取 ServletConfig对象,通过 ServletConfig 对象获取在web.xml文件配置的参数。
// 获取ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
// 根据配置的名字获取值
String value = servletConfig.getInitParameter("username");
// 获取servlet别名
System.out.println(servletConfig.getServletName());
System.out.println(value);

在这里插入图片描述

2. ServletContext对象

2.1 定义与作用

定义:

  • ServletContext是一个接口,它表示Servlet上下文对象。
  • 一个web工程,只有一个ServletContext对象实例。
  • ServletContext对象是一个域对象。
  • ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁。

作用:

  • ServletContext既然代表着当前web站点,那么所有Servlet都共享着一个ServletContext对象,所以Servlet之间可以通过ServletContext实现通讯。
  • ServletConfig获取的是配置的是单个Servlet的参数信息,ServletContext可以获取的是配置整个web站点的参数信息
  • 利用ServletContext 读取web站点的资源文件
  • 实现Servlet的转发(用ServletContext转发不多,主要用request转发)

域对象

  • 域对象,是可以像 Map 一样存取数据的对象。 这里的域指的是存取数据的操作范围,整个 web 工程。
Map域对象
putsetAttribute()
get()getAttribute()
删除remove()removeAttribute()

2.2 操作演示:

  1. 修改demo.java中代码
public class demo extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
        String value = "zouxiaopang";
        //MyName作为关键字,value作为值存进   域对象【类型于Map集合】
        servletContext.setAttribute("MyName",value);
        System.out.println("我是demo!");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}
  1. 创建demo2.java
public class demo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
        //通过关键字获取存储在域对象的值
        String value = (String) servletContext.getAttribute("MyName");
        System.out.println("我是demo1=2:"+ value);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
  1. 如果直接访问demo2,会获取不到MyName关键字的值,值为null。
    在这里插入图片描述
  2. 需要先访问demo,在访问demo2,才能获取到MyName关键字的值。
    在这里插入图片描述

2.3 获取web站点配置的信息

  • web.xml文件支持对整个站点进行配置参数信息(所有Servlet都可以取到该参数信息)。
  1. web.xml文件中配置参数信息
<context-param>
    <param-name>MyName</param-name>
    <param-value>zouxiaopang</param-value>
</context-param>
  1. demo.java中通过名称获取值
public class demo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = this.getServletContext();
        //通过名称获取值
        String value = servletContext.getInitParameter("MyName");
        System.out.println("我是demo2:"+ value);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

在这里插入图片描述
3. 同理,对该站点的所有Servlet都可以获得到MyName的值。

2.4 读取资源文件

  • 资源文件放在web目录下,直接通过文件名就能获取。
InputStream in = this.getServletContext().getResourceAsStream(
				"/db.properties");
  • 资源文件在src下,那么在web服务器中的位置是WEB-INF/classes
InputStream in = this.getServletContext().getResourceAsStream(
				"/WEB-INF/classes/db.properties");
  • 资源在中,那么在web服务器中的位置是WEB-INF/classes/package
InputStream in = this.getServletContext().getResourceAsStream(
				"/WEB-INF/classes/test/db.properties");
  1. 编写db.properties文件
username=zouxiaopang;
password=123456;
  1. 修改demo.java文件中代码
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取ServletContext对象
    ServletContext servletContext = this.getServletContext();
    //通过类装载器获取到读取文件流
    InputStream inputStream  = servletContext.getResourceAsStream("/db.properties");
    read(inputStream);
}

private void read(InputStream in) throws IOException {
    Properties prop = new Properties();
    prop.load(in);
    String username = prop.getProperty("username");
    String password = prop.getProperty("password");
    System.out.println(username);
    System.out.println(password);
}
  1. 访问demo页面
    在这里插入图片描述

3. HttpServletResponse

  http响应由状态⾏、实体内容、消息头、⼀个空⾏组成。HttpServletResponse对象就封装了http响应的信息
  注:如果需要设置返回给用户端的信息,可以通过HttpServletResponse对象来进行设置。

3.1 向浏览器输出数据

  • 输出流(两个流只能使用一个)
字节流getOutputStream();常用于下载(传递二进制数据)
字符流getWriter();常用于回传字符串

调⽤getOutputStream()⽅法向浏览器输出数据,可以使⽤print()也可以使⽤write()

//获取到PrintWriter对象
PrintWriter printWriter = response.getWriter();
printWriter.write("邹小胖向前冲!");
 //获取到OutputStream流
ServletOutputStream servletOutputStream = response.getOutputStream();
//向浏览器输出数据
servletOutputStream.write(("邹小胖向前冲!").getBytes());
servletOutputStream.write(("邹小胖向前冲!").getBytes("UTF-8"));
  1. getBytes()可以正常输出中文:代码在转成byte[]数组的时候默认查的是gb2312编码,⽽"邹小胖向前冲!"⽀持gb2312编码,所以可以正常显示出来。
  2. getBytes("UTF-8"); 会出现乱码,但是程序要实现连通性,应该使用UTF-8编码。
    在这里插入图片描述

避免乱码

  • 方案一(不推荐):
 // 设置服务器字符集为UTF-8    
response.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用UTF-8字符集
response.setHeader("Content-Type","text/html;charset=UTF-8");
  • 方案二(推荐):
//同时设置服务端和客户端都使用UTF-8字符集,还设置了响应头
//此方法必须在获取对象之前调用才有用
response.setContentType("text/html;charset=UTF-8");

在这里插入图片描述

3.2 实现文件下载

现在想要下载本工程下,web目录里的1.jpg,代码如下:

//获取到资源的路径
String path = this.getServletContext().getRealPath("/1.jpg");
//读取资源
FileInputStream fileInputStream = new FileInputStream(path);
//获取到文件名,路径在电脑上保存是\\形式的。
//attachment:提示用户保存
String fileName = path.substring(path.lastIndexOf("\\") + 1);
//设置消息头,告诉浏览器,我要下载1.jpg这个图⽚
response.setHeader("Content-Disposition","attachment;filename="+fileName);
// 将读取的资源传给浏览器
int len = 0;
byte[] bytes = new byte[1024];
ServletOutputStream servletOutputStream = response.getOutputStream();

while((len = fileInputStream.read(bytes)) > 0 ) {
    servletOutputStream.write(bytes,0,len);
}
//关闭资源
servletOutputStream.close();
fileInputStream.close();

在这里插入图片描述

  1. path.lastIndexOf("\") + 1 解释:
    如果取一个文件名 D:\img\abc.jpg,如果要得到abc.jpg,如果不加一,就会得到包括\本身,成了\abc.jpg。
  2. 文件名为中文,会造成乱码,解决方法:
response.setHeader("Content-Disposition", "attachment; filename=" +URLEncoder.encode(fileName, "UTF-8"));

3.3 实现自动刷新

以规定的时间让⻚⾯刷新,更新资源。

response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("3秒后自动跳转至index界面.....");
//三秒后跳转到index.jsp页面,3秒自动刷新
response.setHeader("Refresh","3;url=/index.jsp");

在这里插入图片描述在这里插入图片描述

3.4 生出随机图片

在我们登陆的时候经常要写验证码,⽽那些验证码是⼀张图⽚,就是通过HttpServletResponse写给浏览器的。

  1. java提供了BufferedImage类,生成一张图片
 //在内存中⽣成⼀张图⽚,宽为80,⾼为20,类型是RGB
BufferedImage bufferedImage = new BufferedImage(80, 20,BufferedImage.TYPE_INT_RGB);
//获取到这张图⽚
Graphics graphics = bufferedImage.getGraphics();
//填充整张图⽚
graphics.fillRect(0, 0, 80, 20);
//往图⽚设置颜⾊和字体
graphics.setColor(Color.blue);
graphics.setFont(new Font(null, Font.BOLD, 20));
//往图⽚上写数据,先写个12345,横坐标是0,纵坐标是20【⾼度】
String str = makeNum();
graphics.drawString(str, 0, 20);
//要往浏览器写⼀张图⽚,那要告诉浏览器回送的类型是⼀张图⽚
response.setHeader("ContentType", "jpeg");
//java提供了图⽚流给我们使⽤,这是⼀个⼯具类
//把图⽚传进去,类型是jpg,写给浏览器
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
  1. 生成随机数
private String makeNum() {
    Random random = new Random();
    //这样就会⽣成0-7位的随机数,现在问题⼜来了,如果随机数不够7位呢?如果不够7位,我们加到7位

    int anInt = random.nextInt(9999999);
    //将数字转成是字符串
    String num = String.valueOf(anInt);
    //判断位数有多少个,不够就加
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < 7 - num.length(); i++) {
        stringBuffer.append("0");
    }
    return stringBuffer.append(num).toString();
}

在这里插入图片描述

3.5 重定向跳转

  点击⼀个超链接,通知浏览器跳转到另外的⼀个页面就叫重定向跳转。⻚⾯之间的跳转有两种⽅式:重定向和转发。

  • output.java文件中,编写代码,在页面中输入http://localhost:8080/output会重定向到http://localhost:8080/form.jsp中。
response.sendRedirect("/form.jsp");
  • 通过观察http协议,看到两个状态码,分别是302、200。302状态码在http协议中代表的是临时重定向。
    在这里插入图片描述

  • 举个例⼦:我找纪律委员说:给我⼀份请假表,我要回家。纪律委员告诉我:我这⾥没有请假表,你去找辅导员吧。

  • 重定向是通过302状态码和跳转地址实现的。于是可以通过设置http消息头就可以实现重定向跳转。

//设置状态码为302
response.setStatus(302);
//HttpServletResponse把常⽤的状态码封装成静态常量了,所以我们可以使⽤SC_MOVED_TEMPORARILY代表着302
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);

response.setHeader("Location","/form.jsp");

4. HttpServletRequest

  HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

常用方法:

方法作用
getRequestURI()获取请求的资源路径
getRequestURL()获取请求的统一资源定位符(绝对路径)
getRemoteHost()获取客户端的ip地址
getHeader()获取请求头
getParameter()获取请求的参数
getParameterValues()获取请求的参数(多个值的时候使用)
getMethod()获取请求的方式GET或POST
setAttribute(key,value);设置域数据
getAttribute(key);获取域数据
getRequestDispatcher()获取请求转发对象

4.1 防盗链

  我现在有某电视剧的最新资源,想要看电视剧的人需要在我的网页上看。现在别的网站的人看到我的资源,想要把我的资源粘贴在他自己的网站上。这样我独家的资源就被一个CTRL+C和CTRL+V抢走了,而反盗链就是为防止他们CRTL+C 和 CRTL+V。

  1. 创建mmm.jsp文件,为进入电视剧最新资源的跳板(必须经过此页面,才可以访问最新资源)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>点击下面链接,进入</h3>
    <a href="http://localhost:8080/movie.jsp">青春有你3最新资源</a>
</body>
</html>
  1. 编写movie.java程序
    注:`sendRedirect语句后面必须加return;
public class movie extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取到网页是从哪里来的
        String referer = request.getHeader("Referer");
        //如果不是从我的首页来或者从地址栏直接访问的,
        if(referer == null||!referer.contains("localhost:8080/mmm.jsp")){
            //回到必经页面mmm.jsp
            response.sendRedirect("http://localhost:8080/mmm.jsp");
            return;
        }
        else{
            //能执行下面的语句,说明是从mmm.jsp点击进来的,那没问题,照常显示
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("余景天!!!大板凳!!!");
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
  1. 修改web.xml文件
<servlet>
    <servlet-name>movie</servlet-name>
    <servlet-class>fangdao.movie</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>movie</servlet-name>
    <url-pattern>/movie.jsp</url-pattern>
</servlet-mapping>

如果直接复制http://localhost:8080/movie.jsp,将自动跳转至如下界面
在这里插入图片描述通过点击青春有你3的链接,回调到movie.jsp里
在这里插入图片描述

4.2 表单提交数据

  1. 创建form.jsp
<form action="/zouxiaopang/formpost" method="post">
    <table>
        <tr>
            <td>用户名</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密码</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>性别</td>
            <td>
                <input type="radio" name="gender" value=""><input type="radio" name="gender" value=""></td>
        </tr>
        <tr>
            <td>爱好</td>
            <td>
                <input type="checkbox" name="hobbies" value="游泳">游泳
                <input type="checkbox" name="hobbies" value="跑步">跑步
                <input type="checkbox" name="hobbies" value="飞翔">飞翔
            </td>
        </tr>
        <input type="hidden" name="aaa" value="my name is zouxiaopang">
        <tr>
            <td>你的来自于哪里</td>
            <td>
                <select name="address">
                    <option value="宁波">宁波</option>
                    <option value="深圳">深圳</option>
                    <option value="北京">北京</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>详细说明:</td>
            <td>
                <textarea cols="30" rows="2" name="textarea"></textarea>
            </td>
        </tr>
        <tr>
            <td><input type="submit" value="提交"></td>
            <td><input type="reset" value="重置"></td>
        </tr>
    </table>
</form>
  1. 创建formpost.java文件
    Tomcat服务器默认编码是ISO 8859-1,而浏览器使用的是UTF-8编码。
public class formpost extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置request字符编码的格式
        request.setCharacterEncoding("UTF-8");

        //通过html的name属性,获取到值
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");

        //复选框和下拉框有多个值,获取到多个值
        String[] hobbies = request.getParameterValues("hobbies");
        String[] address = request.getParameterValues("address");

        //获取到文本域的值
        String description = request.getParameter("textarea");

        //得到隐藏域的值
        String hiddenValue = request.getParameter("aaa");

        System.out.println("username:" + username);
        System.out.println("password:" + password);
        System.out.println("gender" + gender);
        for(String s : hobbies)
            System.out.print(s + " ");
        System.out.println();
        for(String s : address)
            System.out.print(s + " ");
        System.out.println();
        System.out.println("description" + description);
        System.out.println("hiddenValue" + hiddenValue);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}
  1. 修改web.xml文件
    注:url-pattern要和form表单action属性值一样
<servlet>
    <servlet-name>form</servlet-name>
    <servlet-class>formpost</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>form</servlet-name>
    <url-pattern>/zouxiaopang/formpost</url-pattern>
</servlet-mapping>
  1. 运行结果
    请添加图片描述
    请添加图片描述

4.3 超链接方式提交数据

  • 常见的get方式提交数据:使用超链接,sendRedirect
    格式如下:
sendRedirect("servlet的地址?参数名="+参数值 &"参数名="+参数值);
  1. 使用超链接将数据带给浏览器(mmm.jsp文件)
<h3>点击下面链接,选择pick的小孩</h3>
<a href="http://localhost:8080/output?name=连淮伟">连淮伟</a>

在这里插入图片描述

  1. output.java中接受数据
 response.setContentType("text/html;charset=UTF-8");
 String name = request.getParameter("name");
 response.getWriter().write(name + "平安健康!!!");

在这里插入图片描述
注:提交数据能用post就用post,get太过于依赖服务器

4.4 实现转发

  • 使⽤response的sendRedirect()可以实现重定向,做到的功能是页面跳转;
  • 使⽤request的
    getRequestDispatcher.forward(request,response)实现转发,做到的功能也是⻚⾯跳转
  1. output.java 实现转发,可以添加参数!
//为name关键字设置值为 邹小胖
request.setAttribute("name","邹小胖");
// 获取到requestDispatcher 对象
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/input");
// 调用requestDispatcher 对象的 forwar() 实现转发,传入request,response
requestDispatcher.forward(request,response);
  1. input.java 中进行处理
response.setContentType("text/html;charset=UTF-8");
String name = (String)request.getAttribute("name");
response.getWriter().write(name);

在这里插入图片描述注意点

  • 使⽤ServletContext和request实现Servlet之间的通讯,⼀般的原则:可以使⽤request就尽可能使⽤request。因为ServletContext代表着整个web应⽤,使⽤ServletContext会消耗⼤量的资源,⽽request对象会随着请求的结束⽽结束,资源会被回收。使⽤request域进⾏Servlet之间的通讯在开发中是⾮常频繁的。
  • 如果在调⽤forward⽅法之前向Servlet引擎的缓冲区中写⼊了内容,只要写⼊到缓冲区中的内容还没有被真正输出到客户端,forward⽅法就可以被正常执⾏,原来写⼊到输出缓冲区中的内容将被清空,但是,已写⼊HttpServletResponse对象中的响应头字段信息保持有效。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值