Spring 4 RestController & Returning JSON - json

I have a simple controller, which should return JSON, but is failing to do so. The JSON library is Jackson, configured as a maven dependency. When I make a request using postman, against this url path, I am receiving a 404 error. When I attempt to inspect the JSON Returned, I see "Malformed JSON: Unexpected '<'".
Could someone suggest what it is I am missing / failing to understand? Thank you
#RestController
#RequestMapping("/World/")
public class RestfulController {
#RequestMapping(value = "/Country/", method = RequestMethod.GET, produces="application/json")
public ResponseEntity<Country> findAllCountrys(){
Country c = new Country(1, "Ethiopia", "Addis Abba", "94 Million");
return new ResponseEntity<Country>(c, HttpStatus.OK);
}
}
spring application context
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.restfulapp.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
</bean>

You should try this:
#RestController
#RequestMapping("/World")
public class RestfulController {
#RequestMapping(value = "/Country", method = RequestMethod.GET)
public Country findAllCountrys(){
Country c = new Country(1, "Ethiopia", "Addis Abba", "94 Million");
return c;
}
}
The request url: http://yourhost/World/Country
This should return a json of Country

Related

Transactions not persisting - Spring MVC with Hibernate

I have a spring MVC (4.1.6) app, using Hibernate ORM (5.3.7) on top of a MySQL 8 Database.
I have a view with a form that should create a row in the DB when it is submitted, but it does not. I can tell the information gets to my #Service bean and DAO #Repository bean. I can also successfully query data from the DB and display it on a view, if I update the DB directly through SQL.
I have read a number of posts and tried to reconfigure my application context and servlet context XMLs with no luck. Can anyone tell me where I am going wrong?
Below are some snippets.
Web_XML
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/applicationContext-dao.xml
/WEB-INF/spring/applicationContext-security.xml
</param-value>
</context-param>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
applicationContext-web.xml
<context:component-scan base-package="edu.neu.snowfinder">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<interceptors>
<beans:bean class= "org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<beans:property name="sessionFactory" ref="sessionFactory"/>
</beans:bean>
</interceptors>
applicationContext-dao.xml
<bean id="sessionFactory" class = "org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name = "dataSource" ref = "dataSource"/>
<property name = "configLocation">
<value> classpath:hibernate.cfg.xml</value>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id = "transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref = "sessionFactory"/>
<property name="dataSource" ref = "dataSource"/>
</bean>
UserServiceImpl
#Service
public class UserServiceImpl implements UserService {
#Autowired
#Qualifier("userHibernateDAO")
private UserDAO userDAO;
#Override
#Transactional
public void createUser(User user) {
System.out.println("Does the Sevice have the user?"+user.getFirstname());
userDAO.createUser(user);
}
#Override
#Transactional
public Collection<User> listUsers() {
return userDAO.listUsers();
}
}
UserHibernateDAO
#Repository
public class UserHibernateDAO implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public void createUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
System.out.println("Does the DAO have the user?"+user.getFirstname());
System.out.println("Does the DAO have a session?"+sessionFactory.getCurrentSession().toString());
Serializable id = sessionFactory.getCurrentSession().save(user);
session.getTransaction().commit();
System.out.println("Whats the saved User's ID??"+id.toString());
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name = "hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name = "hibernate.showsql">true</property>
<property name = "hibernate.formatsql">true</property>
<property name = "hibernate.hbm2ddl.auto">create</property>
<mapping class = "edu.neu.snowfinder.model.User"/>
</session-factory>
</hibernate-configuration>

Angular Spring Post json with array

