rest-assured icon indicating copy to clipboard operation
rest-assured copied to clipboard

Rest Assured doesn't support web form posting "application/x-www-form-urlencoded"

Open quangtringuyen opened this issue 8 years ago • 11 comments
trafficstars

WHEN I post a request for authentication, the error occurs to say that:

"java.lang.IllegalArgumentException: Cannot serialize because cannot determine how to serialize content-type application/x-www-form-urlencoded;charset=UTF-8"

Here is my test method

@Test
public void authenticate()
{
    AuthenDto authenDto = new AuthenDto("username","password","false","Login");
    given()
            .contentType("application/x-www-form-urlencoded;charset=UTF-8")
            .accept("application/json, text/plain, */*")
            .body(authenDto)
    .when()
            .post("ENDPOINT")
    .then()
            .statusCode(200);
}

quangtringuyen avatar Apr 01 '17 15:04 quangtringuyen

Hi!

Firstly, have you tried to use the enum member ContentType.URLENC as .contentType(..) value?

As for described issue, RA appends the default charset to Content-Type header if you don't specify one. So, your actual header looks like "application/x-www-form-urlencoded;charset=UTF-8; charset=UTF-8;", and hence can't be parsed.

You can disable this with the following config RestAssured.config().encoderConfig(EncoderConfig.encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false));. However, it is better if you configure request encoding by using defaultContentCharset(...) for your encoderConfig() and keep the setting above to always send the charset.

gladnik avatar Apr 03 '17 17:04 gladnik

Same problem over here:

java.lang.IllegalArgumentException: Cannot serialize because cannot determine how to serialize content-type application/x-www-form-urlencoded

with

RestAssured.config = RestAssured.config()
  .encoderConfig(encoderConfig()
    .defaultContentCharset("UTF-8")
    .appendDefaultContentCharsetToContentTypeIfUndefined(false));
given()
  .contentType(ContentType.URLENC)
  .formParam("action", "deleteAllMetaDataForRefId")
  .formParam("refID", refId)
  .post()
  .....

michelkaeser avatar Jul 19 '17 12:07 michelkaeser

This looks like a bug indeed. Need to investigate it.

johanhaleby avatar Jul 21 '17 08:07 johanhaleby

same here:

config = RestAssuredConfig.config()
                .objectMapperConfig(objectMapperConfig()
                        .jackson2ObjectMapperFactory((aClass, s) -> objectMapper)).encoderConfig(EncoderConfig.encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false));

and test:

given()
                .contentType(ContentType.URLENC)
                .cookies(cookies.getCookies())
                .pathParam("storeId", registeredStore.getId())
                .formParam("departments", allDepartments)
                .log().all().when().post(ApiEndpoints.postNewDepartments.getCall())
                .then().log().all().and().assertThat().statusCode(201);

Demitsuru avatar Aug 02 '17 16:08 Demitsuru

is there any workaround to post a x-www-form-urlencoded body with Rest-Assured?

RJ05 avatar Oct 09 '17 05:10 RJ05

Since the content-type is "x-www-form-urlencoded", Instead of using 'body' tag, use the 'formparam' tag in the request.

Ex: Replace body("Example","ExValue") with formParam("formParamName", "value1").

Let to know whether if it works.

medineshkumar avatar Nov 30 '17 06:11 medineshkumar

@medineshkumar it works with formParam

aleboulanger avatar Jan 22 '18 13:01 aleboulanger

What if I want to use a POJO class with gson serialization as request body? In such case I will have to pass it as "body" and it gives the same above error. Any solution for such case?

nishant-shah-social avatar Jun 09 '21 18:06 nishant-shah-social

I tried with the formParam and still getting the below error any ideas.

