发布属于自己的第一个java web项目(3)请求和响应

本文详细介绍了Java Web中Servlet的请求路径获取、请求头信息解析、参数处理,以及响应状态码、字符编码、图片响应、重定向、文件下载等关键知识点。通过实例演示和beanutils工具封装,帮助理解Servlet的工作原理。
摘要由CSDN通过智能技术生成


本节主要普及一些概念性的知识,相比前两节操作较少,多多了解

一、Servlet 请求

1.获取路径

具体请求结果可以自己尝试

// 获取虚拟目录路径
public String getContextPath() 
// 获取Servlet的映射路径
public String getServletPath()
// 获取访问者的ip地址
public String getRemoteAddr()
// 获取请求的消息数据
public String getQueryString()
// 获取统一资源标识符
public String getRequestURI()
// 获取统一资源定位符
public String getRequestURL()

2.获取请求头的信息

网址请求头:按f12打开开发者模式,然后进入一个网址,打开Notwork 点开一个请求,如图,headres里面就是请求头信息
在这里插入图片描述

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.util.Enumeration;
import java.util.Iterator;

@WebServlet("/ServletRequest")
public class ServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取一个请求头
        String connection = req.getHeader("connection");
        System.out.println(connection);
        System.out.println("================");

        //获取一个请求的多个值,迭代器遍历
        Enumeration<String> values = req.getHeaders("accept-encoding");
        while (values.hasMoreElements()) {
            String value = values.nextElement();
            System.out.println(value);
        }
        System.out.println("================");

        //获取说有的请求头名称,另外一种遍历方式
        Enumeration<String> headerNames = req.getHeaderNames();
        Iterator<String> stringIterator = headerNames.asIterator();
        while (stringIterator.hasNext()) {
            //通过请求头名称,根据名称获取值
            String handName = stringIterator.next();
            String handValue = req.getHeader(handName);
            System.out.println(handName + " = "+ handValue);
        }
    }

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

可以得到f12下说看到的,但是顺序不一定一致。

3.获取请求参数信息

// 根据参数名获取一个参数值
public String getParameter(String name)
// 根据参数名获取多个参数值
public String[] getParameterValues(String name)
//  获取所有的参数名称
public Enumeration<String> getParameterNames()
// 获取所有的参数名和参数值,并封装为Map集合
public Map<String,String[]> getParameterMap();

用来获取请求参数的值,可以编写一个html页面,跳转到Servlet 也可以直接通过地址栏来获取到值

我们在web目录下面新建regist.html页面并让他跳转到Servlet (此时我的虚拟路径名称为:demo01_war_exploded 所以在前面加上虚拟路径)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
    <form action="/demo01_war_exploded/ServletRequestDemo02" method="post" autocomplete="off">
        姓名:<input type="text" name="username" > <br>
        密码:<input type="password" name="password"> <br>
        爱好:<input type="checkbox" name="hobby" value="study" checked>学习
             <input type="checkbox" name="hobby" value="book" checked>看书
              <input type="checkbox" name="hobby" value="game" >游戏 <br>
        <button type="submit">注册</button>
    </form>
</body>
</html>

对应的Servlet

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.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

@WebServlet("/ServletRequestDemo02")
public class ServletRequestDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//根据参数名获取参数指
        String username = req.getParameter("username");
        System.out.println("姓名:"+username);

        //根据参数名获取多个值
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("爱好:"+ Arrays.toString(hobbies));
        System.out.println("---------");

        //获取所有的参数名称
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            String[] values = req.getParameterValues(parameterName);
            System.out.println(parameterName+":"+Arrays.toString(values));
        }
        System.out.println("----------");

        //获取所有的参数名和参数指,存入一个Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> keys = parameterMap.keySet();
        for (String key : keys) {
            String[] values = parameterMap.get(key);
            System.out.println(key+"="+Arrays.toString(values));
        }
    }

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

访问如图路径并输入相应的值
在这里插入图片描述
点击注册按钮提交,在控制台得到结果

姓名:zhangsan
爱好:[study, book]
---------
username:[zhangsan]
password:[123456]
hobby:[study, book]
----------
username=[zhangsan]
password=[123456]
hobby=[study, book]

这样我们就能得到提交的数据,但是如果提交的值有很多,一次写一个的话未免太复杂了,所以我们可以 通过 beanutils工具类来封装请求结果

