Post : json으로 데이터 보내기

도메인 오브젝트 만들어서 jackson으로 json데이터로 보내는데 json데이터까지는 문제 없이 만들어지는데 "cid can’t be null"이라는 오류 메세지가 옵니다. body에 제대로 값이 안들어가서 그런 것 같은데 httpEntity에 json데이터 넣고 httpPost객체에 setEntity 해서 보냈는데 이런 식으로 하면 안되는건가요?
Rest 서버라고 해서 위와같이 해 보았는데 다른 방법이나 해결책 있으시면 알려주시면 감사하겠습니다.

1개의 좋아요

@koko1321591

작성하신 코드와 로그를 공유해주실 수 있으실까요?

public static void readyPay() throws Exception {
HttpClient httpClient = new DefaultHttpClient();

	String url = "https://kapi.kakao.com/v1/payment/ready";
	HttpPost httpPost = new HttpPost(url);
	httpPost.setHeader("Accept", "application/json");
	httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
	httpPost.setHeader("Authorization", "KakaoAK {api Key}");
	
	KakaoPayRequest sendObject = new KakaoPayRequest();
	sendObject.setCid("TC0ONETIME");
	sendObject.setPartnerOrderId("user01");
	sendObject.setPartnerUserId("user01");
	sendObject.setItemName("컴퓨터");
	sendObject.setQuantity(1);
	sendObject.setTotalAmount(2200);
	sendObject.setVatAmount(200);
	sendObject.setTaxFreeAmount(0);
	sendObject.setApprovalURL("http://127.0.0.1:8080");
	sendObject.setFailURL("http://127.0.0.1:8080");
	sendObject.setCancelURL("http://127.0.0.1:8080");
	
	ObjectMapper objectMapper = new ObjectMapper();
	String jsonValue = objectMapper.writeValueAsString(sendObject);
	HttpEntity httpEntity = new StringEntity(jsonValue, "utf-8");
	
	httpPost.setEntity(httpEntity);
	HttpResponse httpResponse = httpClient.execute(httpPost);
	
	System.out.println(httpResponse);
	System.out.println();
	
	HttpEntity httpEntity01 = httpResponse.getEntity();
	
	InputStream is = httpEntity01.getContent();
	BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
	
	JSONObject resObject = (JSONObject)JSONValue.parse(br);
	System.out.println(resObject);
	ObjectMapper objectMapper01 = new ObjectMapper();
	KakaoPayResponse responseDomain = objectMapper01.readValue(resObject.toString(), KakaoPayResponse.class);
	System.out.println(responseDomain);
	
}

소스는 다음과 같이 작성하였습니다. ready를 위한 메소드 식으로 작성하였습니다.

다음은 log4j로 디버깅 모드를 실행한 결과입니다

POST https://kapi.kakao.com/v1/payment/ready HTTP/1.1
####{“cid”:“TC0ONETIME”,“tid”:null,“pgToken”:null,“partnerOrderId”:“user01”,“partnerUserId”:“user01”,“itemName”:“컴퓨터”,“itemCode”:null,“quantity”:1,“totalAmount”:2200,“taxFreeAmount”:0,“vatAmount”:200,“approvalURL”:“http://127.0.0.1:8080”,“cancelURL”:“http://127.0.0.1:8080”,“failURL”:“http://127.0.0.1:8080”}
::::POST https://kapi.kakao.com/v1/payment/ready HTTP/1.1
Get connection for route {s}->https://kapi.kakao.com
Connecting to kapi.kakao.com:443
CookieSpec selected: best-match
Auth cache not set in the context
Proxy auth state: UNCHALLENGED
Attempt 1 to execute request
Sending request: POST /v1/payment/ready HTTP/1.1

