HttpServletRequest&HttpServletResponse

HttpServletRequest&HttpServletResponse

1.Servlet配置方式

  • 全路径匹配

    以/开始,如/a,/HelloServlet
    

    访问方式:localhost:8080/项目名称/a

  • 路径匹配,前半段匹配

    以/开始,以*结束,如/b/*,/*
    

    访问方式:localhost:8080/项目名称/b/任意

  • 扩展名匹配

    没有/,以*开始,如*.aa
    

    访问方式:localhost:8080/项目名称/任意.aa

2.ServletContext

Servlet上下文,每个web工程都只有一个ServletContext对象,即在一个web工程中无论在哪个Sevlet里获取到的ServletContext都是同一个。在B项目重无法取到A项目的ServletContext,因为ServletContext对象不同。

2.1作用

2.1.1获取全局配置参数

  • web.xml
<!--全局配置参数,哪个Servlet都可以拿到-->
<context-param>
      <param-name>producer</param-name>
      <param-value>wang</param-value>
</context-param>
  • HelloServlet03
//获取ServletContext对象
ServletContext servletContext = getServletContext();
//1.获取全局参数
String producer = servletContext.getInitParameter("producer");
System.out.println(producer);

2.1.2获取web工程中的资源

  • config.properties

name=zhangsan
  • HelloServlet3
		//2.获取web工程中的资源
        //2.1法一:先获取config.properties在tomcat里的绝对路径,再new InputStream
        String realPath = servletContext.getRealPath("");//获取项目在tomcat里的根目录
        System.out.println(realPath);//D:\IDEA.workspace\Demo01\out\artifacts\Demo1_war_exploded2\
        String realPath1 = servletContext.getRealPath("file/config.properties");  

System.out.println(realPath1);//D:\IDEA.workspace\Demo01\out\artifacts\Demo1_war_exploded2\file\config.properties
        Properties p=new Properties();
        InputStream is=new FileInputStream(realPath1);
        p.load(is);
        System.out.println(p.getProperty("name"));

//2.2法二:直接给相对路径,通过getResourceAsStream获取资源流对象
        InputStream resourceAsStream1 = servletContext.getResourceAsStream("file/config.properties");
        p.load(resourceAsStream1);
        System.out.println(p.getProperty("name"));
  • 通过classLoader获取web工程下的资源
InputStream resourceAsStream = HelloServlet3.class.getClassLoader().getResourceAsStream("../../file/config.properties");
/*
此处classLoader的路径为:D:\IDEA.workspace\Demo01\out\artifacts\Demo1_war_exploded2\WEB-INF\classes,所以需要往上找两级,才能获取config.properties的相对路径
*/
p.load(resourceAsStream);
System.out.println(p.getProperty("name"));

2.1.3存取数据,servlet间共享数据

  1. login.html

    <form action="LoginServlet" method="get">
            账号:<input type="text" name="username"><br/>
            密码:<input type="text" name="password"><br/>
            <input type="submit" value="登录">
    </form>
    
  2. LoginServlet

    public class LoginServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1.获取数据
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            PrintWriter pw=resp.getWriter();
            //2.校验数据
            if (username.equals("abc")&&password.equals("123")){
                ServletContext servletContext = getServletContext();
                //2.1获取以前登录成功的次数
                Integer count =(Integer) servletContext.getAttribute("count");
                if(null==count){
                    count=0;
                }
                //2.2登录成功次数加1
                servletContext.setAttribute("count",count+1);
                //2.3跳转到login_success.html
                //设置状态码,302表示临时重定向,常用于页面跳转
                resp.setStatus(302);
                //Location为固定写法,后面为要跳转的页面
                resp.setHeader("Location","login_success.html");
            }else{
                pw.write("login failed");
            }
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    

关于resp.setHeader("Location","login_success.html"),可参见E:\6.1java就业班全套视频\10.HTTP&Servlet(9集)\me第2套 参考学习\code&资料\资料\Http1.1规范.pdf

  1. login_success.html
<a href="CountServlet">获取网站登录成功次数</a>
  1. CountServlet

    public class CountServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext servletContext = getServletContext();
            Integer count = (Integer) servletContext.getAttribute("count");
            PrintWriter writer = resp.getWriter();
            writer.print(count);
            /*
            此处用writer()方法时,弹出了下载对话框,可能是因为writer里有方法是阻塞的,换成print()方法即可*/
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    

3.HttpServletRequest

这个对象封装了客户端提交过来的所有数据。

3.1作用

3.1.1获取客户端请求头信息

Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()){
      String name = headerNames.nextElement();
      String value = req.getHeader(name);
          System.out.println("name="+name+"\t"+"value="+value);
}

