在播放/scala中将数据作为多格式数据发送时出错 [英] Error in sending data as multi form data in play /scala

查看:85
本文介绍了在播放/scala中将数据作为多格式数据发送时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码,相同的代码在播放2.1.5中工作,但是我无法在播放2.1.5中创建战争文件,所以我切换到播放2.4.3,现在作为响应,即将出现400 bad request client从句法上发送错误,甚至post rest api都没有成功.有人可以告诉我我在想什么吗?

This is my code the same code is working in play 2.1.5 but I am unable to create war file in play 2.1.5 so I switched to play 2.4.3 and now in response it is coming that 400 bad request client is sending wrong syntactically even post rest api is not hitting. Can some tell me what I am missing?

import play.api._
import play.api.libs.ws._
import play.api.mvc._
//import javax.inject.Inject
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.libs.ws.WSAuthScheme
import com.ning.http.client.AsyncHttpClient
import com.ning.http.client.multipart.FilePart
import com.ning.http.client.multipart.StringPart
import java.io.File
import org.apache.commons.codec.binary.Base64.encodeBase64

class Application extends Controller {

  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }



def postUpload=Action(parse.multipartFormData){request=>

   val groupingType= request.body.dataParts("Grouping type").mkString
    val email=request.body.dataParts("NotificationRecepients").mkString
    val custId=request.body.dataParts("CustomerId").mkString
    val custIdFinal:Int=custId.toInt


   request.body.file("file").map { file =>

  val file1=file.ref.file.getAbsolutePath;


  val fileName = file.filename 
    val contentType = file.contentType

  //file.ref.moveTo(new File("/home/kanchan/Desktop/"+fileName),true)


     val user = "myUser";
      val password = "myPassword";

 val encodedCredentials =
      new String(encodeBase64("%s:%s".format(user, password).getBytes))

    val asyncHttpClient:AsyncHttpClient =WS.client.underlying
    val postBuilder = asyncHttpClient.preparePost(url)
    val builder = postBuilder
      .addHeader("Authorization", "Basic " + encodedCredentials)
      .addBodyPart(new StringPart("selectedGroupType", "Functional Grouping", "UTF-8"))
      .addBodyPart(new StringPart("mailRecipients", "kancgupt@cisco.com", "UTF-8"))
      .addBodyPart(new StringPart("selectedFile", "Sample_group_upload_file.xlsx", "UTF-8"))
      .addBodyPart(new FilePart("file",new File("/home/kanchan/Downloads/Sample_group_upload_file.xlsx")))

    val response = asyncHttpClient.executeRequest(builder.build()).get();
   Ok(response.getResponseBody)


  }.getOrElse {

     Ok( "Missing file")

  }
}
}

播放版本2.4.3 sbt:0.13.8

Play version 2.4.3 sbt:0.13.8

出现以下错误: Apache Tomcat/6.0.39-错误报告

HTTP状态400-错误请求

类型状态报告

getting following error: Apache Tomcat/6.0.39 - Error report

HTTP Status 400 - Bad Request

type Status report

消息错误的请求

描述客户端发送的请求在语法上不正确.

description The request sent by the client was syntactically incorrect.

推荐答案