“POST /v1/payment/ready HTTP/1.1[\r][\n]”
“Accept: application/json[\r][\n]”
“Content-Type: application/x-www-form-urlencoded;charset=utf-8[\r][\n]”
“Authorization: KakaoAK {api Key}[\r][\n]”
“Content-Length: 310[\r][\n]”
“Host: kapi.kakao.com[\r][\n]”
“Connection: Keep-Alive[\r][\n]”
“User-Agent: Apache-HttpClient/4.3.4 (java 1.5)[\r][\n]”
“[\r][\n]”
POST /v1/payment/ready HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Authorization: KakaoAK {api Key}
Content-Length: 310
Host: kapi.kakao.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.4 (java 1.5)
“{“cid”:“TC0ONETIME”,“tid”:null,“pgToken”:null,“partnerOrderId”:“user01”,“partnerUserId”:“user01”,“itemName”:”[0xec][0xbb][0xb4][0xed][0x93][0xa8][0xed][0x84][0xb0]“,“itemCode”:null,“quantity”:1,“totalAmount”:2200,“taxFreeAmount”:0,“vatAmount”:200,“approvalURL”:“http://127.0.0.1:8080”,“cancelURL”:“http://127.0.0.1:8080”,“failURL”:“http://127.0.0.1:8080”}”
<< “HTTP/1.1 400 Bad Request[\r][\n]”
<< “Date: Wed, 03 Jan 2018 04:45:44 GMT[\r][\n]”
<< “Server: Apache[\r][\n]”
<< “Caller-AppId: 166953[\r][\n]”
<< “Content-Type: application/json;charset=UTF-8[\r][\n]”
<< “Content-Length: 38[\r][\n]”
<< “Connection: close[\r][\n]”
<< “[\r][\n]”
Receiving response: HTTP/1.1 400 Bad Request
<< HTTP/1.1 400 Bad Request
<< Date: Wed, 03 Jan 2018 04:45:44 GMT
<< Server: Apache
<< Caller-AppId: 166953
<< Content-Type: application/json;charset=UTF-8
<< Content-Length: 38
<< Connection: close
HTTP/1.1 400 Bad Request [Date: Wed, 03 Jan 2018 04:45:44 GMT, Server: Apache, Caller-AppId: 166953, Content-Type: application/json;charset=UTF-8, Content-Length: 38, Connection: close]

<< “{“msg”:“cid can’t be null.”,“code”:-2}”
Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@6025e1b6
Connection 0.0.0.0:51532<->203.133.166.33:443 shut down
{“msg”:“cid can’t be null.”,“code”:-2}
KakaoPayResponse [cid=null, partnerOrderId=null, partnerUserId=null, paymentMethodType=null, amount=null, cardInfo=null, itemName=null, itmeCode=null, createAt=null, msg=cid can’t be null., code=-2]

파라미터를 josn body 형식 말고 form data 방식으로 보내보시겠어요?
아래 url에 curl 예제 참고하셔서 파라미터명은 모두 snake_case로 해주세요.

https://developers.kakao.com/docs/restapi/kakaopay-api#단건결제-결제준비

cid:TC0ONETIME
tax_free_amount:0
prodNo:10009
total_amount:120000
tax_free_amount:12000.0
approval_url:http://127.0.0.1:8080/kakaoPay/paymentReady.jsp
cancel_url:http://127.0.0.1:8080
fail_url:http://127.0.0.1:8080
item_name:Aaaaa
partner_user_id:user01
paymentOption:1
receiverName:
receiverPhone:
divyAddr:
divyRequest:
divyDate:

위와같이 form data내역이 나오는데 요청에 응답은 이전의 에러와 같이 나옵니다.
함께 첨부합니다.

Sending request: POST /v1/payment/ready HTTP/1.1

“POST /v1/payment/ready HTTP/1.1[\r][\n]”
“Accept: application/json[\r][\n]”
“Content-Type: application/x-www-form-urlencoded;charset=utf-8[\r][\n]”
“Authorization: KakaoAK {발급받은 key}[\r][\n]”
“Content-Length: 342[\r][\n]”
“Host: kapi.kakao.com[\r][\n]”
“Connection: Keep-Alive[\r][\n]”
“User-Agent: Apache-HttpClient/4.3.4 (java 1.5)[\r][\n]”
“[\r][\n]”
POST /v1/payment/ready HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded;charset=utf-8
Authorization: KakaoAK {발급받은 key}
Content-Length: 342
Host: kapi.kakao.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.4 (java 1.5)
"{“cid”:“TC0ONETIME”,“tid”:null,“pg_token”:null,“partner_order_id”:null,“partner_user_id”:“user01”,“item_name”:“Aaaaa”,“item_code”:null,“quantity”:0,“total_amount”:120000,“tax_free_amount”:0,“vat_amount”:0,“approval_url”:"http://127.0.0.1:8080/kakaoPay/paymentReady.jsp",“cancel_url”:“http://127.0.0.1:8080”,“fail_url”:“http://127.0.0.1:8080”}"
<< “HTTP/1.1 400 Bad Request[\r][\n]”
<< “Date: Mon, 08 Jan 2018 01:29:13 GMT[\r][\n]”
<< “Server: Apache[\r][\n]”
<< “Caller-AppId: 166953[\r][\n]”
<< “Content-Type: application/json;charset=UTF-8[\r][\n]”
<< “Content-Length: 38[\r][\n]”
<< “Connection: close[\r][\n]”
<< “[\r][\n]”
Receiving response: HTTP/1.1 400 Bad Request
<< HTTP/1.1 400 Bad Request
<< Date: Mon, 08 Jan 2018 01:29:13 GMT
<< Server: Apache
<< Caller-AppId: 166953
<< Content-Type: application/json;charset=UTF-8
<< Content-Length: 38
<< Connection: close
HTTP/1.1 400 Bad Request [Date: Mon, 08 Jan 2018 01:29:13 GMT, Server: Apache, Caller-AppId: 166953, Content-Type: application/json;charset=UTF-8, Content-Length: 38, Connection: close]
<< “{“msg”:“cid can’t be null.”,“code”:-2}”
Releasing connection org.apache.http.impl.conn.ManagedClientConnectionImpl@30f53ce0
Connection 0.0.0.0:53196<->27.0.237.16:443 shut down
******{“msg”:“cid can’t be null.”,“code”:-2}
Resolving exception from handler [public static com.model2.mvc.service.domain.kakaopay.KakaoPayResponse com.model2.mvc.web.KakaoPay.KakaoPayRestController.readyPay(com.model2.mvc.service.domain.kakaopay.KakaoPayRequest) throws java.lang.Exception]: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])
Resolving exception from handler [public static com.model2.mvc.service.domain.kakaopay.KakaoPayResponse com.model2.mvc.web.KakaoPay.KakaoPayRestController.readyPay(com.model2.mvc.service.domain.kakaopay.KakaoPayRequest) throws java.lang.Exception]: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])
Resolving exception from handler [public static com.model2.mvc.service.domain.kakaopay.KakaoPayResponse com.model2.mvc.web.KakaoPay.KakaoPayRestController.readyPay(com.model2.mvc.service.domain.kakaopay.KakaoPayRequest) throws java.lang.Exception]: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])
Resolving exception from handler [public static com.model2.mvc.service.domain.kakaopay.KakaoPayResponse com.model2.mvc.web.KakaoPay.KakaoPayRestController.readyPay(com.model2.mvc.service.domain.kakaopay.KakaoPayRequest) throws java.lang.Exception]: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])
Resolving to default view ‘/common/error.jsp’ for exception of type [org.codehaus.jackson.map.exc.UnrecognizedPropertyException]
Exposing Exception as model attribute ‘exception’
Handler execution resulted in exception - forwarding to resolved error view: ModelAndView: reference to view with name ‘/common/error.jsp’; model is {exception=org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])}
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field “code” (Class com.model2.mvc.service.domain.kakaopay.KakaoPayResponse), not marked as ignorable
at [Source: java.io.StringReader@11c4c119; line: 1, column: 38] (through reference chain: com.model2.mvc.service.domain.kakaopay.KakaoPayResponse[“code”])
at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
at org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)
at com.model2.mvc.web.KakaoPay.KakaoPayTest.readyPay(KakaoPayTest.java:51)
at com.model2.mvc.web.KakaoPay.KakaoPayRestController.readyPay(KakaoPayRestController.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:747)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:676)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
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)
Invoking afterPropertiesSet() on bean with name ‘/common/error.jsp’
Rendering view [org.springframework.web.servlet.view.JstlView: name ‘/common/error.jsp’; URL [/common/error.jsp]] in DispatcherServlet with name ‘action’
Added model object ‘exception’ of type [org.codehaus.jackson.map.exc.UnrecognizedPropertyException] to request in view with name ‘/common/error.jsp’
Forwarding to resource [/common/error.jsp] in InternalResourceView ‘/common/error.jsp’
Successfully completed request

로그를 찍어서 많이 지저분한 점 양해부탁드립니다.

해결했습니다~ 혹시 같은 문제를 겪고 계실 분들이 있을까 해서 해결법을 기록합니다.

문제는 x-www-form-urlencoded 방식으로 보내는 것이었는데 저의 경우에는 요청을 계속해서 json방식으로 보내는 것이었습니다.

VO객체의 toString()메소드를 http query 형식으로 하고 ByteArrayEntity클래스 인스턴스를 생성하여 Entity에 넣어주었더니 성공적으로 호출이 되었습니다. 감사합니다.

2개의 좋아요