3.1.2获取客户端提交过来的数据

  • 获取单个值

    如:name=zhangsan&password=123

String username = req.getParameter("username");
String password = req.getParameter("password");
  • 获取多个值

    name=zhangsan&name=lisi&name=wangwu 一个key对应多个值

Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> keySet = parameterMap.keySet();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            String[] strings = parameterMap.get(key);
            for (String s:strings){
                System.out.println(s);
            }
        }

3.1.3获取中文数据乱码问题

客户端提交数据给服务器端,如果数据中带有中文,可能出现乱码,可参照以下方法解决。

  • Get请求

    1.代码转码

    String username = req.getParameter("username");
    String password = req.getParameter("password");
    System.out.println(username+"\t"+password);
    //get请求过来的数据,在url地址栏上就已经经过编码了,所以我们取到的就是乱码,tomcat收到了这批数据,getParameter默认使用ISO-8859-1去解码
    
    //先让文字回到ISO-8859-1对应的字节数组 , 然后再按utf-8组拼字符串
    username = new String(username.getBytes("ISO-8859-1") , "UTF-8");
    
    1. 修改tomcat配置文件

    直接在tomcat里面做配置,以后get请求过来的数据永远都是用UTF-8编码。可以在tomcat里面conf/server.xml的Connector标签上加上URIEncoding="utf-8"。

    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
    
  • Post请求

    req.setCharacterEncoding("UTF-8");
    //设置请求体里的文字编码,要写在req.getParameter之前
    

4.HttpServletResponse

负责返回数据给客户端。

4.1作用

4.1.1输出数据到页面

//1.以字符流的方式写数据
resp.getWriter().write("hello response");
//2.以字节流的方式写数据
resp.getOutputStream().write("hello response".getBytes());

4.1.2响应中文数据乱码问题

  • 以字符流输出
//1.指定输出到客户端时,这些文字使用UTF-8编码
resp.setCharacterEncoding("UTF-8");
//2.规定浏览器看这份数据时使用UTF-8编码
resp.setHeader("Content-Type","text/html;charset=UTF-8");//固定写法,参见Http 1.1规范
resp.getWriter().write("今天周一");
  • 以字节流输出
//1.规定浏览器看这份数据时使用UTF-8编码
resp.setHeader("Content-Type", "text/html;charset=UTF-8");
//2. 指定输出的中文用的码表
resp.getOutputStream().write("今天周一".getBytes("UTF-8"));

不管是字节流还是字符流,直接一行代码搞定:

resp.setContentType("text/html;charset=UTF-8");

然后再写数据即可。

5.下载资源案例

5.1直接以超链接方式下载

直接以超链接的方式下载,不写任何代码。 也能够下载东西下来。原因是tomcat里面有一个默认的Servlet:DefaultServlet 。这个DefaultServlet专门用于处理放在tomcat服务器上的静态资源。

  • download.html
<a href="file/aa.jpg">aa.jpg</a><br>
<a href="file/bb.txt">bb.txt</a><br>
<a href="file/cc.rar">cc.rar</a><br>
<a href="file/黑马.png">黑马.png</a><br>

5.2手动编码实现下载

  • download.html
<a href="DownloadServlet?filename=aa.jpg">aa.jpg</a><br>
<a href="DownloadServlet?filename=bb.txt">bb.txt</a><br>
<a href="DownloadServlet?filename=cc.rar">cc.rar</a><br>
<a href="DownloadServlet?filename=黑马.png">黑马.png</a><br>

  • DownloadServlet
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取要下载的文件名称
        String filename = req.getParameter("filename");
        System.out.println(filename);
        //2.获取此文件在tomcat里的绝对路径
        String realPath = getServletContext().getRealPath("file/" + filename);
        //解决文件下载时文件名中的中文乱码问题
        //获取客户端类型
        String clientType = req.getHeader("User-Agent");
        System.out.println(clientType);
        if(clientType.contains("Firefox")){
            //如果是火狐浏览器
            byte[] bytes=filename.getBytes("UTF-8");
            filename=new String(bytes,0,bytes.length,"ISO-8859-1");
        }else{
            //Edge,chrome等
            filename = URLEncoder.encode(filename, "UTF-8");
        }
        //当用户点击链接时,让浏览器弹出下载框,而不是直接展示
        resp.setHeader("Content-Disposition","attachment; filename="+filename);
        //3.转换成输入流
        InputStream is=new FileInputStream(realPath);
        OutputStream os=resp.getOutputStream();
        byte[] b=new byte[1024];
        while(is.read(b)!=-1){
            os.write(b,0,b.length);
        }
        os.close();
        is.close();
    }
posted @ 2020-10-19 19:20  ALiWang1123  阅读(186)  评论(0编辑  收藏  举报