I'm having a SpringBoot and SpringMVC internal application (internal meaning hidden from the internet by a firewall) and a public authentication (OAuth2) service in the DMZ.
I'm accessing the landing page from the from a client in the internal area.
This page has a login button. When I press it, I'm forwarding the client to the auth server (in the DMZ), that I can access only going through a proxy.
I tried setting the VM env variables:
-Dhttp.proxyHost=xx -Dhttp.proxyPort=yy -Dhttp.proxySet=true
and setting them in the System.properties
System.setProperty("http.proxyHost", "http://xx");
System.setProperty("http.proxyPort", "xx");
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
but both with no effect.
I also tried to define a SimpleClientHttpRequestFactory bean :
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="requestFactory"
class="org.springframework.http.client.SimpleClientHttpRequestFactory">
<property name="proxy">
<bean id="proxy" class="java.net.Proxy">
<constructor-arg>
<util:constant static-field="java.net.Proxy.Type.HTTP" />
</constructor-arg>
<constructor-arg>
<bean class="java.net.InetSocketAddress">
<constructor-arg value="xx" />
<constructor-arg value="yy" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
</beans>
without anymore success.
Question
How can I configure Spring to proxify my redirect ?
Thanks!
Got it work as follow (see restTemplateProxy)
private final String server = "xx";
private final int port = yy;
private final SimpleClientHttpRequestFactory clientHttpReq = new SimpleClientHttpRequestFactory();
private final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
private RestTemplate restTemplateProxy = null;
{
clientHttpReq.setProxy(proxy);
restTemplateProxy = new RestTemplate(clientHttpReq);
}
#RequestMapping(value = "getLightToken", method = RequestMethod.GET)
private String getLightToken(Model model) throws JsonProcessingException, IOException {
/* Header */
headers.clear();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
/* Body */
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
body.add(CLIENT_ID.key, CLIENT_ID.val);
body.add(CLIENT_SECRET.key, CLIENT_SECRET.val);
body.add(GRANT_TYPE.key, GRANT_TYPE.val);
body.add(SCOPE.key, SCOPE.val);
/* Set the body and header of the request */
HttpEntity<?> request = new HttpEntity<>(body, headers);
/* Request Authorisation */
ResponseEntity<String> response = restTemplateProxy.exchange(BASE_URL + TOKEN_URI, HttpMethod.POST, request, String.class);
return response.getBody();
}
I'm debugging a controller method in Spring MVC that should return a view, but I'm getting a 404 page.
Error
HTTP Status 404
/WEB-INF/views/responsive/pages/company/myCompanyCreatePurchaseOrderPage.jsp
The view is actually located in
/WEB-INF/views/pages/company/myCompanyCreatePurchaseOrderPage.jsp
Code
#RequestMapping(method = RequestMethod.GET, value = "/admin/getPoNumbers", produces = "application/json")
protected String getPurchaseOrdersFromSettings(#RequestParam(value = "uid")
final String uid, final Model model, final HttpServletRequest request, final RedirectAttributes redirectAttributes) {
// unrelated code omitted
return "pages/company/myCompanyCreatePurchaseOrderPage";
}
Where does this prefix get set?
InternalResourceViewResolver bean on your web.xml or applicationContext.xml
Sample
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
I'm making a SOAP request with custom headers which contains the security part of the request.
But the request now contains two headers and its throwing the following error :
[Request processing failed; nested exception is org.springframework.ws.soap.client.SoapFaultClientException: No WS-Security header found] with root cause
The headers that is formed is :
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><soapenv:Envelope xmlns:ser="dasdasdasd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><wsse:Security xmlns:wsse="asdasdasdas" soapenv:mustUnderstand="1"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-2"><wsse:Username>test</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">adasdasdasdasd</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">!##!####$#!#!##%*(&*&^%#$##</wsse:Nonce><wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header></soapenv:Envelope></SOAP-ENV:Header><SOAP-ENV:Body><ns2:CreateSaleOrderRequest xmlns:ns2="http://uniware.unicommerce.com/services/"><ns2:SaleOrder><ns2:DisplayOrderCode>200</ns2:DisplayOrderCode></ns2:SaleOrder></ns2:CreateSaleOrderRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
My code for the above request is below :
private static final String uri = "http://requestb.in/1eh2un81";
public String createSaleOrder(Suborder suborder)
{
SaleOrder saleorder = new SaleOrder();
saleorder = setSaleOrderObject(suborder);
CreateSaleOrderRequest request = new CreateSaleOrderRequest();
request.setSaleOrder(saleorder);
String response = this.getWebServiceTemplate().marshalSendAndReceive(uri, request,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException
{
SoapMessage soapmessage = (SoapMessage)message;
SoapHeader header = soapmessage.getSoapHeader();
//soapmessage.getEnvelope().addAttribute(, "soapenv");
StringBuilder soapheader = new StringBuilder();
soapheader.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"zsdasdasdasd">");
soapheader.append("<soapenv:Header>");
soapheader.append("<wsse:Security soapenv:mustUnderstand=\"1\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"> ");
soapheader.append("<wsse:UsernameToken wsu:Id=\"UsernameToken-2\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");
soapheader.append("<wsse:Username>test</wsse:Username>");
soapheader.append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">adasdasdasdasd</wsse:Password>");
soapheader.append("<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">!2312312!##!##!#$##%R</wsse:Nonce>");
soapheader.append("<wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created>");
soapheader.append("</wsse:UsernameToken>");
soapheader.append("</wsse:Security>");
soapheader.append("</soapenv:Header>");
soapheader.append("</soapenv:Envelope>");
StringSource HeaderSource = new StringSource(soapheader.toString());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(HeaderSource,header.getResult());
}
}).toString();
System.out.println(response);
Please suggest how do i resolve this error.TIA!
Uhm provided you're using spring you would have to go something like this.. inside your xml for the ws you should have:
<bean id="YourWsClientBean" class="eu.europa.acer.aris.dciws.client.DciWsClient">
<constructor-arg ref="webServiceTemplate"></constructor-arg>
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory"/>
<property name="marshaller" ref="marshaller"></property>
<property name="unmarshaller" ref="unMarshaller"></property>
<property name="messageSender">
<bean
class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
</bean>
</property>
<!-- NON PROXY
<property name="messageSender" ref = "httpSender"></property> -->
<property name="defaultUri" value="https://testframework.test-acer-remit.eu/dci-ws/" />
<property name="interceptors">
<list>
<ref bean="securityConfInterceptor" />
</list>
</property>
</bean>
<bean id="securityConfInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration" value="classpath:securityPolicy.xml" />
<property name="callbackHandlers">
<!-- <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
<property name="keyStore" ref="keyStore" /> <property name="privateKeyPassword"
value="changeit" /> <property name="trustStore" ref="trustStore" /> </bean> -->
<list>
<ref bean="keyStoreHandler"/>
</list>
</property>
</bean>
marshaller and unmarshaller should be clear to you i suppose.
The most important part in your case is
inside the securityPolicy.xml you will be able to define your desirede policy for outgoing//incoming messages, be it signature, usernameandpassword, etc..
The following file for example is for signing the request with a certain certificate.
<?xml version="1.0" encoding="UTF-8"?>
<!-- <xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:Sign includeTimestamp="false"> <xwss:X509Token certificateAlias="ceremp
staging ca"/> </xwss:Sign> </xwss:SecurityConfiguration> -->
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<!-- <xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/>
<xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/>
<xwss:Timestamp /> <xwss:UsernameToken name="mojo" password="mojopass" digestPassword="true"
useNonce="true"/> -->
<xwss:Sign>
<xwss:X509Token certificateAlias="acerprivate" />
<!-- <xwss:X509Token certificateAlias="acer staging cert" /> -->
<xwss:CanonicalizationMethod algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<xwss:SignatureMethod algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<xwss:SignatureTarget type="xpath"
value="./SOAP-ENV:Envelope/SOAP-ENV:Body">
<xwss:DigestMethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<xwss:Transform algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
<xwss:AlgorithmParameter name="XPATH"
value="./SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature[1]/ds:KeyInfo/wsse:SecurityTokenReference" />
</xwss:Transform>
<xwss:Transform
algorithm="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform">
<xwss:AlgorithmParameter name="CanonicalizationMethod"
value="http://www.w3.org/2001/10/xml-exc-c14n#" />
</xwss:Transform>
</xwss:SignatureTarget>
</xwss:Sign>
</xwss:SecurityConfiguration>
Hope this give you an hand as a general concept.
At times I advice some colleague new with ws to take the dirty alternative, if they want to keep the altering as simple as possible.
E.g. this is from spring forum -->
public void sendAndReceiveXMLPayload(String xmlFileNamePath) throws IOException {
ClassPathResource
classPathResource =
new ClassPathResource(xmlFileNamePath);
Source
requestSource =
new ResourceSource(classPathResource);
StringResult
result =
new StringResult();
getWebServiceTemplate().
sendSourceAndReceiveToResult(
requestSource,
new WSSESecurityHeaderRequestWebServiceMessageCallback(),
result
);
}
notice WSSESecurityHeaderRequestWebServiceMessageCallback
define a
public class WSSESecurityHeaderRequestWebServiceMessageCallback implements WebServiceMessageCallback {
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
try {
// Assumption: We are using the default SAAJWebMessageFactory
SaajSoapMessage
saajSoapMessage =
(SaajSoapMessage)message;
SOAPMessage
soapMessage =
saajSoapMessage.getSaajMessage();
SOAPPart
soapPart =
soapMessage.getSOAPPart();
SOAPEnvelope
soapEnvelope =
soapPart.getEnvelope();
SOAPHeader
soapHeader =
soapEnvelope.getHeader();
Name
headerElementName =
soapEnvelope.createName(
"Security",
"wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
);
// Add "Security" soapHeaderElement to soapHeader
SOAPHeaderElement
soapHeaderElement =
soapHeader.addHeaderElement(headerElementName);
// This may be important for some portals!
soapHeaderElement.setActor(null);
// Add usernameToken to "Security" soapHeaderElement
SOAPElement
usernameTokenSOAPElement =
soapHeaderElement.addChildElement("UsernameToken");
// Add username to usernameToken
SOAPElement
userNameSOAPElement =
usernameTokenSOAPElement.addChildElement("Username");
userNameSOAPElement.addTextNode("myUserName");
// Add password to usernameToken
SOAPElement
passwordSOAPElement =
usernameTokenSOAPElement.addChildElement("Password");
passwordSOAPElement.addTextNode("myPassword");
} catch (SOAPException soapException) {
throw new RuntimeException("WSSESecurityHeaderRequestWebServiceMessageCallback", soapException);
}
}
}
in this class feel free to change what you do with your header as you see fit and you're done...
I want to upload a multipartfile. When I use my REST request everything works just fine. When I want to test in JUnit the multipartfile param is not transmitted, I think (because I can't reach the main breakpoint in the debugger).
Error log:
Expected MultipartHttpServletRequest: is a MultipartResolver configured?
spring-common-test.xml:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- max upload size in bytes -->
<property name="maxUploadSize" value="20971520" /> <!-- 20MB -->
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</bean>
Controller
#RequestMapping(value = "/services/tasks/addDocument", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public String set(#RequestParam("idTask") Long idTask,#RequestParam("descriere") String descriere,#RequestParam("name") String name, #RequestParam("file") MultipartFile file){
//things}
Test
#Test
public void testAddDocController() throws Exception {
FileInputStream fis = new FileInputStream("C:/HaxLogs.txt");
MockMultipartFile multipartFile = new MockMultipartFile("file", fis);
HashMap<String, String> contentTypeParams = new HashMap<String, String>();
contentTypeParams.put("boundary", "265001916915724");
MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams);
String resp = mockMvc.perform(post("/services/tasks/addDocument").param("idTask", "141").param("descriere","vadfadfad").param("name", "C:/HaxLogs.txt").content(multipartFile.getBytes()).contentType(mediaType))
.andReturn().getResponse().getContentAsString();
//.andExpect(status().isOk());
System.out.println(resp);
}
I'm trying to send a JSON representation of a Map into my controller as a POST parameter.
#RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" })
public #ResponseBody Results search(#RequestParam("filters") HashMap<String,String> filters, HttpServletRequest request) {
//do stuff
}
I found that #RequestParam would just throw a 500 error, so I tried using #ModelAttribute instead.
#RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" })
public #ResponseBody Results search(#ModelAttribute("filters") HashMap<String,String> filters, HttpServletRequest request) {
//do stuff
}
This would correctly respond to requests, but I realized that the Map was empty. With later experimentation, I found that any object (not just HashMap) would be instantiated, but no fields would be filled in. I do have Jackson on my classpath, and my controllers will respond with JSON. However, it would appear that my current configuration is not allowing Spring to read JSON in via a GET/POST parameter.
How does one pass JSON representations of objects from a client-side AJAX request to a Spring controller as a request parameter and get a Java object out?
EDIT Adding my relevant Spring configuration
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true" />
</bean>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
On the suggestion of a commenter, I tried #RequestBody. This will work, so long as the JSON strings are quoted with double quotes.
#RequestMapping(value = "/search.do", method = RequestMethod.POST, consumes = { "application/json" })
public #ResponseBody Results<T> search(#RequestBody HashMap<String,String> filters, HttpServletRequest request) {
//do stuff
}
This does solve my immediate issue, but I'm still curious as to how ou might pass in multiple JSON objects via an AJAX call.
This does solve my immediate issue, but I'm still curious as to how ou might pass in multiple JSON objects via an AJAX call.
The best way to do this is to have a wrapper object that contains the two (or multiple) objects you want to pass. You then construct your JSON object as an array of the two objects i.e.
[
{
"name" : "object1",
"prop1" : "foo",
"prop2" : "bar"
},
{
"name" : "object2",
"prop1" : "hello",
"prop2" : "world"
}
]
Then in your controller method you recieve the request body as a single object and extract the two contained objects. i.e:
#RequestMapping(value="/handlePost", method = RequestMethod.POST,
consumes = { "application/json" })
public void doPost(#RequestBody WrapperObject wrapperObj) {
Object obj1 = wrapperObj.getObj1;
Object obj2 = wrapperObj.getObj2;
//Do what you want with the objects...
}
The wrapper object would look something like...
public class WrapperObject {
private Object obj1;
private Object obj2;
public Object getObj1() {
return obj1;
}
public void setObj1(Object obj1) {
this.obj1 = obj1;
}
public Object getObj2() {
return obj2;
}
public void setObj2(Object obj2) {
this.obj2 = obj2;
}
}
You may use the Jackson library to convert from Json to Map.
#web-context.xml
<bean id="messageAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
#maven dependencies:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-lgpl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-lgpl</artifactId>
<version>1.9.13</version>
</dependency>
#Controller
#RequestMapping(value = "/method", method = RequestMethod.DELETE)
public String method(
#RequestBody Map<String, Object> obj){
#Request (e.g. jquery Ajax)
$.ajax({"type": "DELETE",
"contentType": "application/json;",
"url": "/method",
"data": JSON.stringify({"key": "Ricardo"}),
"dataType": "json";}
});
It's much easier with Python Frameworks or Play! ufff
I have passed the Map object to Java using below code :
Javascript Code :
var values = {
"object1" : JSON.stringify(object1),
"object2" : JSON.stringify(object2)
};
var response = $http.post(url,data);
Server Side Code :
#RequestMapping(value = "/deleteData",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Result deleteData(#RequestBody HashMap<String, Object> dataHashMap) {
Object1 object1= (Object1) JsonConvertor.jsonToObject((String) dataHashMap.get("object1"), Object1.class);
Object2 object2= (Object2) JsonConvertor.jsonToObject((String) dataHashMap.get("object2"), Object2.class);
}
JsonConvertor Class :
public class JsonConvertor {
public static <T> Object jsonToObject(String json, Class<T> clazz) {
if (json == null)
throw new IllegalArgumentException("null cannot be converted to Object");
Gson gson = new GsonBuilder().disableHtmlEscaping().setDateFormat("dd-MMM-yyyy").create();
return gson.fromJson(json, clazz);
}
}
You are not getting json correctly.
Do like that ....
/*
* Mapping for Demographics And Profiling Question Filter
*/
#RequestMapping (value = "/generalFilter")
public void ageFilteration(#RequestParam Map <String,String> filterParams,HttpServletRequest request,HttpServletResponse response) throws IOException
{
// System.out.println("Geographies in Controller :"+ filterParams.get("geographies"));
List<FeasibilityBean> feasibilityList = feasibilityDao.getGeneralFeasibilityList(filterParams,request);
// System.out.println(" General Filter List Size:"+feasibilityList.size());
response.getWriter().print(new Gson().toJsonTree(feasibilityList,new TypeToken<List<FeasibilityBean>>(){}.getType()));
}
}
Js Code
var ages='',ageCond='',genders='',genderCond='';
$.ajax({
type: "POST",
url : url,
data : {ages:ages,ageCond:ageCond,genders:genders,genderCond:genderCond},
beforeSend: function() {
$(thisVar).find('i').addClass('fa-spin');
},
success : function(feasibilityJson){
},
error : function(data) {
alert(data + "error");
},
complete:function(){
$(thisVar).find('i').removeClass('fa-spin');
}
});
or you want to bind bean with json....
https://stackoverflow.com/a/21689084/5150781
https://stackoverflow.com/a/37958883/5150781
#RequestMapping(method = RequestMethod.POST)
public HttpEntity<Resource<Customize>> customize(#RequestBody String customizeRequest) throws IOException {
Map<String, String> map = mapper.readValue(customizeRequest, new TypeReference<Map<String,String>>(){});
log.info("JSONX: " + customizeRequest);
Long projectId_L = Long.parseLong(map.get("projectId"));
[...]
As #dario's answer, but for Jackson 2 version:
spring-web-context.xml
<bean id="messageAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=utf-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
maven pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
java controller
#RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" })
public #ResponseBody Results search(#RequestBody Map<String,Object> filters, HttpServletRequest request) {