I created a Java Spring MVC web app which offers simple restful services.
And I have the object class like this..
public class CreateEventWrapper {
private String Topic;
private String SubscriptionReference;
private Date UtcTime;
private List<Message> Messages;
...
}
public class Message {
private List<Source> Source;
...
}
public class Source {
private String Name;
private String Value;
...
}
The controller:
...
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping(produces = "application/json")
class EventController {
#RequestMapping(value = "/event", method = RequestMethod.POST)
public ResponseEntity<CreateEventWrapper> CreateEvent(#RequestBody CreateEventWrapper eventWrapper) {
return new ResponseEntity<CreateEventWrapper>(eventWrapper, HttpStatus.OK);
}
}
And I have the json format file using Postman to upload to the server.
The upload function works fine.
{
"topic":"Face",
"subscriptionReference":"http:\\abc",
"utcTime":"2016-10-20T19:00:00Z",
"messages":[{
"source":[{"name":"VideoSource","value":"[1]123.avi"},
{"name":"AnalyticEngine","value":"FacialRecognition"}]
}]
}
I expect the format will be the same with the object order in the class
something like topic, subscriptionReference, utcTime, orderm, message..
but I got the output with message, subscriptionReference, utcTime, topic..
{
"messages": [
{
"source": [
{
"name": "VideoSource",
"value": "[1]123.avi"
},
{
"name": "AnalyticEngine",
"value": "FacialRecognition"
}
]
}
],
"subscriptionReference": "http:\abc",
"utcTime": 1476990000000,
"topic": "Face"
}
Can I have the specific order just like the class object order?
Attach with my spring config and porm.xml for reference.
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" xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx" 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.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-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<!-- Activates annotation-based bean configuration -->
<context:annotation-config />
<!-- Scans for application #Components to deploy -->
<context:component-scan base-package="org.itri.ccma.paas.service.event.webservice" />
</beans>
porm.xml
...
<!-- Json lib -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.1</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.4.2</version>
</dependency>
<!-- Springframework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
...
You shall try this
//lower cases since it affects the json output not the class field names
#JsonPropertyOrder({ "topic", "subscriptionReference", "utcTime", "messages" })
public class CreateEventWrapper {
private String Topic;
private String SubscriptionReference;
private Date UtcTime;
private List<Message> Messages;
...
}
And I suggest you to use lowerCamelCase naming variables convention in your code since its most popular
Related
I'm using spring-5.0.3
http://localhost:8080/firstapp_spring/greeting
HTTP Status 500 - Internal Server Error
type Exception report
messageInternal Server Error
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: No adapter for handler [com.actions.GreetingController#4275cbe5]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
There is no error during building project.
pom.xml =>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
class=>
package com.actions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
#Controller
public class GreetingController {
#RequestMapping(value = "/firstapp_spring/greeting", method = RequestMethod.GET)
public String greetingForm(Model model) {
model.addAttribute("greeting", new Greeting());
return "greeting";
}
#RequestMapping(value = "/firstapp_spring/greeting", method = RequestMethod.POST)
public String greetingSubmit(#ModelAttribute Greeting greeting) {
return "result";
}
}
app-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-3.0.xsd">
<!-- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.ftl</value>
</property>
</bean>
<bean name="/hello" class="com.actions.HelloController"></bean>
<bean name="/greeting" class="com.actions.GreetingController"></bean>
</beans>
The request mapping that you've defined in your Controller class is:
#RequestMapping(value = "/firstapp_spring/greeting", method = RequestMethod.GET)
and the URL you're trying to access is:
http://localhost:8080/myproject/greeting
You're missing the "/firstapp_spring" part.
Since you're using Spring > 4.3 you can take advantage of the new HTTP mapping annotations: #GetMapping and #PostMapping
Your request mapping can become, the much shorter equivalent:
#GetMapping("/firstapp_spring/greeting")
When I run the main class then this error pop up. I have checked most of the links for this issue but couldn't solve the problem. Please check the following files to get some idea about the problem Thanks in advance.
# bean.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" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:property-placeholder
location="com/springproject/test/springtest01/props jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<context:component-scan
base-package="com.springproject.test.springtest01">
</context:component-scan>
</beans>
#pom.xml#
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springproject.test</groupId>
<artifactId>springtest01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springtest01</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
</dependencies>
</project>
#NoticesDao#
package com.springproject.test.springtest01;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
#Component("noticeDao")
public class NoticesDAO {
private JdbcTemplate jdbc;
#Autowired
public void setDataSource(DataSource jdbc) {
this.jdbc = new JdbcTemplate(jdbc);
}
public List<Notice> getNotices() {
return jdbc.query("select * form notices", new RowMapper<Notice>() {
public Notice mapRow(ResultSet rs, int rowNum) throws SQLException {
Notice notice = new Notice();
notice.setId(rs.getInt("id"));
notice.setName(rs.getString("name"));
notice.setEmail(rs.getString("email"));
notice.setText(rs.getString("text"));
return notice;
}
});
}
}
#jdbc.properties#
jdbc.username = root
jdbc.password = 123456
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/springtutorial
#Main#
public class App
{
public static void main( String[] args )
{
try{
ApplicationContext context = new ClassPathXmlApplicationContext("com/springproject/test/springtest01/beans/beans.xml");
NoticesDAO noticesDAO = (NoticesDAO) context.getBean("noticeDao");
List<Notice> notices = noticesDAO.getNotices();
for(Notice notice: notices){
System.out.println(notice);
}
((ClassPathXmlApplicationContext)context).close();
}catch(Exception e){
System.out.println("==========="+e);
}
}
}
First, your SQL request is invalid, it should be select * FROM notices not FORM.
Second, I didn't manage to get the same error as you. In fact, I could not even make the application context to find the bean.xml and jdbc.properties files with your current configuration. I changed some configuration as follows:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
and
<context:property-placeholder location="jdbc.properties" />
put the files in a main/resources directory, then built and successfully ran the project with
mvn clean compile
mvn mvn exec:java -Dexec.mainClass="com.springproject.test.springtest01.App"
I've been fighting with the Spring framework for few weeks now, and I got
a normal MVC page to show up, and I got JDBC to print onto the console.
But I can't seem to get these to work together...
I've been through countless tutorials at this point and every one of them
seem to have some type of error or problem.
I think I've finally managed to get together a pretty decent and working build, but nope, still getting only 404's.
I think the problem might be in the spring-servlet.xml file:
<context:component-scan base-package="src" />
And I'm not sure if you can even load project like that, but it's the only thing I can think of here.
I include all the other files too, though.
Console Errors
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:spring-mvc' did not find a matching property.
and
SEVERE: Servlet [spring] in web application [/spring-mvc] threw load() exception
java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1275)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1109)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:520)
at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:501)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1050)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:989)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4903)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5213)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-mvc</groupId>
<artifactId>spring-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.8</java.version>
<spring.version>3.1.0.RELEASE</spring.version>
<cglib.version>2.2.2</cglib.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.gatein.common</groupId>
<artifactId>common-logging</artifactId>
<version>2.2.2.Final</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.8.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
</dependencies>
</project>
spring-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" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Telling container to take care of annotations stuff -->
<context:annotation-config />
<!-- Declaring base package -->
<context:component-scan base-package="controller" />
<!-- Adding view resolver to show jsp's on browser -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Declare beans -->
<bean id="userDao" class="dao.UserDaoImpl" />
<bean id="userService" class="services.UserServiceImpl" />
<!-- Declare datasource bean -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/userdb" />
<property name="username" value="root" />
<property name="password" value="38613861" />
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>SpringJDBCTemplate</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
homePageController
package controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import domain.*;
import services.*;
#Controller
public class HomePageController {
#Autowired
UserService userService;
#RequestMapping("/register")
public ModelAndView registerUser(#ModelAttribute User user) {
List<String> genderList = new ArrayList<String>();
genderList.add("male");
genderList.add("female");
List<String> cityList = new ArrayList<String>();
cityList.add("delhi");
cityList.add("gurgaon");
cityList.add("meerut");
cityList.add("noida");
Map<String, List> map = new HashMap<String, List>();
map.put("genderList", genderList);
map.put("cityList", cityList);
return new ModelAndView("register", "map", map);
}
#RequestMapping("/insert")
public String inserData(#ModelAttribute User user) {
if (user != null)
userService.insertData(user);
return "redirect:/getList";
}
#RequestMapping("/getList")
public ModelAndView getUserLIst() {
List<User> userList = userService.getUserList();
return new ModelAndView("userList", "userList", userList);
}
#RequestMapping("/edit")
public ModelAndView editUser(#RequestParam String id,
#ModelAttribute User user) {
user = userService.getUser(id);
List<String> genderList = new ArrayList<String>();
genderList.add("male");
genderList.add("female");
List<String> cityList = new ArrayList<String>();
cityList.add("delhi");
cityList.add("gurgaon");
cityList.add("meerut");
cityList.add("noida");
Map<String, Object> map = new HashMap<String, Object>();
map.put("genderList", genderList);
map.put("cityList", cityList);
map.put("user", user);
return new ModelAndView("edit", "map", map);
}
#RequestMapping("/update")
public String updateUser(#ModelAttribute User user) {
userService.updateData(user);
return "redirect:/getList";
}
#RequestMapping("/delete")
public String deleteUser(#RequestParam String id) {
System.out.println("id = " + id);
userService.deleteData(id);
return "redirect:/getList";
}
}
Project tree
Project tree from Eclipse Neon2
Not my answer but the one which solved the case, posting as answers since it's buried deep in comments.
Sorry for the delay.... It still not right. I know that because
Eclipse should not show the package as main.java.controller.... Maven
ignores that folder and start right under the java folder as it was
the src folder itself. Something must be wrong on your project. Try
cleaning everything, remove the project from eclipse, delete
(physically) the folder .settings and the file .classpath and the file
.project. Go on your folder project on the console and run mvn clean
eclipse:clean then open all folders of if (like the image I showed to
you) and paste it here so I can see what it is wrong
– Jorge Campos
I am creating a spring boot application based on an assignment in an online MOOC. The course is over and I am just trying the assignment on my own.
THis is my pom.xml file:
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples.service.service</groupId>
<artifactId>VideoManagerServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Web -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- Spring -->
<spring-framework.version>3.2.3.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<!-- Other Web dependencies -->
<!-- Spring and Transactions -->
<!-- Logging with SLF4J & LogBack -->
<!-- Hibernate -->
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
THis is my controller:
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.hakeem.videoserver.model.Video;
import com.hakeem.videoserver.service.VideoService;
#RestController
#RequestMapping(value="/api",consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
public class VideoController {
#Autowired
VideoService videoService;
#RequestMapping(value="/add",method=RequestMethod.POST)
public void addVideo(#RequestBody Video video){
videoService.addVideo(video);
}
#RequestMapping(value="/all",method=RequestMethod.GET)
public #ResponseBody ArrayList<Video> getAllVideos(HttpServletResponse response){
ArrayList<Video> videos;
videos = videoService.getAllVideos();
if(videos.size() == 0){
response.setStatus(HttpStatus.NO_CONTENT.value());
}
return videos;
}
#RequestMapping(value="/delete",method=RequestMethod.DELETE)
public void deleteVideo(#RequestBody Video video){
videoService.deleteVideo(video);
}
#RequestMapping(value="/find/{id}")
public #ResponseBody Video findVideo(#PathVariable int id, HttpServletResponse response){
return videoService.findVideo(id);
}
#RequestMapping(value="/testing",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody int testEndPoint(HttpServletResponse response){
return 10;
}
}
The problem is my addVideo endpoint only works when I annotate with #RestController but not when I annotate with #Controller.
However my testEndpoint method works when I annotate with #RestController and #Controller
However if I add #ResponseBody to the Class or the addVideo method then it works.
Using the Postmat plugin on Chrome, when I send the following Post Request:
http://localhost:8080/api/add
With this body for a video:
{
"id":1,
"title":"test",
"contentType":"test1",
"dataUrl":"testurl",
"starRating":"5",
"duration":7
}
I get this message in Postman:
{ "timestamp": 1440349612613,
"status": 405,
"error": "Method Not Allowed",
"exception":"org.springframework.web.HttpRequestMethodNotSupportedException", "message": "Request method 'POST' not supported", "path": "/api/add"
}
And this message in my eclipse console:
WARN PageNotFound - Request method 'POST' not supported
But the video is add and can be retrieved without any errors if I had #ResponseBody to the class or the method return type.
Therefore the main question is:
Why do I need to add #ResponseBody if the addVideo is not returning anything.
There were two questions asked here:
Why #RestController works, but #Controller does not?
If you check the documentation, you will see that RestController is
A convenience annotation that is itself annotated with #Controller
and #ResponseBody.
Why do you need to add #ResponseBody if the return type is void?
The reason for this is that even if there is no actual value you want to return, there will be a response sent to the client (at least an HTTP OK). For this reason you need to use one of these:
#ResponseBody
#ResponseStatus(value = HttpStatus.OK)
I am working on a basic Hello World program using Spring and Restful webservices. But when I try to call my service I am getting below error message:
HTTP Status 406 -
description - The resource identified by this request is only capable
of generating responses with characteristics not acceptable according
to the request "accept" headers.
Here is my web.xml file's servlet mapping:
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Here is my spring web configuration file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="hello" />
<mvc:annotation-driven />
<!-- Map returned view name "rssViewer" to bean id "rssViewer"
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
-->
<bean id="xmlViewer"
class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>hello.Greeting</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</beans>
Here is my Maven pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.examples</groupId>
<artifactId>WebServices1</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>WebServices1 Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.1.6.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- for compile only, your container should have this -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
</dependencies>
<build>
<finalName>WebServices1</finalName>
</build>
</project>
Here is my controller:
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping("/greeting")
public Greeting greeting(#RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
This is my Greeting pojo class:
package hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
When I deploy my application and access the URL as http://localhost:8081/WebServices1/rest/greeting, I am getting HTTP 406 error message in browser.
update:
As per my mozilla firebug plugin, here are my headers for request:
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding
gzip, deflate
Accept-Language
en-US,en;q=0.5
Cache-Control
max-age=0
Connection
keep-alive
Cookie
JSESSIONID=9B49E7A23D6CDE85CAC4152E22834D35; textwrapon=false; textautoformat=false; wysiwyg=textarea
; m=34e2:|2663:t|c01:t|5cf4:t|4a01:t|54e1:t
Host
localhost:8081
User-Agent
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Response Headers:
Content-Language
en
Content-Length
1067
Content-Type
text/html;charset=utf-8
Date
Mon, 22 Jun 2015 11:00:08 GMT
Server
Apache-Coyote/1.1
The issue is with the dependencies that you have in pom.xml file.
In Spring 4.1.* version the pom.xml dependency for Jackson libraries should include these:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.1</version>
</dependency>
You can get more details in these posts:
Spring JSON request getting 406 (not Acceptable) - Answer given by bekur
and also here:
406 Spring MVC Json, not acceptable according to the request "accept" headers
Also FYI, your code will work if you change the spring version back to 4.0.* or anything else.