当前位置: 首页 > 知识库问答 >
问题:

输入流到servletInputStream

蒋飞捷
2023-03-14

我有这个输入流:

InputStream inputStream = new ByteArrayInputStream(myString.getBytes(StandardCharsets.UTF_8));

如何将其转换为ServletInputStream?

我试过:

ServletInputStream  servletInputStream = (ServletInputStream) inputStream;

但不工作。

编辑:

我的方法是这样的:

private static class LowerCaseRequest extends HttpServletRequestWrapper {

        public LowerCaseRequest(final HttpServletRequest request) throws IOException, ServletException {
            super(request);
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {

            ServletInputStream servletInputStream;

            StringBuilder jb = new StringBuilder();
            String line;
            String toLowerCase = "";

            BufferedReader reader = new BufferedReader(new InputStreamReader(super.getInputStream()));
            while ((line = reader.readLine()) != null) {
                toLowerCase = jb.append(line).toString().toLowerCase();
            }

            InputStream inputStream = new ByteArrayInputStream(toLowerCase.getBytes(StandardCharsets.UTF_8));

            servletInputStream = (ServletInputStream) inputStream;

            return servletInputStream;

        }
 }

我正在尝试将我的所有请求转换为小写。

共有3个答案

范俊逸
2023-03-14

你只能施放这样的东西:

ServletInputStream  servletInputStream = (ServletInputStream) inputStream;

如果您尝试转换的输入流实际上已经是ServletInputStream。如果它是InputStream的其他实现,它会抱怨。你不能将一个对象投射到它不是的东西上。

在 Servlet 容器中,您可以从 Servlet 请求中获取一个 Servlet 输入流:

ServletInputStream  servletInputStream = request.getInputStream();

那么,你到底想做什么?

编辑

我很好奇为什么要将请求转换为小写-为什么不只是让您的servlet不区分大小写?换句话说,您的小写请求数据的代码可以复制到您的servlet中,然后它可以在那里处理它…总是寻找最简单的解决方案!

李谦
2023-03-14

请尝试此代码。

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(myString.getBytes(StandardCharsets.UTF_8));
    ServletInputStream servletInputStream=new ServletInputStream(){
        public int read() throws IOException {
          return byteArrayInputStream.read();
        }
      }
瞿博学
2023-03-14

我的建议是:不要创建< code > bytearrayiputstream ,只使用已经从< code>getBytes方法中获得的字节数组。这应该足以创建一个< code>ServletInputStream。

不幸的是,aksappy的答案只覆盖了读取方法。虽然这在 Servlet API 3.0 及更低版本中可能已经足够了,但在更高版本的 Servlet API 中,您还需要实现另外三种方法。

这是我对这个类的实现,尽管随着它变得相当长(由于ServletAPI 3.1中引入的新方法),您可能会考虑将它分解为嵌套类甚至顶级类。

    final byte[] myBytes = myString.getBytes("UTF-8");
    ServletInputStream servletInputStream = new ServletInputStream() {
        private int lastIndexRetrieved = -1;
        private ReadListener readListener = null;

        @Override
        public boolean isFinished() {
            return (lastIndexRetrieved == myBytes.length-1);
        }

        @Override
        public boolean isReady() {
            // This implementation will never block
            // We also never need to call the readListener from this method, as this method will never return false
            return isFinished();
        }

        @Override
        public void setReadListener(ReadListener readListener) {
            this.readListener = readListener;
            if (!isFinished()) {
                try {
                    readListener.onDataAvailable();
                } catch (IOException e) {
                    readListener.onError(e);
                }
            } else {
                try {
                    readListener.onAllDataRead();
                } catch (IOException e) {
                    readListener.onError(e);
                }
            }
        }

        @Override
        public int read() throws IOException {
            int i;
            if (!isFinished()) {
                i = myBytes[lastIndexRetrieved+1];
                lastIndexRetrieved++;
                if (isFinished() && (readListener != null)) {
                    try {
                        readListener.onAllDataRead();
                    } catch (IOException ex) {
                        readListener.onError(ex);
                        throw ex;
                    }
                }
                return i;
            } else {
                return -1;
            }
        }
    };

根据您的要求,您可能还想覆盖其他方法。正如romfret指出的,建议覆盖一些方法,例如关闭可用。如果您不实现它们,流将始终报告有0个字节可供读取,并且关闭方法不会影响流的状态。您可能可以在不覆盖skip的情况下逃脱,因为默认实现将多次调用read

    @Override
    public int available() throws IOException {
        return (myBytes.length-lastIndexRetrieved-1);
    }

