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")
}
}
}
Play version 2.4.3 sbt:0.13.8
getting following error: Apache Tomcat/6.0.39 - Error report
type Status report
message Bad Request
description The request sent by the client was syntactically incorrect.
答案 0 :(得分:0)
你描述的东西真的很奇怪。我接受了你的代码,curl,REST服务器echo(http://httpbin.org,正好http://httpbin.org/post url),用2.4.3 play创建了一个新的play-scala应用程序。它就像一个魅力。
代码:
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 -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左右的一些错误的迁移步骤。
我的 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”,更新为“build 1.8.0_60-b27” - 没有区别。
我收到了这个[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 文件名= Sample_group_upload_file.xlsx]
这是部分中实现toString
的方式。这就是全部,它没有说出“正确”或“不正确”的内容。
我的结果
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]
如您所见,它与您的非常相似,但如果您输出字符串部分的名称和值,我很确定您会收到两者:
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