day13-request和response

来源:互联网 发布:淘宝店铺怎样进行装修 编辑:程序博客网 时间:2024/06/13 23:53
知识点:

1.servletContext的另外一个作用读取文件(获取配置文件)

2.文件下载(重要)

3.中文乱码(response) 想页面返回信息乱码的解决方法

4.Request后台获取值信息乱码的解决方法


1.页面跳转(转发 &重定向)(重要面试题)

2.完成注册

 

Debug调试:

快捷键F5进入,F6下一步 , F8直接运行至下一个断点(没有断点了的话就直接完成全部语句)

一.ServletContext的功能:

【功能一:读取全局初始化参数】(了解)

* StringgetInitParameter(String name);      ---获得Servlet的初始化参数的.

* EnumerationgetInitParameterNames();     ---获得所有Servlet的初始化参数的名称.

 

演示方法同读取web工程下的文件.

1.配置全局初始化参数的代码:

<display-name>day10</display-name>

  <context-param>是在servlet标签外的

    <param-name>username</param-name>

    <param-value>root</param-value>

  </context-param>

  <context-param>

    <param-name>password</param-name>

    <param-value>123</param-value>

 </context-param>

 

2.读取全局初始化参数

         private void test1(){

                   Stringusername =this.getServletContext().getInitParameter("username");

                   Stringpassword =this.getServletContext().getInitParameter("password");

                   System.out.println(username+"    "+password);

                  

                   Enumeration<String>e =this.getServletContext().getInitParameterNames();

                   while(e.hasMoreElements()){

                            Stringname =e.nextElement();

                            Stringvalue =this.getServletContext().getInitParameter(name);

                            System.out.println(name+"    "+value);

                   }


【功能二:获得文件的MIME的类型】

private void test2() {

                   Stringtype =this.getServletContext().getMimeType("1.html");

                   System.out.println(type);

         }

演示方法开工程à登servlet

【功能三:作为域对象存取数据】

范围:整个web项目.而且全局的对象.

创建:服务器启动的时候,服务器为每个web项目创建一个单独的ServletContext对象.

销毁:服务器关闭的时候销毁ServletContext.

 

前面已讲.(记录登录人数)

【功能四:读取web项目下的文件】

【演示传统方式读取WEB工程文件】

          * 传统方式读取文件:

          * * 使用的是相对路径,相对的JVM的路径.

          * * 但是现在是一个web项目,相对于JVM的路径的.现在JVM已经交给tomcat管理.

          * 所以现在是相对tomcat管理的bin路径,此时可以在bin下创建src文件夹,里面放properties

          * 而且还必须在bin下点startup启动tomcat,才能读取配置文件.十分繁琐

          */

         private void test1() throwsFileNotFoundException, IOException {

                   InputStreamis =newFileInputStream("src/db.properties");

                   Propertiesproperties =new Properties();

                   properties.load(is);

                  

                   StringdriverClass =properties.getProperty("driverClass");

                   Stringurl =properties.getProperty("url");

                   Stringusername =properties.getProperty("username");

                   Stringpassword =properties.getProperty("password");

                  

                   System.out.println(driverClass);

                   System.out.println(url);

                   System.out.println(username);

                   System.out.println(password);

         }

所以以后读取web项目的文件的时候绝对不能使用相对路径.

【使用ServletContext域对象读取WEB项目下的文件】

* InputStream getResourceAsStream(String path); --- 根据提供路径读取文件返回一个文件的输入流.

* String getRealPath(String path); --- 返回一个路径的磁盘绝对路径.

读取文件的路径的书写:此时进的默认路径相当于是在工程里边,就是项目名里了

 

1.getResourceAsStream方式读取:
2.getRealPath来读取的方式:

* 读取WEB工程文件的Servlet

 */

public class ReadFileServletextends HttpServlet {

         protected voiddoGet(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {

                   test3();

         }

@Test

         /**

          * 使用ServletContext中的getRealPath读取.

          */

         private void test3() throwsFileNotFoundException, IOException {

                   // 获得ServletContext:

                   ServletContextcontext =this.getServletContext();

                   // 获得该文件的磁盘绝对路径.

                   StringrealPath =context.getRealPath("/WEB-INF/classes/db.properties");

                   InputStreamis =newFileInputStream(realPath);

                   Propertiesproperties =new Properties();

                   properties.load(is);

                  

                   StringdriverClass =properties.getProperty("driverClass");

                   Stringurl =properties.getProperty("url");

                   Stringusername =properties.getProperty("username");

                   Stringpassword =properties.getProperty("password");

                  

                   System.out.println(driverClass);

                   System.out.println(url);

                   System.out.println(username);

                   System.out.println(password);

         }

        

         /**

          * 使用ServletContext中的getResourceAsStream读取.

          */

         private void test2() throwsFileNotFoundException, IOException {

                   // 获得ServletContext对象:

                   ServletContextcontext =this.getServletContext();

                   InputStreamis =context.getResourceAsStream("/WEB-INF/classes/db.properties");

                   Propertiesproperties =new Properties();

                   properties.load(is);

                  

                   StringdriverClass =properties.getProperty("driverClass");

                   Stringurl =properties.getProperty("url");

                   Stringusername =properties.getProperty("username");

                   Stringpassword =properties.getProperty("password");

                  

                   System.out.println(driverClass);

                   System.out.println(url);

                   System.out.println(username);

                   System.out.println(password);

         }

        

         /**

          * 传统方式读取文件:

          * * 使用的是相对路径,相对的JVM的路径.

          * * 但是现在是一个web项目,相对于JVM的路径的.现在JVM已经交给tomcat管理.

          * 所以现在是相对tomcat管理的bin路径,此时可以在bin下创建src文件夹,里面放properties

          * 而且还必须在bin下点startup启动tomcat,才能读取配置文件.十分繁琐

          */

         private void test1() throwsFileNotFoundException, IOException {

                   InputStreamis =new FileInputStream("src/db.properties");

                   Propertiesproperties =new Properties();

                   properties.load(is);

                  

                   StringdriverClass =properties.getProperty("driverClass");

                   Stringurl =properties.getProperty("url");

                   Stringusername =properties.getProperty("username");

                   Stringpassword =properties.getProperty("password");

                  

                   System.out.println(driverClass);

                   System.out.println(url);

                   System.out.println(username);

                   System.out.println(password);

         }

 

         protected void doPost(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {

                   doGet(request,response);

         }

}

演示步骤:发布项目,网页登录到这个Servlet,然后就能看到控制台的输出了.


3.(扩展)类加载器读取文件:

作用:将默认路径定位到classes 下,

 

public class ReadFileUtils {

         public static void readFile() throws IOException{

                   // 使用类的加载器来读取文件.

                   // 类的加载器用来加载class文件,class文件加载到内存.

                   InputStreamis = ReadFileUtils.class.getClassLoader().getResourceAsStream("db.properties");

                   Propertiesproperties =new Properties();

                   properties.load(is);

                 

                   StringdriverClass =properties.getProperty("driverClass");

                   Stringurl =properties.getProperty("url");

                   Stringusername =properties.getProperty("username");

                   Stringpassword =properties.getProperty("password");

                  

                   System.out.println(driverClass);

                   System.out.println(url);

                   System.out.println(username);

                   System.out.println(password);

         }

}

 

测试类

public classReadFileServlet2 extends HttpServlet {

         private static final long serialVersionUID = 1L;

         protected voiddoGet(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {

                   ReadFileUtils.readFile();

         }

 

         protected voiddoPost(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {

                   doGet(request,response);

         }

}

二.【Response的概述】

Response:代表响应的对象.从服务器向浏览器输出内容.

【Response的常用的API】

响应行: 设置状态码

SetStatus(状态码) ;

响应头:


* 针对一个key对应多个value的头信息.


* 针对一个key对应一个value的头信息.

响应体



登录成功后,完成文件的下载.

【文件下载的2种方式】

一种:超链接下载.直接将文件的路径写到超链接的href中.---前提:文件类型,浏览器不支持.

二种:手动编写代码的方式完成文件的下载.

* 设置两个头和一个流:

    * Content-Type                    :文件的MIME的类型.

    * Content-Disposition    :以下载的形式打开文件.

    * InputStream               :文件的输入流.

 

文件下载的代码(包含了中文文件的下载处理):

步骤1:(文件下载页面中)对所需要下载的文件的处理:(将文件的名字提交给实现下载功能的DownloadServlet)

步骤2.( DownloadServlet中)先接收文件名,再设置文件类型头,

获得realpath用于设置inputstream ,

再判断用户浏览器类型设置相应编码(处理乱码) ,

再获得inputstream 和response输出流.

 

文件下载页面:

<h3>手动编码方式下载</h3>

<ahref="/day10/DownloadServlet?filename=hello.txt">hello.txt</a><br/>

<a href="/day10/DownloadServlet?filename=美女.jpg">美女.jpg</a><br/>

 

DownloadServlet的代码:

public class DownloadServlet extends HttpServlet {

         private static final long serialVersionUID = 1L;

         protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

                   // 1.接收参数

                   Stringfilename =new String(request.getParameter("filename").getBytes("ISO-8859-1"),"UTF-8");

                   System.out.println(filename);

                   // 2.完成文件下载:

                   // 2.1设置Content-Type

                   Stringtype =this.getServletContext().getMimeType(filename);

                   response.setHeader("Content-Type",type);

                   // 2.3设置文件的InputStream.

                   StringrealPath =this.getServletContext().getRealPath("/download/"+filename);

                  //servletContext读取web项目下文件的getRealPath方式,默认工程名下开始

                   // 根据浏览器的类型处理中文文件的乱码问题:

                   Stringagent =request.getHeader("User-Agent");

                   System.out.println(agent);

                   if(agent.contains("Firefox")){

                            filename =base64EncodeFileName(filename);

                   }else{

                            filename = URLEncoder.encode(filename,"UTF-8");

                   }

                  

                   // 2.2设置Content-Disposition    (文件下载使用的一个头信息)

                   response.setHeader("Content-Disposition","attachment;filename="+filename);

                   //服务器内存去服务器磁盘中查找到相应的文件通过输入流加载到服务器内存中,最后再向浏览器输出

                   InputStreamis =new FileInputStream(realPath);

                   // 获得response的输出流:

                   OutputStreamos =response.getOutputStream();

                   intlen = 0;

                   byte[]b = newbyte[1024];

                   while((len =is.read(b))!= -1){

                            os.write(b, 0,len);

                   }

                   is.close();

         }

         //base64编码的设置代码,比较十分复杂,只需要知道拿来用就行了

         public static Stringbase64EncodeFileName(String fileName) {

                   BASE64Encoderbase64Encoder =newBASE64Encoder();

                   try {

                            return"=?UTF-8?B?"

                                               +new String(base64Encoder.encode(fileName

                                                                 .getBytes("UTF-8"))) +"?=";

                   }catch(UnsupportedEncodingExceptione) {

                            e.printStackTrace();

                            thrownewRuntimeException(e);

                   }

         }

总结response输出方式与乱码:

response输出响应内容的方法:(向页面响应)

使用字节流响应数据:

private void test1(HttpServletResponse response)throws IOException {

                   response.getOutputStream().write("HelloOutputStream Response...".getBytes());

         }

 

使用字符流响应数据:

private void test2(HttpServletResponseresponse)throws IOException {

                   response.getWriter().println("HelloWriter Response...");

         }      

 

规定:这两个方法是互斥的. 做出响应的时候只能使用其中的一种流响应.

 

* 使用字节流输出中文:不一定有乱码.

      * 设置中文转成字节数组取出的时候的编码

  * 设置浏览器默认打开的时候编码

         private void test3(HttpServletResponseresponse)throws IOException {

                   // 设置浏览器默认打开的时候采用的字符集编码

                   response.setHeader("Content-Type","text/html;charset=UTF-8");

                   // 设置中文转成字节数组的时候取出的编码

                   response.getOutputStream().write("中文".getBytes("UTF-8"));

         }

   

* 使用字符流输出中文:一定会乱码

* 设置response的字符流的缓冲区的编码(默认的编码是ISO-8859-1).

* 设置浏览器默认打开的时候采用的字符集编码.

       private voidtest4(HttpServletResponse response)throws IOException {

                   // 设置浏览器默认打开的时候采用的字符集编码

                   //response.setHeader("Content-Type","text/html;charset=UTF-8");

                   // 设置response的字符流的缓冲区的编码.

                   //response.setCharacterEncoding("UTF-8");

                  

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

                   response.getWriter().println("中文");

         }

三.【Request的功能(API)】

功能一:获得客户机相关的信息

1.获得请求方式:(动态代理的通用字符集filter中用到)

2.获得请求的路径:URI为从工程开始的路径名, URL为全路径名

3.获得客户机IP地址

4.获得工程名:用于跳转的工程名通用匹配

protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

                   String method =request.getMethod();//获得请求方式:

                   System.out.println("请求方式:"+method);

                   String ip =request.getRemoteAddr();//获得客户机的IP地址:

                   System.out.println("IP地址:"+ip);

                   String url =request.getRequestURL().toString();//获得用户的请求的全路径:

                   String uri =request.getRequestURI();//从工程开始的路径名

                   String contextPath =request.getContextPath();//获得发布的工程名:

                   System.out.println("工程名:"+contextPath);

         }

功能二:(重要)获得从页面中提交的参数:(用于servlet中获取前台数据)


功能三:作为域对象存取数据:(下面讲)

RemoveAttribute(String name ) ;

SetAttribute(String name , Object object) ;

getAttribute (String name) ;得到一个对象

 

完成用户注册的功能:

网站首页上点击注册的链接,跳转到注册页面,在注册页面中输入信息.完成注册:(将数据保存到数据库中).

 

注册代码实现:

原理,首先将注册页面表单的数据提交到RegistServlet中,然后依次其中调用service业务层的注册方法. dao层的注册方法.注册完后直接跳转到登录的页面.

public class RegistServlet extends HttpServlet {

         private static final long serialVersionUID = 1L;

         protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

                   try{

                            request.setCharacterEncoding("UTF-8");

                            // 1.接收参数

                            Stringusername =request.getParameter("username");

                            Stringpassword =request.getParameter("password");

                            Stringemail =request.getParameter("email");

                            Stringname =request.getParameter("name");

                            Stringsex =request.getParameter("sex");

                            Stringtelephone =request.getParameter("telephone");

                            // 2.封装数据

                            Useruser =new User();

                            user.setUsername(username);

                            user.setPassword(password);

                            user.setEmail(email);

                            user.setName(name);

                            user.setSex(sex);

                            user.setTelephone(telephone);

                           

                            // 3.调用业务层处理数据

                            UserServiceuserService =new UserService();

                            userService.regist(user);

                            // 4.页面跳转                  response.sendRedirect(request.getContextPath()+"/demo2-regist/login.htm");

                   }catch(Exceptione){

 

* DAO中的用户的注册的方法:

         public void regist(User user) throws SQLException {

                   QueryRunnerqueryRunner =newQueryRunner(JDBCUtils.getDataSource());

                   Stringsql ="insertinto user values (null,?,?,?,?,?,?)";

                   Object[]params = {user.getUsername(), user.getPassword(), user.getEmail(), user.getName(), user.getSex(),

                                     user.getTelephone()};

                   queryRunner.update(sql,params);

         }

总结request接收参数的中文乱码:

1.处理request接收参数的中文乱码的问题:

现在无论是GET还是POST提交中文的时候,都会出现乱码的问题.

 

POST的解决方案:

*request的缓冲区是ISO-8859-1编码. 所以需要设置request的缓冲区的编码

*(重点)request.setCharacterEncoding(“UTF-8”);

 ---一定要在接收参数之前设置编码就OK.

protected voiddoPost(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {

                   request.setCharacterEncoding("UTF-8");

                   Stringname =request.getParameter("name");

                   System.out.println("POST方式:"+name);

         }

 

 

GET的解决方案:(公司中根本不会用get提交)

* 方法1.使用URLEncoder和URLDecoder进行编码和解码的操作.

* 方法2.(重点).使用String的构造方法:

protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {                  

                   Stringname =new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");

                   System.out.println("GET方式:"+name);

         }

 

面试题:Tomcat优化(优化字符集):(有视频)


2.面试题:重定向和转发的区别:(redirect和forward的区别)都是实现页面的跳转

页面跳转的重定向写法:

protected voiddoGet(HttpServletRequest request,HttpServletResponseresponse) throwsServletException, IOException {

              // 重定向:

                   //response.sendRedirect("/day10/ForwardServlet2");

 

// 转发:

                 request.getRequestDispatcher("/ForwardServlet2").forward(request,response);

                  

* 1.重定向的地址栏会发生变化,转发的地址栏不变.

* 2.重定向两次请求两次响应,转发一次请求一次响应.(最重要的回答)

* 3.重定向路径需要加工程名,转发的路径不需要加工程名.

* 4.重定向可以跳转到任意网站,转发只能在服务器内部进行转发.

重定向跳转的浏览器效果图.

转发跳转的浏览器效果图.

防止重复提交:

 

3.Request作为域对象存取数据:

使用request对象存取数据:

* setAttribute(Stringname,Stringvalue);

* ObjectgetAttribute(String name);

 

request的作用范围:

* 作用范围就是一次请求的范围.(重定向的方式就取不到request所存的值了,下面举例)

* 创建和销毁:

    * 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象.

    * 销毁:当服务器对这次请求作出了响应之后.

网站跳网站必须是重定向 ;

登录信息填写错误后跳转回重新填写并返回错误信息,使用转发.

 

4.在登录失败时重新跳转到登录的页面,并且在页面上显示用户名或者密码错误的提示信息.

首先在接收前台数据的后台Userservlet中用request存好要输出的提示语句,然后跳转回登录页面并显示提示,由于html是静态页面所以我们要重新写一份jsp的登录页面并且在需要显示的地方添加取出语句,才能显示request存的提示语句.并且由于requst存的数据的作用范围只能在一次请求中,因为重定向是两次请求两次相应所以我们只能够使用转发的方式实现页面的跳转.

Userservlet中的关键语句:

if(existUser ==null){

         request.setAttribute("msg","用户名或密码错误!");                      request.getRequestDispatcher("/demo1-download/login.jsp").forward(request,response);

 

jsp页面需要显示提示的地方添加取出语句的关键语句;

         <font>会员登录</font>USER LOGIN<br/>

         <span>${msg }</span>

         <div>&nbsp;</div>

 

今日重点:

Request .  getparameter . setattribute  . 转发重定向 . 



原创粉丝点击