JavaWeb学习笔记整理3

JavaWeb学习笔记整理3

 

1、通过反射优化方法调用

Servlet是JavaWeb极其重要的一部分,客户端可通过Servlet调用各种方法来实现功能,在前台实现功能时,后台通过得到相应的方法名来决定执行什么方法,如果这时候用if-else来判断就会导致效率低下,同时若方法过多也会导致代码行繁多;故可用类加载器反射得到方法来调用,具体代码如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //解决post请求中文乱码问题
        request.setCharacterEncoding("UTF-8");
        //解决响应中文乱码问题
        response.setContentType("text/html; charset=UTF-8");
        String action = request.getParameter("action");

        //反射优化大量elseif代码

        try {
            //获取action业务鉴别字符串,获取相应的业务、方法反射对象
            Method method =     
 this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
            //调用目标业务方法
            method.invoke(this,request,response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e); //把异常抛给Filter过滤器
        }


 }

 //获取action业务鉴别字符串,获取相应的业务、方法反射对象
 Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
 //调用目标业务方法
method.invoke(this,request,response);

  this.getClass()是获取当前对象的类加载器,

getDeclaredMethod(String name, Class<?>... parameterTypes),第一个参数为方法名,后面参数为方法的参数的类。

2、request和response

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。

当需要获取客户机端提交过来的数据时,找request对象;当需要向客户机输出数据,找response对象。

请求响应的具体现实流程:

  • 1.浏览器发送请求
  • 2.服务器接收请求,创建两个对象(request和response),将请求的信息封装request对象
  • 3.找到对应的servlet,将这两个对象传递给servlet
  • 4.Servlet收到请求,执行service方法,处理自己的业务逻辑,生成动态的内容,将内容返回给服务器
  • 5.服务器收到内容之后,进行拆分,生成响应信息,返回给浏览器

request简述

request获取参数值:request.getParameter(String s);

该参数有多个值时要用: request.getParameterValues(String s);

获取全部参数:request.getParameterMap()。

其余API:

  • getRequestURI() 获取请求的资源路径
  • getRequestURL() 获取请求的统一资源定位符(绝对路径)
  • getRemoteHost() 获取客户端的IP地址
  • getHeader() 请求头
  • getMethod() 请求的方式

 

request对象也是一个存储数据的区域对象,所以也具有如下方法:

  • setAttribute(String name, Object o)
  • getAttribute(String name)
  • removeAttribute(String name)

response简述

设置状态码
 setStatus(int sc)

  • 200 正确
  • 302 重定向
  • 304 查找本地缓存
  • 404 请求资源不存在
  • 500 服务器内部错误

设置响应头:setHeader(String name,String value)

setContentType 会同时设置服务器和客户端都使用UTF-8字符集,也设置了响头
该方法一定要在获取流对象之前调用才有效
response.setContentType("text/html;UTF-8");

 

响应流

响应流有以下两个
字符流
PrintWriter writer = response.getWriter();
writer.println("w分段函数覅u和ponse");
字节流
response.getOutputStream();

 

文件的上传与下载

上传UploadServlet

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //先判断上传的数据是否为多段数据(只有是多段的数据,才是文件上传的)
        if (ServletFileUpload.isMultipartContent(request)) {
            //创建FileItemFactory工厂实现类
            DiskFileItemFactory itemFactory = new DiskFileItemFactory();
            //创建用于解析上传数据的工具类ServletFileUpload类
            ServletFileUpload servletFileUpload = new ServletFileUpload(itemFactory);
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);
                //循环判断每一个表单项,是普通类型,还是上传的文件
                for (FileItem fileItem : list) {
                    if (fileItem.isFormField()) {
                        //普通表单项

                        System.out.println("表单项的name属性值:" + fileItem.getFieldName());
                        System.out.println("表单项的value属性值:" + fileItem.getString("UTF-8"));
                    } else {
                        //上传的文件
                        System.out.println("表单项的name属性值:" + fileItem.getFieldName());
                        System.out.println("上传的文件名:" + fileItem.getName());
//上传的文件下载到本地
                        fileItem.write(new File("e:\\" + fileItem.getName()));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

下载DownServlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取下载的文件名
        String downloadFileName = "2.jpg";

        //2、读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext = getServletContext();
        //获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        System.out.println("下载的文件类型:" + mimeType);
        //回传前,通过响应头告诉客户端返回的数据类型
        response.setContentType(mimeType);
        //告诉客户端收到的数据是用于下载使用(用响应头)
        //Content-Disposition响应头,表示收到的数据怎么处理
        //attachment表示附件,表示下载使用
        //filename= 表示指定下载的文件名,可以用别的名字 如"attachment;filename=22.jpg"
        //用中文文件名的话要对文件名重新编码URLEncoder.encode("照片.jpg","UTF-8")
        response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode("截图1.jpg","UTF-8"));

        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
        //获取响应的输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //3、把下载的文件回传给客户端
        //读取输入流中所有的数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);

    }

 

请求转发与请求重定向

请求转发:
request.getRequestDispatcher(URL地址).forward(request, response)

处理流程:

  1. 客户端发送请求,Servlet做出业务逻辑处理。
  2. Servlet调用forword()方法,服务器Servlet把目标资源返回给客户端浏览器。

请求重定向:
response.sendRedirect(URL地址)

处理流程:

  1. 客户端发送请求,Servlet做出业务逻辑处理。
  2. Servlet调用response.sendReadirect()方法,把要访问的目标资源作为response响应头信息发给客户端浏览器。
  3. 客户端浏览器重新访问服务器资源xxx.jsp,服务器再次对客户端浏览器做出响应。

 

 请求转发特点:
1、浏览器地址栏不会发生变化
2、只有一次请求
3、共享Request域中的数据
4、不可以访问工程外的资源

 重定向特点:
1、浏览器地址栏会发生变化
2、共有两次请求
3、不能共享Request中的数据
4、可以访问工程外的资源

  • request.getRequestDispatcher()是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;服务器内部转发,整个过程处于同一个请求当中。
  • response.sendRedirect()则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。不在同一个请求。重定向,实际上客户端会向服务器端发送两个请求。
  • 所以转发中数据的存取可以用request作用域:request.setAttribute(), request.getAttribute(),重定向是取不到request中的数据的。只能用session。
  • forward()更加高效,在可以满足需要时,尽量使用RequestDispatcher.forward()方法。(思考一下为什么?)
  • RequestDispatcher是通过调用HttpServletRequest对象的getRequestDispatcher()方法得到的,是属于请求对象的方法。
  • sendRedirect()是HttpServletResponse对象的方法,即响应对象的方法,既然调用了响应对象的方法,那就表明整个请求过程已经结束了,服务器开始向客户端返回执行的结果。
  • 重定向可以跨域访问,而转发是在web服务器内部进行的,不能跨域访问。

转发与重定向中路径的区别:

灵活获取工程地址:

String basepath = req.getScheme()   //协议 http
                + "://"
                + req.getServerName()   //localhost或127.0.0.1或者其他,根据访问地址灵活获取
                + ":"
                + req.getServerPort()   //8080
                + req.getContextPath()  // /ser1 工程名
                + "/";

 

四大作用域

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值