Issue in running Spring Restful web services without Spring Boot - spring

I am trying to build Restful web services. My Maven project name is rest and I am following Spring's Building a RESTful Web Service to do that but I don't want to use Spring Boot but just create a war and host it on Tomcat in my eclise/STS. Here are my web.xml and XX-servlet.xml files:
web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
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-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.rest" />
<mvc:annotation-driven/>
</beans>
GreetingController.java
#RestController
public class GreetingController2 {
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("Hello %s", name));
}
}
when I run this on Tomcat the URL: http://localhost:8080/rest gives 404 and I see this message in tomcat console Aug 16, 2017 3:59:28 PM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/rest/] in DispatcherServlet with name 'rest'
whereas I do have the mapping.
And when I hit http://localhost:8080/rest/greeting I get http 406 with message The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers. whereas as per the tutorial it should be converted to JSON which can be rendered in the browser.
I spent a lot of time trying to figure out and looking at various posts on SO to find what's wrong but could not.

You dont have a default mapping like
#RequestMapping("/")
As per your code above you should have below url working fine
http://localhost:8080/rest/greeting

Related

Spring MVC #GetMapping("") is executed three times in the first request

I've been working with Spring, I don't understand what the problem is. In the Test.class Spring MVC controller the code (the default controller, the first request will receive it) in the get request the code is executed three times this method includes 3 threads or 3 get requests.
Synchronized method and SingleThreadModel interface don't help, so I think the problem is with three requests?
If I execute the code in a different controller (not in the default fetch request) everything works good.
Test.class
#Controller
public class Test {
#GetMapping("")
public String hello(ModelMap model) {
System.out.println("method hello said 'yes'"); //runs twice
return "index";
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>Spring MVC</display-name>
<servlet>
<servlet-name>PredictWeather</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servletsConfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PredictWeather</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
servletsConfig.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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="servlets"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
logs
Perhaps someone has come across, or knows how to solve the problem, thanks for any answer! I ask the question for the first time, perhaps it is poorly formulated

No mapping found for HTTP request with URI [/FitnessTracker/]

I am getting an warnning in springmvc
as No mapping found for HTTP request with URI [/FitnessTracker/] in DispatcherServlet with name 'fitTrackerServlet'
INFO: FrameworkServlet 'fitTrackerServlet': initialization completed in 2194 ms
Feb 26, 2017 9:43:08 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/FitnessTracker/] in DispatcherServlet with name 'fitTrackerServlet'
When i press url http://localhost:8080/fitnessTracker/ I am getting 404 error.
Thanks
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>fitTrackerServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>fitTrackerServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<display-name>Archetype Created Web Application</display-name>
</web-app>
and my servlet-config.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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
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">
<mvc:annotation-driven />
<context:component-scan base-package="com.pluralsight.controller"></context:component-scan>
<!--
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>
and my controller
#Controller
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello (Model model) {
System.out.println("Test");
model.addAttribute("greeting", "Hello WorldX");
return "hello";
}
}
Does your component-scan base-package match the package where your HelloController is in? If not, that is the problem.
<context:component-scan base-package="com.pluralsight.controller"></context:component-scan>
Configures component scanning directives for use with #Configuration
classes. Either basePackageClasses() or
basePackages() (or its alias value()) may be specified to define
specific packages to scan.
Spring does not find your HelloController and so doesn't map anything.
Otherwise you could also follow these steps.
I am wondering why you have you application configured with XML. With this tool you can start a maven project with a Spring boot application that will be, by default, already configured to build exactly what you want.
Then you only need a class with:
#RestController
#RequestMapping("/fitnessTracker")
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello (Model model) {
System.out.println("Test");
model.addAttribute("greeting", "Hello WorldX");
return "hello";
}
}
And that's it, Spring will do the rest for you ;)
In my case the problem was that i was using this url-pattern
<url-pattern>/*</url-pattern>
instead of this
<url-pattern>/</url-pattern>
and also i had to add
#RequestMapping(value = "/fitnessTracker")
under the
#Controller
annotation.
I found the solution at : https://www.baeldung.com/spring-mvc-404-error for the pattern.

Spring MVC 4.0 RESTFul Web Services

I am trying to build a hello world restful web service with the help of spring mvc 4.0 framework. I created a dynamic web application added web.xml , rest-servlet.xml and MyController.java file in a package mythird.attempt.sample.controller.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>My sample rest</display-name>
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
rest-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="mythird.attempt.sample.controller" />
<mvc:annotation-driven />
</beans>
MyController.java
package mythird.attempt.sample.controller;
import org.springframework.web.bind.annotation.PathVariable;
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;
#RestController
#RequestMapping("/myfirst")
public class MyController {
#RequestMapping(value = "/{name}", method = RequestMethod.GET)
public String getGreeting(#PathVariable String name) {
String result="Hello "+name;
return result;
}
#RequestMapping(value="/qq", method = RequestMethod.GET)
#ResponseBody
public String getGreeting1() {
String result="Hello world";
return result;
}
}
I tried deploying this on both apache tomcat and glassfish.
When i hit the url "localhost:8080//.../myfirst/asdf in the browser
Glassfish gave warnings like
"No mapping found for HTTP request with URI [/myfirst/asdf] in DispatcherServlet with name.."
And gave a dialog with details and ok , on clicking details
it gives
System.Deployment.Application.InvalidDeploymentException (ManifestParse)
- Exception reading manifest from localhost:8080/TestApache1/myfirst/kk: the manifest may not be valid or the file could not be opened.
- Source: System.Deployment
- Stack trace:
at System.Deployment.Application.ManifestReader.FromDocument(String localPath, ManifestType manifestType, Uri sourceUri)
Please help me out here!!. thanks in advance!!
I think the url should be "localhost:8080/{warname}/rest/myfirst/asdf
The web.xml says that the servlet will kick in for all url's that have a "rest" path in it, i do not think you are using that in your sample attempts
Got the solution..
Things started working fine when i used the normal browser instead of embedded browser in my eclipse.
Thanks!

RequestMapping in spring mvc

I am trying to understand requestmapping in spring mvc, I have an application, actually I am just getting started with spring mvc.
I have these two urls
The first one with a forward slash at the end seems to be working fine.
http://localhost:8080/contactmanager/index/
The second one without a forward slash at the end does not work
http://localhost:8080/contactmanager/index
This second one gives me the 'HTTP Status 404 -' error, how can I force the application to be appending a forwards slash at the end of the url?
The method in the controller looks like this
#RequestMapping("/index")
public String listContacts(Map<String, Object> map) {
map.put("contact", new Contact());
map.put("contactList", contactService.listContact());
//org.springframework.web.context.ContextLoaderListener
//org.springframework.web.context.ContextLoaderListener
//org.springframework.web.servlet.DispatcherServlet
//org.springframework.web.servlet.DispatcherServlet
return "contact";
}
and my web.xml looks like this
<servlet>
<servlet-name>contactmanager</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/contactmanager-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>contactmanager</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Thanks in advance.
Using java configuration:
#Configuration
#EnableWebMvc
public class WebConfig {}
or using XML configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
From Spring's reference documentation:
The above registers a RequestMappingHandlerMapping, a
RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver
(among others) in support of processing requests with annotated
controller methods using annotations such as #RequestMapping ,
#ExceptionHandler, and others.
In RequestMappingHandlerMapping there is useful boolean flag - decription from Javadoc:
/**
* Whether to match to URLs irrespective of the presence of a trailing slash.
* If enabled a method mapped to "/users" also matches to "/users/".
* <p>The default value is {#code true}.
*/
public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) {
this.useTrailingSlashMatch = useTrailingSlashMatch;
}
Since this is enabled by default just make sure that your configuration uses RequestMappingHandlerMapping.
If this doesn't help you, check that spring's default servlet is configured: <mvc:default-servlet-handler/> and try add to web.xml
<!-- Disables Servlet Container welcome file handling. Needed for compatibility with Servlet 3.0 and Tomcat 7.0 -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>

spring destroy-method + request scope bean

So I wanted to do something like this:
#Component
#Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public class MyBean {
#Autowired HttpServletRequest request;
#PreDestroy
public void afterRequest() {
try {
System.out.println("After request...");
// use request here:
}
finally {
System.out.println("Completed successfully...");
}
}
}
And I end up with the following message, AFTER the "Completed successfully..." message logs:
09:19:16 WARN Invocation of destroy method failed on bean with name 'scopedTarget.myBean': java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
I'm not really sure what to make of this, since my logging indicates the destroy method completed successfully. Does anyone know what's going on?
EDIT:
Here's the mvc-servlet.xml. As you can see there is not much going on here. It's all annotation driven:
<?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" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<!-- properties file -->
<context:property-placeholder location="app.properties" />
<context:component-scan base-package="my.package.web" />
<context:component-scan base-package="my.package.services" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/view" p:suffix=".jspx" />
</beans>
If you use request scope without spring MVC you should declare org.springframework.web.context.request.RequestContextListener in web-app listener.
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
check http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-web-configuration
I never did get this working, but I ended up changing the code to apply #After advice on the controller methods, which has the same effect.

Resources