jetty请求form表单太大解决

文章介绍了使用Jetty进行图片上传时遇到的请求参数大小限制问题,默认限制为200000Byte。当文件大小超出限制时,会出现非法状态异常。文中提供了通过JVM参数或在jetty.xml中配置来解除此限制的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在用jetty做图片上传时发现jetty的request.getParameter方法对数据长度有限制,默认是200000Byte。

超过200000Byte就出现异常:

Java代码
java.lang.IllegalStateException: Form too large395336>200000
    at org.eclipse.jetty.server.Request.extractParameters(Request.java:249)
    at org.eclipse.jetty.server.Request.getParameter(Request.java:648)

 可以通过设置JVM参数来修改这个限制:

Jetty7:org.eclipse.jetty.server.Request.maxFormContentSize=-1

Jetty6:org.mortbay.jetty.Request.maxFormContentSize=-1

 

-1代表不限制。

 

也可以在jetty.xml中添加以下代码:

Jetty7:

Xml代码
<Call class="java.lang.System" name="setProperty">
  <Arg>org.eclipse.jetty.server.Request.maxFormContentSize</Arg>
  <Arg>-1</Arg>
</Call>


Jetty6:

Xml代码
   <Call class="java.lang.System" name="setProperty">  
     <Arg>org.mortbay.jetty.Request.maxFormContentSize</Arg>  
     <Arg>-1</Arg>  
   </Call>  



