Spring REST custom deserialisation - spring-mvc

Is it possible to have configure spring to deserialise an incoming json how you want.
So example
{ "user":"abc" }
I would like this to hit my custom deserialiser before being processed by my by controller method.
How can i do this? I have access to an user object, but that object cannot be annotated as its external to my project.
But i would still like to populate that object and pass it into by REST method.

You have to create the objectMapper bean implementation which contains a mixIn as:
#Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(MyObject.class, MyObjectMixin.class);
return mapper;
}
Then the mixing will be like that:
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#class")
#JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
#JsonDeserialize(using = MyObjectDeserializer.class)
public class MyObjectMixin {
}
And finally, the deserializer must just extends JsonDeserializer with the method:
#Override
public MyObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {

Related

No mapping found for HTTP request with URI [/api/transactions] in DispatcherServlet with name ''

I thought this is a standard configuration. But I get a 404 back. Where else should I configure Spring Boot ?
#RestController
#RequestMapping("/api")
public class TransactionStatisticsController {
public static final Logger logger = LoggerFactory.getLogger(TransactionStatisticsController.class);
#RequestMapping(value = "/transactions",
method = RequestMethod.POST)
public ResponseEntity sendTransaction(#RequestBody Transaction request) {
logger.info( request.toString());
return new ResponseEntity(HttpStatus.OK);
}
}
This is my test.
#JsonTest
#SpringBootTest(classes = Application.class)
#AutoConfigureMockMvc
#RunWith(SpringRunner.class)
public class TransactionStatisticsRestTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private JacksonTester<Transaction> json;
private static Transaction transaction;
#BeforeClass
public static void createTransaction(){
BigDecimal amount = new BigDecimal(12.3343);
transaction = new Transaction(amount.toString(),
"2010-10-02T12:23:23Z");
}
#Test
public void getTransactionStatus() throws Exception {
final String transactionJson = json.write(transaction).getJson();
mockMvc
.perform(post("/api/transactions")
.content(transactionJson)
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}
public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsBytes(transaction);
}
}
Request being made is
MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/transactions
Parameters = {}
Headers = {Content-Type=[application/json;charset=UTF-8]}
Body = {"amount":"12.3343000000000007077005648170597851276397705078125","timestamp":"2010-10-02T12:23:23Z[UTC]"}
Session Attrs = {}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Update : I added a component scan pointing to a base package. I don't see that error now. Please see the comments where there is an answer.
As in the comment section ,there was only requirement was to bind a component scan base package location .
#Component scan -->Configures component scanning directives for use with #Configuration classes. Provides support parallel with Spring XML's element.
Either basePackageClasses() or basePackages() (or its alias value()) may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
Please share your project folder architecture. It might be possible that your controller package is out of the main class package. That's why it is showing 404.
This code :
#RestController
#RequestMapping("/api")
public class TransactionStatisticsController {
public static final Logger logger = LoggerFactory.getLogger(TransactionStatisticsController.class);
#RequestMapping(value = "/transactions",
method = RequestMethod.POST)
public ResponseEntity sendTransaction(#RequestBody Transaction request) {
logger.info( request.toString());
return new ResponseEntity(HttpStatus.OK);
}
}
This should be into your main package where
#SpringBootApplication
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
this main class resides.
I hope, this will help.
Seems using #JsonTest does not even allow to load Application Context, results mapping is not loaded and its throw 404 so #JsonTest is not a replacement for #SpringBootTest, it is a way to easily test json serialization/de-serialization.
As per documentation:
you can use the #JsonTest annotation. #JsonTest auto-configures the
available supported JSON mapper, which can be one of the following
libraries:
Jackson ObjectMapper, any #JsonComponent beans and any Jackson Modules
Gson
Jsonb
If by using Gson and removing #JsonTest your test run fine..(add Gson Dependency in pom)
#SpringBootTest
#AutoConfigureMockMvc
#RunWith(SpringRunner.class)
public class DemoKj01ApplicationTests {
#Autowired
private MockMvc mockMvc;
private static Transaction transaction;
#BeforeClass
public static void createTransaction(){
BigDecimal amount = new BigDecimal(12.3343);
transaction = new Transaction(amount.toString(),
"2010-10-02T12:23:23Z");
}
#Test
public void getTransactionStatus() throws Exception {
//final String transactionJson = json.write(transaction).getJson();
Gson gson = new Gson();
String jsonRequest = gson.toJson(transaction);
mockMvc
.perform(post("/api/transactions")
.content(jsonRequest)
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}
It is beacause of the trailing slas in #RequestMapping(value = "/transactions/", method = RequestMethod.POST)
Remove it and it will be ok : value = "/transactions/" => value = "/transactions"

Spring MVC - PropertyEditor not called during ModelAttribute type conversion

Using Spring 3.2.3, I'm trying to implement a simple CRUD controller that handles REST-ful URLs. It relies on a PropertyEditor to convert a path variable to a BusinessService entity by loading it from an application service. Code is as follows:
#Controller
public class BusinessServiceController {
#Autowired
private BusinessServiceService businessSvcService;
public BusinessServiceController() {
}
#InitBinder
public void initBinder(final WebDataBinder binder) {
binder.registerCustomEditor(BusinessService.class, new BusinessServicePropertyEditor(businessSvcService));
}
#RequestMapping(value = "/ui/account/business-services/{businessSvc}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ModelAndView update(#ModelAttribute("businessSvc") #Valid final BusinessService businessSvc, final BindingResult result,
final RedirectAttributes redirectAttribs) throws UnknownBusinessServiceException {
ModelAndView mav;
if (result.hasErrors()) {
mav = new ModelAndView("/business-service/edit");
}
else {
businessSvcService.updateBusinessService(XSecurity.principal().getId(), businessSvc);
mav = new ModelAndView("redirect:/ui/account/business-services");
redirectAttribs.addFlashAttribute("message", Message.info("businessService.updated", businessSvc.getTitle()));
}
return mav;
}
}
public class BusinessServicePropertyEditor extends PropertyEditorSupport {
private final BusinessServiceService businessSvcService;
public BusinessServicePropertyEditor(final BusinessServiceService businessSvcService) {
this.businessSvcService = businessSvcService;
}
#Override
public String getAsText() {
final BusinessService svc = (BusinessService) getValue();
return Long.toString(svc.getId());
}
#Override
public void setAsText(final String text) {
final BusinessService svc = businessSvcService.getBusinessService(Long.parseLong(text));
setValue(svc);
}
}
According to SPR-7608, starting from Spring 3.2, #ModelAttribute method argument resolution checks if a path variable by the same name exists (it does here), in which case it tries to convert that path variable's value to the target parameter type through registered Converters and PropertyEditors. This is not what I'm experiencing. When I inspect what ServletModelAttributeMethodProcessor does, it clearly uses the request DataBinder's ConversionService to perform type conversion, which does not consider registered PropertyEditors, and hence BusinessServicePropertyEditor#setAsText is never called.
Is this a configuration problem or an actual bug?
Thanks for your help!
Spring's ConversionService and Converters are replacement for standard Java Beans PropertyEditors.
You need to implement Converter instead of PropertyEditor if this feature is based purely on conversion service.
To register your custom converters in WebDataBinder you might use ConfigurableWebBindingInitializer or #InitBinder method.

How to setup OAuth2RestTemplate (Post Updated)

I am not sure if I have OAuth2RestTemplate configured correctly. I am getting the following error when I run the tester class.
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#1df3248: defining beans [propertyConfigurer,dataSource,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,emf,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,accountRepository,questionRepository,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,jpaQuestionService,jpaAccountService,passwordEncoder,accountHelper,tradeConfig,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#1,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,baseOAuth2ProtectedResourceDetails,oAuth2ProtectedResourceDetails,accessTokenRequest,oAuth2ClientContext,oAuth2RestTemplate]; root of factory hierarchy
Exception in thread "main" error="access_denied", error_description="Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it."
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:146)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:216)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:168)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:89)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:442)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:123)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:385)
at com..main(Tester.java:44)
Classes
#Configuration
public class AppConfig {
#Bean
//#Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
public BaseOAuth2ProtectedResourceDetails baseOAuth2ProtectedResourceDetails(){
BaseOAuth2ProtectedResourceDetails baseOAuth2ProtectedResourceDetails = new BaseOAuth2ProtectedResourceDetails();
baseOAuth2ProtectedResourceDetails.setClientId(clientId);
baseOAuth2ProtectedResourceDetails.setClientSecret(clientSecret);
return baseOAuth2ProtectedResourceDetails;
}
#Bean
public DefaultAccessTokenRequest accessTokenRequest(){
return new DefaultAccessTokenRequest();
}
#Bean
public OAuth2ClientContext oAuth2ClientContext(){
return new DefaultOAuth2ClientContext(accessTokenRequest());
}
#Bean
public OAuth2RestTemplate oAuth2RestTemplate(){
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(baseOAuth2ProtectedResourceDetails(),oAuth2ClientContext());
return restTemplate;
}
}
Tester Class
public class Tester {
public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath*:jpa-app-context.xml");
ctx.refresh();
EntityManagerFactory emf = (EntityManagerFactory) ctx.getBean("emf");
EntityManager em = emf.createEntityManager();
TransactionSynchronizationManager.bindResource(emf , new EntityManagerHolder(em));
OAuth2RestTemplate oAuth2RestTemplate = (OAuth2RestTemplate) ctx.getBean("oAuth2RestTemplate");
//OAuth2RestTemplate oAuth2RestTemplate = ctx.getBean(OAuth2RestTemplate.class);
String uri="https:api..";
Object obj = oAuth2RestTemplate.exchange(uri, HttpMethod.POST, null, Object.class);
System.out.println("Tester Object: "+ obj.toString());
}
}
I faced the same exception, but with another protected resource type.
Generally, the exception raises only when AccessTokenProviderChain can't find an appropriate *AccessTokenProvider for particular *ProtectedResourceDetails instance. Meaning, when you try to do the following:
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri(url);
resource.setClientId(clientId);
resource.setClientSecret(secret);
resource.setGrantType("password");
return resource;
The code expects a client_credentials grant type since we use a ClientCredentialsResourceDetails, but we pass password value.
Here the code that worked in my case:
private OAuth2ProtectedResourceDetails withOAuth2Authentication(final String url, final String clientId, final String secret) {
ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri(url);
resource.setClientId(clientId);
resource.setClientSecret(secret);
// here you can provide additional properties such as scope etc.
return resource;
}
#Bean
RestTemplate callbackClientV2() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(
withOAuth2Authentication(v2ServerUrl, v2Username, v2Password),
new DefaultOAuth2ClientContext(atr)
);
}