i try to send json object from angular frontend to spring mvc backend without success. This is my config and what i have tried :
config :
web.xml :
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/META-INF/jdu/contexts/rest-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
rest-servlet.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<!-- prevent JSON Hijacking -->
<property name="prefixJson" value="true"/>
</bean>
</beans>
applicationContext:
<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- Use the HibernateAware mapper instead of the default -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.mc.jdu.utils.HibernateAwareObjectMapper"/>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
pom.xml with jackson-version = 2.6.3:
<!-- Data Mapper package is a high-performance data binding package built
on Jackson JSON processor -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency><!-- jackson -->
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
my controller :
#RequestMapping(value="/create", method=RequestMethod.POST)
#ResponseBody
public StatusResponse create(EventsDTO eventsDTO) throws TechnicalException {
return service.create(eventsDTO);
}
EventDTO :
public class EventsDTO implements BeanInterface{
private String textColor;
private String color;
private List<CallendarDTO> events = new ArrayList<CallendarDTO>();
public EventsDTO(){
}
// getters and setters
CallendarDTO :
public class CallendarDTO {
private String title;
private String libelle;
private String date;
private String start;
private String end;
private String duree;
private boolean allDay;
private boolean stick;
Angular :
var _queryPost = function(url, data, defData) {
$http({
headers:{'Content-Type':'application/json'},
method: 'POST',
url: url,
params: data
})
.success( function(data, status, headers, config) {
defData.$resolve(data);
$log.info(data);
})
. error(function(data, status, headers, config) {
$log.warn('*** DataProvider - query - error - status:' + status);
401===status?$location.path('/signIn'):$location.path('/error' + status);
defData.$reject(data);
});
return defData;
};
And the data :
$scope.eventsDTO = [];
$scope.eventsDTO.color = "green ";
$scope.eventsDTO.texColor="";
//$scope.eventsDTO.events=[];
$scope.eventsDTO.events= [
{
"title":"1",
"date":"2013-10-04",
"libelle":"lib 1",
"start":"08:30",
"end":"10:30",
"duree":"02:00",
"allDay":false,
"stick":true
},
{
"title":"2",
"date":"2013-10-04",
"libelle":"lib 2",
"start":"08:30",
"end":"10:30",
"duree":"02:00",
"allDay":false,
"stick":true
}
];
OK. if i try like this i get : "the server responded with a status of 400 (Bad Request)"
If the events list is empty, it works....but of course i need this list
So i red this post : Spring MVC : post request and json object with array : bad request
and i have tried to add #RequestBody on the controller like this :
#RequestMapping(value="/create", method=RequestMethod.POST)
#ResponseBody
public StatusResponse create(#RequestBody EventsDTO eventsDTO) throws TechnicalException {
return service.create(eventsDTO);
}
but now i get : "the server responded with a status of 415 (Unsupported Media Type)"
In fact, the app works when i pass object without List inside. But if there is a List (like EventsDTO with its CallendarDTO List), it doesn't work.
The error 415 by adding #RequestBody make me think that my Jackson config is wrong...but where ?
I have tried to change apllicationContext.xml configuration with what i have found ont the web, for exemple, by adding :
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter" />
</list>
</property>
</bean>
But i don't understand exactly how does it work..
How can i pass my EventsDTO ?

WSO2ESB - Sending message to MB with JSON content type

Using WSO2 ESB, I'm trying to send an AMQP message to the WSO2 message broker. This AMQP message should have JSON content type.
I expose a Proxy service in WSO2 ESB that gets the message, transforms it to JSON and sends it to the message broker. The proxy service configuration looks like :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="json_sample" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<log level="full"/>
<header name="To"
value="jms:/sample-queue?transport.jms.ConnectionFactoryJNDIName=sampleConnectionFactory&java.naming.factory.initial=org.wso2.andes.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=repository/conf/jndi.properties&transport.jms.DestinationType=queue"/>
<send/>
</inSequence>
</target>
<publishWSDL>
<definitions name="JsonSample" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/JsonSample.wsdl" targetNamespace="http://www.examples.com/wsdl/JsonSample.wsdl">
<message name="JsonSampleRequest">
<part name="prop1" type="xsd:string"/>
<part name="prop2" type="xsd:string"/>
</message>
<portType name="JsonSample_PortType">
<operation name="jsonObject">
<input message="tns:JsonSampleRequest"/>
</operation>
</portType>
<binding name="JsonSample_Binding" type="tns:JsonSample_PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="jsonObject">
<soap:operation soapAction="jsonObject"/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:jsonsample" use="encoded"/>
</input>
</operation>
</binding>
<service name="JsonSample_Service">
<port binding="tns:JsonSample_Binding" name="JsonSample_Port">
<soap:address location="http://www.examples.com/JsonSample/"/>
</port>
</service>
</definitions>
</publishWSDL>
<description/>
</proxy>
This proxy service works well, transforming the message to JSON, but do not set AMQP message content type to JSON. The message is considered as text.
When I try to inject an AMQP message in the message broker programmatically, using this code, I really have a message with JSON content type :
import java.util.Properties;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.wso2.andes.client.message.JMSTextMessage;
public class StackOverflowSample {
private static final String QPID_ICF = "org.wso2.andes.jndi.PropertiesFileInitialContextFactory";
private static final String CF_NAME_PREFIX = "connectionfactory.";
private static final String CF_NAME = "qpidConnectionfactory";
private static final String CARBON_CLIENT_ID = "carbon";
private static final String CARBON_VIRTUAL_HOST_NAME = "carbon";
private static final String host = "localhost";
private static final int port = 5675;
private static final String userName = "admin";
private static final String password = "admin";
private static final String queueName = "sample-queue";
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, QPID_ICF);
properties.put(CF_NAME_PREFIX + CF_NAME, getTCPConnectionURL(userName, password));
InitialContext ctx = new InitialContext(properties);
// Lookup connection factory
QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup(CF_NAME);
QueueConnection queueConnection = connFactory.createQueueConnection();
queueConnection.start();
QueueSession queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
// Send message
Queue queue = queueSession.createQueue(queueName);
// create the message to send
JMSTextMessage textMessage = (JMSTextMessage) queueSession
.createTextMessage("{\"prop1\":\"value1\",\"prop2\":\"value2\"}");
textMessage.setContentType("application/json");
javax.jms.QueueSender queueSender = queueSession.createSender(queue);
queueSender.send(textMessage);
queueSender.close();
queueSession.close();
queueConnection.close();
}
private static String getTCPConnectionURL(String username, String password) {
// amqp://{username}:{password}#carbon/carbon?brokerlist='tcp://{hostname}:{port}'
return new StringBuffer().append("amqp://").append(username).append(":").append(password).append("#")
.append(CARBON_CLIENT_ID).append("/").append(CARBON_VIRTUAL_HOST_NAME).append("?brokerlist='tcp://")
.append(host).append(":").append(port).append("'").toString();
}
}
Changing textMessage.setContentType("application/json"); to textMessage.setContentType("text/plain"); gives me the same result as using the ESB.
So the question is : how can I configure the ESB to set the AMQP message content type as JSON ?
Thanks
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
is used to choose message formatter class.
You could have a try with :
<property name="ContentType"
value="application/json"
scope="axis2"
type="STRING"/>