    @Override
    public void close() throws IOException {
        lastIndexRetrieved = myBytes.length-1;
    }

不幸的是,由于匿名类的性质,您很难编写有效的<code>close

但是,如果您将类分解为嵌套或顶级类(甚至是具有构造函数的匿名类,您可以从定义它的行调用它),myBytes可以是非最终字段而不是最终局部变量,您可以添加这样的行:

myBytes = null;

关闭方法,这将允许Java释放字节数组占用的内存。

当然,这需要你写一个构造函数,比如:

    private byte[] myBytes;

    public StringServletInputStream(String str) {
        try {
            myBytes = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("JVM did not support UTF-8", e);
        }
    }

如果您想支持标记/重置,您可能还想覆盖< code >标记 、< code >标记支持和< code >重置。我不确定它们是否真的被你的容器调用过。

    private int readLimit = -1;
    private int markedPosition = -1;

    @Override
    public boolean markSupported() {
        return true;
    }

    @Override
    public synchronized void mark(int readLimit) {
        this.readLimit = readLimit;
        this.markedPosition = lastIndexRetrieved;
    }

    @Override
    public synchronized void reset() throws IOException {
        if (markedPosition == -1) {
            throw new IOException("No mark found");
        } else {
            lastIndexRetrieved = markedPosition;
            readLimit = -1;
        }
    }

    // Replacement of earlier read method to cope with readLimit
    @Override
    public int read() throws IOException {
        int i;
        if (!isFinished()) {
            i = myBytes[lastIndexRetrieved+1];
            lastIndexRetrieved++;
            if (isFinished() && (readListener != null)) {
                try {
                    readListener.onAllDataRead();
                } catch (IOException ex) {
                    readListener.onError(ex);
                    throw ex;
                }
                readLimit = -1;
            }
            if (readLimit != -1) {
                if ((lastIndexRetrieved - markedPosition) > readLimit) {
                    // This part is actually not necessary in our implementation
                    // as we are not storing any data. However we need to respect
                    // the contract.
                    markedPosition = -1;
                    readLimit = -1;
                }
            }
            return i;
        } else {
            return -1;
        }
    }
 类似资料:
  • 交互式应用程序通常要分别用类 istream 和 ostream 输入和输出数据。当提示信息出现在屏幕上时,用户输入一个数据来响应。显然,提示信息必须在执行输入操作前出现。在有输出缓冲区的情况下,只有在缓冲区已满时、在程序中明确地刷新输出缓冲区时或因程序结束而自动刷新输出缓冲区时,输出信息才会显示到屏幕上。为保证输出要在下一个输入前显示,C++ 提供了成员函数tie,该函数可以实现输入/输出操作的

  • 原因:java.lang.IllegalArgumentException:无法检索类路径资源[BZH91AY&SY 90 WT A%l!!9 d N$L]的InputStream: 在org.springframework.beans.propertyeditors.inputstreameditor.setastext(inputstreameditor.java:77)在org.spring

  • 下面我们要讨论流的输入,这是用流读取运算符(即重载的运算符>>)实现的。流读取运算符通常会跳过输人流中的空格、tab键、换行符等等的空白字符,稍后将介绍如何改变这种行为。 当遇到输入流中的文件结束符时,流读取运算符返回0(false);否则,流读取运算符返回对调用该运算符的对象的引用。每个输入流都包含一组用于控制流状态(即格式化、出错状态设置等)的状态位。当输入类型有错时,流读取运算符就会设置输人

  • 本小节将会介绍基本输入输出的 Java 标准类,通过本小节的学习,你将了解到什么是输入和输入,什么是流;输入输出流的应用场景,File类的使用,什么是文件,Java 提供的输入输出流相关 API 等内容。 1. 什么是输入和输出(I / O) 1.1 基本概念 输入/输出这个概念,对于计算机相关专业的同学并不陌生,在计算中,输入/输出(Input / Output,缩写为 I / O)是信息处理系

  • 问题内容: 我有罐子或战争。 我正在以编程方式读取此jar,当我在此jar中找到该jar时,我想再次以编程方式阅读它。 但是JarFile仅提供getInputStream,我无法将其传递给JarFile(File file)构造函数。 如何从罐子中读取罐子? 编辑:我正在考虑以某种方式从类加载器中获取文件。 问题答案: 您可以在文件系统中创建jar文件,例如 并将Stream写入其中。之后,您可

  • 主要内容:C++输入流和输出流本教程一开始就提到,C++ 又可以称为“带类的 C”,即可以理解为 C++ 是 C 语言的基础上增加了面向对象(类和对象)。在此基础上,学过 C 语言的读者应该知道,它有一整套完成数据读写(I/O)的解决方案: 使用 scanf()、gets() 等函数从键盘读取数据,使用 printf()、puts() 等函数向屏幕上输出数据; 使用 fscanf()、fgets() 等函数读取文件中的数据,使