封装请求结果

首先新建一个类用来封装结果(对象名称必须和前台的name属性一致

import java.util.Arrays;

public class Student {
    private String username;
    private String password;
    private String[] hobby;

    public Student() {
    }

    public Student(String username, String password, String[] hobby) {
        this.username = username;
        this.password = password;
        this.hobby = hobby;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", hobby=" + Arrays.toString(hobby) +
                '}';
    }
}

然后再 web-> WEB-INF 下面新建一个lib包,将beanutils工具类的相关jar包导入,资源我会在结尾给出
接着来改造我们的Servlet,下面给出相关代码

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取所有的参数名和参数指,存入一个Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        Student stu=new Student();
        try {
            BeanUtils.populate(stu,parameterMap);
            System.out.println(stu);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

然后同样在前台提交,控制台得如下结果

Student{username='zhangsan', password='123', hobby=[study, book]}

注意:

  1. 我们封装类的对象的名称必须和前台name属性里的名称一致
  2. 导入包必须是在web -> WEB-> WEB-INF 下新建lib目录来存放jar包
  3. 如遇到中文乱码问题,在Servlet 加上 req.setCharacterEncoding(“utf-8”);来设置请求编码

二、Servlet响应

浏览器访问服务器后,服务器给客户端响应的数据会封装为ServletResponse对象,它有一个子类叫HttpServletResponse对象,用于封装按照Http协议封装的响应数据。

1.响应状态码

状态码状态
100只有请求的一部分已经被服务器接收,但只要它没有被拒绝,客户端应继续该请求
200请求成功
302重定向,所请求的页面已经临时转移到一个新的 URL
304访问缓存,所请求的页面已经临时转移到一个新的 URL
404客户端错误,请求路径服务器没有对应的资源
405客户端错误,请求方式找不到对应的方法
500服务端错误,可能服务器内部有异常

2.解决响应乱码

注意:此方法虽然可以解决响应乱码,但是因为改变了响应方式为html,所以可能会造成css image 等资源无法访问

//设置响应编码,
resp.setContentType("text/html;charset=utf-8");

3.响应图片

在web/img目录下放一张a.jpeg图片,把图片中所有的字节响应给客户端。

@WebServlet("/ServletRequestDemo03")
public class ServletResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取输出流对象
        ServletOutputStream out = resp.getOutputStream();
        //获取文件的绝对路径
        String imgPath = getServletContext().getRealPath("img/a.jpeg");
        //获取输入流对象
        FileInputStream fis = new FileInputStream(imgPath);
        byte[] bs=new byte[1024];
        int len;
        while ((len=fis.read(bs))!=-1){
            out.write(bs,0,len);
        }
        fis.close();
    }

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

4.重定向和定时刷新

//定时刷新,3秒后跳转到指定页面
 resp.setHeader("Refresh","3;url=regist.html");
 //重定向
 //重定向到regist.html
 //resp.sendRedirect(req.getContextPath()+"//regist.html");
//也可以使用下面两个方法,完成重定向;302表示重定向的状态码
resp.setStatus(302);
resp.setHeader("location","regist.html");
//转发
req.getRequestDispatcher("regist.html").forward(req, resp);

注意:重定向和请求转发不太一样,请求转发是只有一个请求,而重定向有两次请求。所以重定向不能通过请求域共享数据,只有在同一个请求链中才能通过请求域中心数据。

5.文件下载

主要是这一句话,将资源以附件的形式接收

//设置响应头,告诉浏览器以附件形式接受
resp.setHeader("content-disposition","attachment;filename="+file.getName());

例如下载 img/a.jpg的图片

@WebServlet("/servletResponseDemo5")
public class ServletResponseDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //准备要下载的图片
        File file=new File("img/a.jpg");

        //设置响应头,告诉浏览器以附件形式接受
        resp.setHeader("content-disposition","attachment;filename="+file.getName());

        //获取输出流对象
        ServletOutputStream out = resp.getOutputStream();
        //获取文件的绝对路径
        String imgPath = getServletContext().getRealPath(file.getPath());
        //获取输入流对象
        FileInputStream fis = new FileInputStream(imgPath);
        byte[] bs=new byte[1024];
        int len;
        while ((len=fis.read(bs))!=-1){
            out.write(bs,0,len);
        }
        fis.close();
    }

下载所需工具包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值