JSON Response with Spring 3 MVC and jQuery

I have some huge trouble receiving JSON from my simple Spring Controller although I checked against many other tutorials and even the official spring blog and could not find any difference, so please help me.
So my dependencies in my project are:
spring-context 3.2.2 RELEASE
spring-web 3.2.2 RELEASE
spring-webmvc 3.2.2 RELEASE
spring-test 3.2.2 RELEASE
junit 4.10
servlet-api 2.5
atmosphere-runtime 1.1.0 RC4
logback-classic 1.0.13
libthrift 0.9.0
jackson-mapper-asl 1.9.12
jackson-core-asl 1.9.12
My Controller is very simple and just generates a random UUID and returns it. It looks as follows:
#Controller
public class SimpleController {
#RequestMapping(value="/new", method=RequestMethod.GET)
public #ResponseBody SimpleResponse new() throws JsonGenerationException, JsonMappingException, IOException {
SimpleResponse sr = new SimpleResponse();
sr.setId(UUID.randomUUID().toString());
return sr;
}
}
The model is just a simple POJO like
public class SimpleResponse {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Configuration is done like this
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
<display-name>SimpleTest</display-name>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
and
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="de.tum.ibis.wsc" />
</beans>
So thats the server side. On the client side I have a html page with just one line of jQuery code
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(document).ready(function() {
$.getJSON("http://localhost:8080/Frontend/app/new", function(data) { console.log("it works"); });
});
</script>
</head>
<body>
</body>
</html>
Now according to everything I have read this should work but it does not for me. If I call localhost:8080/Frontend/app/new directly in my browser I get something like this: {"id":"b46b8d67-5614-44ed-90ef-d2da14d260f6"} and Firebug tells me that the response header from the server is
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Server: Jetty(7.6.5.v20120716)
so content-type should be fine. Well if I now run the jquery ajax call I get the error "JSON.parse: unexpected end of data " in jquery.js and I have no cloue why. I hope anybody can help me with that. Thanks!
------ Update ------
Firebug: jQuery error
Firebug: All I get
Firebug: This is what I get if a access the url directly
Try configuring ContentNegotiationManagerFactoryBean in Spring XML config, see Spring docs
Set favorPathExtension to false and update method's #RequestMapping like so
#RequestMapping(value="/new", method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
In your AJAX request, you're using
http://localhost:8080/Frontend/app/new
And your servlet declares URL "/new", you should use "/app/new" instead.
#RequestMapping(value="/app/new", method=RequestMethod.GET)

Spring mvc configuration JSON

I would know how works the configuration about Spring MVC rest services that returns JSON.
I have configurated the applicationContenxt.xml in this way:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="contentNegotiatingViewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</list>
</property>
</bean>
<bean class="com.MyController"></bean>
And this is the code of my controller:
#Controller(value="MyController")
public class MyController {
#RequestMapping(value="/getValue", method=RequestMethod.GET)
public ModelAndView getValue() {
Map model = new HashMap();
model.put("asasa", "bbbbb");
model.put("cccc", "ddddd");
return new ModelAndView("jsonView",model);
}
}
I'm missing something about xml configuration or Java code? I have always error 404 while trying to invoke this resource: http://localhost:8080/fss/MyController/getValue
Just do:
#Controller
public class HelloController {
#RequestMapping(value="/hello", method=RequestMethod.GET)
public #ResponseBody String hello(#RequestParam String name) {
return "Hi " + name;
}
}
Change the return type to an object and include jackson in the classpath for an object response.
The request need to have a application/json header for the controller to return json.
Check out http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
And don't forget to add jackson converter to Spring context file.
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</mvc:message-converters>
</mvc:annotation-driven>
By the way - if your method accepts JSON, then use #RequestBody annotation with incoming data type:
#RequestMapping
public #ResponseBody OutgoingClass getJsonByJson(#RequestBody IncomingClass data) {...}
You can find nice examples of JSON and Spring MVC and more https://sites.google.com/site/upida4j/example