Spring MVC jackson auto serialize?

I would like to serialize an object with jackson in spring MVC.
I have a controller which returns an ObjectTest1 which has a property ObjectTest2.
public class ObjectTest1{
private ObjectTest2;
// setters getters...
}
public class ObjectTest2{
private String value;
// setters getters...
}
public #ResponseBody ObjectTest1 test() throws IOException ...
I have a mapper and I have a serializer for ObjectTest2 and I've annotated the ObjectTest1.getObjectTest2 method with #JsonSerialize(using = ObjectTest2.class).
It works correctly!
But I want to use this serializer in a lot of Object, not just in ObjectTest1.
What should I do to avoid put annotation every getter method? Can use spring this serializer automatically for all properites which is ObjectTest2?
UPDATED:
I've already use this in my code:
<mvc:annotation-driven>
In ajax response Objects generated correctly as json.
Maybe I should try to explain another way.
So.
I have these objects:
public class DTO{
private InnerThing innerThing;
#JsonSerialize(using=ThingSerializer.class)
public InnerThing getThing(){...}
}
public class InnerThing{
private String value;
}
Generated json looks like:
{"innerThing":{"value":"something"}}
Afther when I've written a serializer, json is:
{"innerThing":"something"}
It is OK, but to get the second version of json I must annotate the getInnerThing method in DTO class with #JsonSerialize...
I don't want to annotate all methods where I use InnerThing as a property.
So my question is, can spring auto serialize every property which type is InnerThing?
By default, Spring will handle serialization and de-serialization of JSON automatically if you add Jackson to the classpath and you use either <mvc:annotation-driven> or #EnableWebMvc.
Links to the Spring Reference Docs:
Spring 3.0: <mvc:annotation-driven>
Spring 3.1: <mvc:annotation-driven> and #EnableWebMvc
You want Jackson to always use your custom JsonSerializer or JsonDeserializer to serialize/deserialize a specific type?
I ended up writing a custom Jackson module to let Jackson find serializers and deserializers that are Spring beans.
I am using Spring 3.1.2 and Jackson 2.0.6
Simplified version:
public class MyObjectMapper extends ObjectMapper {
#Autowired
public MyObjectMapper(ApplicationContext applicationContext) {
SpringComponentModule sm = new SpringComponentModule(applicationContext);
registerModule(sm);
}
}
Module:
public class SpringComponentModule extends Module {
private ApplicationContext applicationContext;
public SpringComponentModule(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override public String getModuleName() {
return "jackson-spring-component";
}
#Override public Version version() {
return SpringComponentModuleVersion.instance.version();
}
#Override
public void setupModule(SetupContext context) {
context.addSerializers(new SpringComponentSerializers(this.applicationContext));
context.addDeserializers(new SpringComponentDeserializers(this.applicationContext));
}
}
ComponentSerializer class:
public class SpringComponentSerializers extends Serializers.Base {
private ApplicationContext applicationContext;
public SpringComponentSerializers(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) {
Class<?> raw = type.getRawClass();
Map<String,JsonSerializer> beanSet = applicationContext.getBeansOfType(JsonSerializer.class);
for(String beanName : beanSet.keySet()) {
JsonSerializer<?> serializer = beanSet.get(beanName);
if(serializer.handledType().isAssignableFrom(raw)) {
return serializer;
}
}
return null;
}
}