import static io.restassured.RestAssured.*; import java.util.HashMap; import java.util.Map; import org.json.simple.JSONObject; import io.restassured.RestAssured; import io.restassured.config.EncoderConfig; import static io.restassured.config.EncoderConfig.encoderConfig; import io.restassured.http.ContentType; import io.restassured.response.Response; import io.restassured.response.ValidatableResponse; import io.restassured.specification.RequestSpecification; public class Trial {

public static void main(String[] args) {
	String baseURI="https://api.TEST.com/";
	RequestSpecification _REQ_SPEC=given()
			.config(RestAssured.config() .encoderConfig(EncoderConfig.encoderConfig()
					.encodeContentTypeAs("x-www-form-urlencoded", ContentType.URLENC)))
					.contentType(ContentType.URLENC.withCharset("UTF-8")) 
			.with()
			.baseUri(baseURI) 
			.header("Host", "api.test.com")
			.header("Accept", "application/json")
			.formParam("organization", "val1") 
			.formParam("login", "val2")
			.formParam("password", "val3");
	Response _RESP=_REQ_SPEC.when().post("/P1/prompt");
	ValidatableResponse _VALIDATABLE_RESP=_RESP.then();
						_VALIDATABLE_RESP.assertThat().statusCode(200);
}

}

Getting below Error: WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v9.Java9 (file:/C:/Users/errah/.m2/repository/org/codehaus/groovy/groovy/3.0.8/groovy-3.0.8.jar) to constructor java.lang.AssertionError(java.lang.String) WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v9.Java9 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release Exception in thread "main" java.lang.AssertionError: 1 expectation failed. Expected status code <200> but was <400>.

at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:59)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:493)
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure$validate$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
at io.restassured.internal.ResponseSpecificationImpl.validateResponseIfRequired(ResponseSpecificationImpl.groovy:674)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:193)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:61)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
at io.restassured.internal.ResponseSpecificationImpl.statusCode(ResponseSpecificationImpl.groovy:126)
at io.restassured.specification.ResponseSpecification$statusCode$0.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
at io.restassured.internal.ResponseSpecificationImpl.statusCode(ResponseSpecificationImpl.groovy:134)
at io.restassured.internal.ValidatableResponseOptionsImpl.statusCode(ValidatableResponseOptionsImpl.java:89)
at io.restassured.internal.ValidatableResponseImpl.super$2$statusCode(ValidatableResponseImpl.groovy)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1268)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:144)
at io.restassured.internal.ValidatableResponseImpl.statusCode(ValidatableResponseImpl.groovy:142)
at io.restassured.internal.ValidatableResponseImpl.statusCode(ValidatableResponseImpl.groovy)
at Trial.main(Trial.java:70)

rahulprinjay avatar Aug 20 '21 05:08 rahulprinjay

Getting same

request = given() .headers(headers) .headers("X-Api-Client", "NFAqxq7d7") .headers("x-service-id", "cacq_collective_appctx") .headers("Content-type",MULTIPART_FORM_DATA_VALUE) .multiPart("files", new File("resources/properties/test.txt")) .multiPart("fileMetaData", metaData);

Error - Cannot serialize because cannot determine how to serialize content-type multipart/form-data

ngbyname avatar Nov 17 '22 10:11 ngbyname

Getting same

request = given() .headers(headers) .headers("X-Api-Client", "NFAqxq7d7") .headers("x-service-id", "cacq_collective_appctx") .headers("Content-type",MULTIPART_FORM_DATA_VALUE) .multiPart("files", new File("resources/properties/test.txt")) .multiPart("fileMetaData", metaData);

Error - Cannot serialize because cannot determine how to serialize content-type multipart/form-data

I ran into the same issue. Funny enough, it works when I remove the content-type header. So something like this:

request = given()
    .headers(headers)
    .headers("X-Api-Client", "NFAqxq7d7")
    .headers("x-service-id", "cacq_collective_appctx")
    .multiPart("files", new File("resources/properties/test.txt"))
    .multiPart("fileMetaData", metaData);

fire2 avatar Dec 18 '23 14:12 fire2