<think>我们正在讨论的是在JavaHTTP服务器端接收上传的文件流。通常,HTTP服务器接收文件上传是通过处理POST请求(通常是multipart/form-data格式)来实现的。但是,请注意,`FileInputStream`是用于读取本地文件的,而不是直接从网络流中读取的。在服务器端,我们接收的是来自客户端的网络输入流,然后我们需要从这个输入流中解析出文件内容,并写入到本地文件中。然而,用户的问题提到“使用fileinputstream接收http传输的文件流”,这可能需要澄清。在服务器端,我们不会直接使用FileInputStream来接收网络传输,而是使用ServletAPI或者类似机制获取InputStream(如`ServletInputStream`),然后将其写入文件,之后如果需要读取该文件,才使用FileInputStream。但如果我们自己实现一个简单的HTTP服务器,那么处理上传文件的步骤大致如下:1.在服务器端,我们监听某个端口,接收客户端的连接(Socket)。2.从Socket获得输入流(InputStream),读取客户端发送的HTTP请求。3.解析HTTP请求头部,特别是Content-Type和Content-Length(对于multipart/form-data,还需要解析boundary)。4.从输入流中读取文件数据(根据请求格式进行解析),并写入到本地的文件输出流(FileOutputStream)中。5.关闭相关资源。但是,请注意,直接使用Socket和手动解析HTTP请求是复杂的,通常我们会使用现成的库(如Servlet容器)来处理。如果用户指的是在Servlet中接收上传的文件,那么通常使用`Part`接口(Servlet3.0以后)或者使用ApacheCommonsFileUpload等库。鉴于用户要求使用`FileInputStream`来接收,这不太可能,因为`FileInputStream`是从文件读的,而我们需要将网络流写入文件。因此,我们可能会在写入文件后,使用`FileInputStream`读取该文件(例如,进行后续处理),但这已经是另一个步骤了。因此,本问题可能被理解为:如何在JavaHTTP服务器端接收上传的文件流(使用`FileInputStream`来读取已保存的文件)?或者如何将上传的文件流保存到本地文件?下面我将给出一个简单的示例,展示如何在一个简单的HTTP服务器(使用`ServerSocket`)中接收文件上传请求,并将请求体保存为文件(注意:这个示例仅适用于整个请求体就是一个文件内容的情况,例如客户端直接POST文件内容,而不使用multipart/form-data格式。对于multipart/form-data,需要复杂的解析)。如果用户想要的是Servlet环境下的做法,那么更常见的做法如下(使用Servlet3.0的Part):```java@WebServlet("/upload")@MultipartConfigpublicclassUploadServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{PartfilePart=request.getPart("file");//"file"是表单中文件字段的nameStringfileName=Paths.get(filePart.getSubmittedFileName()).getFileName().toString();//解决路径问题InputStreamfileContent=filePart.getInputStream();//然后使用这个输入流写入到文件Filefile=newFile(UPLOAD_PATH+File.separator+fileName);try(FileOutputStreamout=newFileOutputStream(file)){IOUtils.copy(fileContent,out);//使用ApacheCommonsIO简化}//之后,如果需要读取这个文件,可以使用FileInputStreamtry(FileInputStreamin=newFileInputStream(file)){//处理文件}}}```但是,用户可能没有使用Servlet环境,而是自己实现一个简单的服务器。因此,我们考虑自己实现一个简单的服务器来处理上传(注意:这个示例仅适用于单文件上传且请求体直接是文件内容,不含元数据的情况):步骤:1.创建ServerSocket监听端口。2.循环接受客户端连接。3.读取请求头,直到遇到空行(表示请求头结束)。4.读取请求体(剩余部分),并将其写入文件。但是,对于HTTP协议,我们需要读取Content-Length头,以知道请求体的长度。以下是一个简化的代码示例:```javaimportjava.io.*;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.StringTokenizer;publicclassSimpleHttpServer{publicstaticvoidmain(String[]args)throwsIOException{intport=8080;ServerSocketserverSocket=newServerSocket(port);System.out.println("服务器启动,监听端口:"+port);while(true){try(Socketsocket=serverSocket.accept();BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream()));OutputStreamout=socket.getOutputStream()){//读取请求头Stringline;intcontentLength=0;while((line=reader.readLine())!=null&&!line.isEmpty()){if(line.startsWith("Content-Length:")){contentLength=Integer.parseInt(line.substring("Content-Length:".length()).trim());}//可以添加其他头部解析}//如果请求中没有Content-Length,则不能继续if(contentLength<=0){sendError(out,"需要Content-Length头部");continue;}//保存文件(这里简单处理,固定文件名)StringfileName="uploaded_file.dat";try(InputStreaminput=socket.getInputStream();FileOutputStreamfileOut=newFileOutputStream(fileName)){//读取请求体(注意:reader已经读到请求头的末尾,但为了准确,使用原始流)//这里我们直接读取指定长度byte[]buffer=newbyte[4096];intremaining=contentLength;while(remaining>0){intbytesRead=input.read(buffer,0,Math.min(buffer.length,remaining));if(bytesRead<0){break;}fileOut.write(buffer,0,bytesRead);remaining-=bytesRead;}//发送响应Stringresponse="HTTP/1.1200OK\r\n\r\n文件上传成功";out.write(response.getBytes());}}catch(Exceptione){e.printStackTrace();}}}privatestaticvoidsendError(OutputStreamout,Stringmessage)throwsIOException{Stringresponse="HTTP/1.1400BadRequest\r\n\r\n"+message;out.write(response.getBytes());}}```注意:上述代码仅用于演示,没有处理并发,也没有处理完整的HTTP请求(比如只处理了Content-Length,没有处理分块传输编码等),也没有处理多部分上传(multipart)。实际应用中,强烈建议使用成熟的HTTP服务器库(如Netty,Jetty,Tomcat)或框架。回到问题:在服务器端,我们使用`FileOutputStream`将网络流写入文件,然后如果我们想要读取这个文件,就可以使用`FileInputStream`。所以,我们并不是用`FileInputStream`来接收HTTP传输的文件流,而是用它来读取已经保存到本地的文件。结论:-接收HTTP文件流通常是通过读取Socket的输入流(或ServletAPI的Part输入流)来实现的。-然后将这个输入流写入文件(使用FileOutputStream)。-如果后续需要读取该文件,则使用FileInputStream。因此,用户的问题可能将两个步骤混淆了:接收(保存)和读取。下面,我将根据上述理解给出一个结构化的答案。</think> ### Java HTTP 服务器使用 FileInputStream 接收文件流 在 Java HTTP 服务器中直接使用 `FileInputStream` 接收文件流是**不正确的实现方式**。`FileInputStream` 用于读取本地文件,而服务器接收 HTTP 文件流应采用网络流处理方式。以下是正确的实现步骤和代码示例: #### 核心实现流程 1. **监听客户端连接** ```java ServerSocket serverSocket = new ServerSocket(8080); // 监听8080端口 Socket clientSocket = serverSocket.accept(); // 接受客户端连接 ``` 2. **获取网络输入流** ```java InputStream inputStream = clientSocket.getInputStream(); // 获取HTTP数据流[^1] ``` 3. **解析 HTTP 请求头** ```java BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while (!(line = reader.readLine()).isEmpty()) { // 解析Content-Type和Content-Length等头部信息 if (line.startsWith("Content-Length:")) { contentLength = Integer.parseInt(line.substring(15).trim()); } } ``` 4. **保存文件流到本地** ```java try (FileOutputStream fos = new FileOutputStream("uploaded_file.dat")) { byte[] buffer = new byte[4096]; int bytesRead; while (contentLength > 0 && (bytesRead = inputStream.read(buffer, 0, Math.min(buffer.length, contentLength))) != -1) { fos.write(buffer, 0, bytesRead); contentLength -= bytesRead; } } ``` #### 完整示例代码 ```java import java.io.*; import java.net.*; public class SimpleHttpFileServer { public static void main(String[] args) throws IOException { try (ServerSocket serverSocket = new ServerSocket(8080)) { System.out.println("服务器已启动,监听端口: 8080"); while (true) { try (Socket client = serverSocket.accept(); InputStream in = client.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { // 解析请求头 int contentLength = -1; String line; while (!(line = reader.readLine()).isEmpty()) { if (line.startsWith("Content-Length:")) { contentLength = Integer.parseInt(line.substring(15).trim()); } } // 保存文件 if (contentLength > 0) { try (FileOutputStream fos = new FileOutputStream("uploaded_file.dat")) { byte[] buffer = new byte[4096]; int bytesRead; while (contentLength > 0 && (bytesRead = in.read(buffer, 0, Math.min(buffer.length, contentLength))) != -1) { fos.write(buffer, 0, bytesRead); contentLength -= bytesRead; } System.out.println("文件保存成功"); } } // 返回响应 OutputStream out = client.getOutputStream(); out.write("HTTP/1.1 200 OK\r\n\r\n".getBytes()); } } } } } ``` #### 关键注意事项 1. **流处理顺序** - 必须先解析 HTTP 头部再读取请求- 使用 `BufferedReader` 读头部直到空行,然后用二进制流读文件体 2. **大文件处理** ```java // 使用缓冲提高性能 BufferedInputStream bis = new BufferedInputStream(in); BufferedOutputStream bos = new BufferedOutputStream(fos); ``` 3. **错误处理** ```java try { // 文件传输代码 } catch (IOException ex) { OutputStream out = client.getOutputStream(); out.write("HTTP/1.1 500 Server Error\r\n\r\n".getBytes()); } finally { // 关闭所有流 } ``` #### 何时使用 FileInputStream? `FileInputStream` 应仅在**文件已完整保存到磁盘后**使用: ```java // 在接收完成后读取文件 try (FileInputStream fis = new FileInputStream("uploaded_file.dat")) { byte[] fileData = fis.readAllBytes(); // 处理文件内容... } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值