Http Post with request content type form not working in Spring MVC 3

code snippet:
#RequestMapping(method = RequestMethod.POST)//, headers = "content-type=application/x-www-form-urlencoded")
public ModelAndView create(#RequestBody UserAccountBean account) {
try{
accounts.put(account.assignId(), account);
}catch(RuntimeException ex)
{
return new ModelAndView("account/registerError");
}
return new ModelAndView("account/userVerification");
}
After receiving request, What I got is Http Status code 415:
The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().
If I change the code to this:
code snippet:
#RequestMapping(method = RequestMethod.POST,headers = "content-type=application/x-www-form-urlencoded")
public ModelAndView create(#RequestBody UserAccountBean account) {
try{
accounts.put(account.assignId(), account);
}catch(RuntimeException ex)
{
return new ModelAndView("account/registerError");
}
return new ModelAndView("account/userVerification");
}
I will get 405 Method not allowed. Funny thing is in the allow header of response, it lists GET and POST as allowed methods.
I do have a class that does JOSN mapping:
#Component
public class JacksonConversionServiceConfigurer implements BeanPostProcessor {
private final ConversionService conversionService;
#Autowired
public JacksonConversionServiceConfigurer(ConversionService conversionService) {
this.conversionService = conversionService;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AnnotationMethodHandlerAdapter) {
AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
HttpMessageConverter<?>[] converters = adapter.getMessageConverters();
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJacksonHttpMessageConverter) {
MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter;
jsonConverter.setObjectMapper(new ConversionServiceAwareObjectMapper(this.conversionService));
}
}
}
return bean;
}
}
Copied from Spring examples. works great with JSON content-type.
A more general question is how to make spring mvc request handlers work with different request content-types.
Any advice would be greatly appreciated.
Unfortunately FormHttpMessageConverter (which is used for #RequestBody-annotated parameters when content type is application/x-www-form-urlencoded) cannot bind target classes (as #ModelAttribute can).
Therefore you need #ModelAttribute instead of #RequestBody. If you don't need to pass different content types to that method you can simply replace the annotation:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView create(#ModelAttribute UserAccountBean account) { ... }
Otherwise I guess you can create a separate method form processing form data with the appropriate headers attribute:
#RequestMapping(method = RequestMethod.POST,
headers = "content-type=application/x-www-form-urlencoded")
public ModelAndView createFromForm(#ModelAttribute UserAccountBean account) { ... }
EDIT: Another possible option is to implement your own HttpMessageConverter by combining FormHttpMessageConverter (to convert input message to the map of parameters) and WebDataBinder (to convert map of parameters to the target object).
I was having HTTP response code of 415
My problems were resolved when I added Content Type to request header
e.g
"Content-Type: application/json"
At the heart of the problem, we wish to accept both application/json and application/x-www-form-urlencoded Content-types with the same request handler.
To do this, I use the #RequestBody, which was already working for application/json for me (and generally others from the threads I've found, but there is extra work so application/x-www-form-urlencoded can be used with #RequestBody.
First, create a new HttpMessageConverter capable of changing the request input to an object. I do this by reusing the FormHttpMessageConverter, which is already capable of changing the input to a MultiValueMap. I then change the MultiValueMap to a regular Map, and use Jackson to turn the Map to the desired object.
Here is the code for the HttpMessageConverter:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* <p>Converts HTTP requests with bodies that are application/x-www-form-urlencoded or multipart/form-data to an Object
* annotated with {#link org.springframework.web.bind.annotation.RequestBody} in the the handler method.
*
* #author Jesse Swidler
*/
public class ObjectHttpMessageConverter implements HttpMessageConverter<Object> {
private final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
private final ObjectMapper objectMapper = new ObjectMapper();
private static final LinkedMultiValueMap<String, String> LINKED_MULTI_VALUE_MAP = new LinkedMultiValueMap<>();
private static final Class<? extends MultiValueMap<String, ?>> LINKED_MULTI_VALUE_MAP_CLASS
= (Class<? extends MultiValueMap<String, ?>>) LINKED_MULTI_VALUE_MAP.getClass();
#Override
public boolean canRead(Class clazz, MediaType mediaType) {
return objectMapper.canSerialize(clazz) && formHttpMessageConverter.canRead(MultiValueMap.class, mediaType);
}
#Override
public boolean canWrite(Class clazz, MediaType mediaType) {
return false;
}
#Override
public List<MediaType> getSupportedMediaTypes() {
return formHttpMessageConverter.getSupportedMediaTypes();
}
#Override
public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
Map<String, String> input = formHttpMessageConverter.read(LINKED_MULTI_VALUE_MAP_CLASS, inputMessage).toSingleValueMap();
return objectMapper.convertValue(input, clazz);
}
#Override
public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws UnsupportedOperationException {
throw new UnsupportedOperationException("");
}
}
There are many different ways a Spring app might pick up that message converter. For me, it was accomplished in an XML file:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="com.terminal.core.services.config.ObjectHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
Using #ModelAttribute is indeed the preferred way to deal with form parameters.
Using JSON worked for me as well, I suppose it makes the JSON interpreter get the data from the body.
I was trying to use PUT though, which is a bit harder.
You can read my post about it here.
Below worked for me
On server side:
#RequestMapping(value = "test", method = RequestMethod.POST, consumes = {"application/xml", "application/json"})
#ResponseStatus(HttpStatus.OK)
public #ResponseBody
String methodName(#RequestBody EntityClassName entity) {
On client side:
String json = new JSONStringer().object()
.key("key").value("value")
.endObject()
.toString();
StringEntity se = new StringEntity(json);
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
request.setEntity(se);
HttpResponse response = client.execute(request);
I use this code for convert html form to json .
function ConvertFormToJSON(form) {
var array = $(form).serializeArray();
var json = {};
$.each(array, function() {
json[this.name] = this.value || '';
});
return json;
}
and use single quotations was wrong . I changed ' ' to " " and problem solved.

Resources