当使用 okhttp 发送 post 请求时,服务器接收到的请求正文为空。可能是啥问题?

Posted

技术标签:

【中文标题】当使用 okhttp 发送 post 请求时,服务器接收到的请求正文为空。可能是啥问题?【英文标题】:Server receives the request body as null, when sending post request using okhttp. what could be the issue?当使用 okhttp 发送 post 请求时,服务器接收到的请求正文为空。可能是什么问题? 【发布时间】:2020-07-26 09:04:47 【问题描述】:

这是将参数fnameselectedFile(byteArray)作为post请求正文的一部分从android发送到tomcat服务器的代码。

    public void uploadFile()
        EditText filename=findViewById(R.id.fileName);
        //content://
        try 
            InputStream inputStream=getContentResolver().openInputStream(filePath);
            selectedFile= IOUtils.toByteArray(inputStream);
         catch (FileNotFoundException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        

        String purl="http://192.168.1.11:8080/placement/V2TryUploadFile";

        RequestBody requestBody=new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("fname",filename.getText().toString())
                .addFormDataPart("selectedFile",filename.getText().toString(),RequestBody.create(MediaType.parse("application/pdf"),selectedFile))
                .build();
        Request request=new Request.Builder()
                .url(purl)
                .post(requestBody)
                .build();

        Toast.makeText(MainActivity.this,filename.getText().toString(),Toast.LENGTH_SHORT).show();
        Toast.makeText(MainActivity.this,selectedFile.length+":",Toast.LENGTH_SHORT).show();
        OkHttpClient okHttpClient=new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(Call call, IOException e) 
                call.cancel();
                runOnUiThread(new Runnable() 
                    @Override
                    public void run() 
                        Toast.makeText(MainActivity.this,"Failed to Upload",Toast.LENGTH_SHORT).show();
                    
                );
            

            @Override
            public void onResponse(Call call, Response response) throws IOException 
                final String responseString=response.body().string();
                runOnUiThread(new Runnable() 
                    @Override
                    public void run() 
                        Toast.makeText(MainActivity.this,responseString,Toast.LENGTH_SHORT).show();
                    
                );
            
        );

Servlet 代码(在 tomcat 服务器上运行)处理从 android add 发送的 post 请求

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
        // TODO Auto-generated method stub
        String fname=request.getParameter("fname")+".pdf";
        Part selectedFile=request.getPart("selectedFile");
        System.out.println(fname);
        System.out.println(selectedFile+"");
        InputStream filecontent = selectedFile.getInputStream();

        byte[] fileAsByteArray = IOUtils.toByteArray(filecontent);

        FileOutputStream imageOutFile = new FileOutputStream("C:\\Users\\VAISHAK`\\placeWorkSpace\\placement\\ResumeUploads\\" + fname);
        imageOutFile.write(fileAsByteArray);
        imageOutFile.close();
        doGet(request, response);
    

问题是 fname 和 selectedFile 在 android app 中未显示为 null,但在 tomcat 服务器控制台中均显示为 null。

还有下面是eclipse中的tomcat服务器日志

null.pdf
null
Apr 13, 2020 11:56:20 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [trial.V2TryUploadFile] in context with path [/placement] threw exception
java.lang.NullPointerException
    at trial.V2TryUploadFile.doPost(V2TryUploadFile.java:49)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

【问题讨论】:

你有一个NullPointerException。所以告诉我们什么是null。以及在哪个声明中。 不要使用空指针。使用前检查是否为空。 @blackapps 问题是。为什么 servlet 中的 post 请求参数为空。但是当我在 okhttp 请求中从 android 应用程序发送时它们不为空 @blackapps ``` String fname=request.getParameter("fname")+".pdf";部分 selectedFile=request.getPart("selectedFile"); ```上面两个变量都是null,导致后面的代码抛出空指针异常 字符串 fname=request.getParameter("fname")+".pdf";部分 selectedFile=request.getPart("selectedFile"); .由于这些语句在 servlet 中为空,因此后续语句正在抛出空指针异常 @blackapps .. 抱歉现在清楚了 【参考方案1】:

我终于找到了解决办法

servlet默认不处理

MutipartBody FORM

所以为了支持它,我们需要在 servlet 中添加以下注释

@MultipartConfig

【讨论】:

以上是关于当使用 okhttp 发送 post 请求时,服务器接收到的请求正文为空。可能是啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 的 OKhttp 中通过 POST 请求发送 JSON 正文

Okhttp3、http2多路复用POST请求高峰负载时响应时间长

OkHTTP、Retrofit 中文乱码解决方法

基于OkHttp3 加入HttpDns功能

Android进阶:5发送post请求json数据格式以及okhttp框架的使用

向服务器发送多个请求时,Okhttp 刷新过期令牌