您描述的东西确实很奇怪.我将您的代码,curl,REST服务器回显( http://httpbin.org ,确切地称为

You describing something really strange. I took your code, curl, REST server echo (http://httpbin.org, exactly http://httpbin.org/post url), create new play-scala application with the 2.4.3 play. It works like a charm.

代码:

package controllers

import play.api._
import play.api.libs.ws._
import play.api.mvc._
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.libs.ws.WSAuthScheme
import com.ning.http.client.AsyncHttpClient
import com.ning.http.client.multipart.FilePart
import com.ning.http.client.multipart.StringPart
import java.io.File
import org.apache.commons.codec.binary.Base64.encodeBase64

class Original extends Controller {

  def postUpload = Action(parse.multipartFormData) { request =>

    val groupingType = request.body.dataParts("Groupingtype").mkString
    val email = request.body.dataParts("NotificationRecepients").mkString
    val custId = request.body.dataParts("CustomerId").mkString
    val custIdFinal: Int = custId.toInt

    request.body.file("file").map { file =>

      val file1 = file.ref.file.getAbsolutePath;

      val fileName = file.filename
      val contentType = file.contentType

      val url = "http://httpbin.org/post"

      val user = "myUser";
      val password = "myPassword";

      val encodedCredentials =
        new String(encodeBase64("%s:%s".format(user, password).getBytes))

      val asyncHttpClient: AsyncHttpClient = WS.client.underlying
      val postBuilder = asyncHttpClient.preparePost(url)
      val builder = postBuilder
        .addHeader("Authorization", "Basic " + encodedCredentials)
        .addBodyPart(new StringPart("selectedGroupType", groupingType, "UTF-8"))
        .addBodyPart(new StringPart("mailRecipients", email, "UTF-8"))
        .addBodyPart(new StringPart("selectedFile", fileName, "UTF-8"))
        .addBodyPart(new FilePart("file", new File(file1)))

      val response = asyncHttpClient.executeRequest(builder.build()).get();
      Ok(response.getResponseBody)

    }.getOrElse {

      Ok("Missing file")

    }
  }
}

curl命令(从项目根文件夹):

curl command (from the project root folder):

curl -i -X POST \
   -H "Content-Type:multipart/form-data" \
   -F "Groupingtype=Groupingtype" \
   -F "NotificationRecepients=NotificationRecepients" \
   -F "CustomerId=123" \
   -F "file=@app/controllers/Application.scala" \
 'http://localhost:9000/post'

卷曲响应:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 06 Oct 2015 18:38:11 GMT
Content-Length: 3122

{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "package controllers..."
  }, 
  "form": {
    "mailRecipients": "NotificationRecepients", 
    "selectedFile": "Application.scala", 
    "selectedGroupType": "Groupingtype"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Authorization": "Basic bXlVc2VyOm15UGFzc3dvcmQ=", 
    "Content-Length": "3215", 
    "Content-Type": "multipart/form-data; boundary=2EmAF3UE9xSuA6KQpUS3q-Ohzkp0f_7-8", 
    "Host": "httpbin.org", 
    "User-Agent": "AHC/1.0"
  }, 
  "json": null, 
  "origin": "111.111.111.111", 
  "url": "http://httpbin.org/post"
}

尝试创建一个新的简单项目并使用我的代码-然后将您的代码迁移到这个新项目中-也许您会发现一些东西.从2.1.5左右开始,可能是一些错误的迁移步骤.

Try to create new simple project and use my code - then migrate yours in to this new project - maybe you will find something. It could be some wrong migration steps from 2.1.5 or so.

我的 build.sbt

name := """scala-send-multipart-clean"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

我的 project/plugins.sbt

// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.3")

// web plugins

addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.0.6")

addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.3")

addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.7")

addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0")

我的 project/build.properties

#Activator-generated Properties
#Wed Oct 07 00:44:35 EEST 2015
template.uuid=7da33b5a-3aef-4d2e-b318-dae93632b999
sbt.version=0.13.8

java版本"1.8.0_40" ,已更新为内部版本1.8.0_60-b27" -没什么区别.

java version "1.8.0_40", updated to the "build 1.8.0_60-b27" - no difference.

我正在获取此[StringPart name = selectedGroupType contentType = UTF-8 charset = US-ASCII tranferEncoding = 8bit contentId = null dispositionType = null,StringPart名称= mail收件人contentType = UTF-8 charset = US-ASCII tranferEncoding = 8bit contentId = null dispositionType = null,StringPart名称= selectedFile contentType = UTF-8 charset = US-ASCII tranferEncoding = 8bit contentId = null dispositionType = null,FilePart名称= file contentType =应用程序/八位字节流charset = null tranferEncoding =二进制contentId = null dispositionType = null filename = Sample_group_upload_file.xlsx]

I am getting this [StringPart name=selectedGroupType contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, StringPart name=mailRecipients contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, StringPart name=selectedFile contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, FilePart name=file contentType=application/octet-stream charset=null tranferEncoding=binary contentId=null dispositionType=null filename=Sample_group_upload_file.xlsx]

这是在 Parts 中实现toString的方式.就是这样,它并不能说明正确"或不正确".

It is the way toString is realised in the Parts. That's all, it does not tell something about "correct" or "not correct".

我的搜索结果

println(builder.build().getParts())

[StringPart name=selectedGroupType contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, StringPart name=mailRecipients contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, StringPart name=selectedFile contentType=UTF-8 charset=US-ASCII tranferEncoding=8bit contentId=null dispositionType=null, FilePart name=file contentType=application/octet-stream charset=null tranferEncoding=binary contentId=null dispositionType=null filename=multipartBody1697314279257602964asTemporaryFile]

您看到的与您的非常相似,但是如果您要输出字符串部分的名称和值,我很确定您会同时收到这两个信息:

As you see it very similar to yours, but if you will output names and values for the string part, I am pretty sure you will receive both:

import scala.collection.JavaConversions._

... 

builder.build().getParts().map{ part =>
    if(part.isInstanceOf[StringPart]){
      val stringPart: StringPart = part.asInstanceOf[StringPart]
      println(stringPart.getName() + ":" + stringPart.getValue())
    }
}

结果:

selectedGroupType:Groupingtype
mailRecipients:NotificationRecepients
selectedFile:Application.scala

这篇关于在播放/scala中将数据作为多格式数据发送时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