spring rest project with client side in angular js - how to approach the rest service with ajax - ajax

So I have a spring rest project that includes client side app.
I can run the service on a local tomcat and get responses querying "http://:8080/books" for example.
I can set app an apache server and go to "http://" to see my client app (the apache htdocs dir points to the project client app dir).
What I can't manage to do is send ajax rest queries to the service.
I'm using angular js so it looks like:
$http.get("http://:8080/books").success(...).error(...);
and it always enters the error callback method.
In the debugger/network tab I see that the request status is "canceled". Looking at the request's details I see next to the "Request headers" title the message: "CAUTION: Provisional headers are shown".
Here is my 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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Library Application</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.library.application</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>prod</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>BooksServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.library.service.config.ControllerConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BooksServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
My project structure is:
src
main
java
resources
webapp
resources
WEB-INF
test
Is it because the origin is different (mainly the port)?
Should I add some code to my web.xml to serve the client through tomcat? If so how?
thanks.

I guess you have a problem with cross-domain requests(yes, different port is another domain for the browser and it will cancel the request for security purposes if server will not include cross-domain headers). Try to add this headers to your REST response:
responseHeaders.add("Access-Control-Allow-Origin", "*");
if you need cookies you might need this as well:
responseHeaders.add("Access-Control-Allow-Credentials", "true");
in the second case you have to set an origin, '*' will not work in this case
more info here

Angular http uses relative urls.
For example using : www.stackoverflow.com
And
$http.get('/api/search?'
would call : www.stackoverflow.com/api/search
You can tests your rest api using your browser for gets requests, and one of the many plugins for post/put/delete.
(they are jsut made up urls btw)

Found it.
Thanks for all the answers, I was looking for the spring solution.
+1 JohnnyAW for your answer.
In my controller config class I've extended WebMvcConfigurerAdapter and overridden an addResourceHandlers method pointing to my client web app dir:
#Configuration
#EnableWebMvc
#ComponentScan("com.library.service")
public class ControllerConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Note that it works because configuration is annotated with #EnableWebMvc.

Related

Creating a route with Spring in Netbeans

I know this is a pretty basic issue, but I struggle hard with it...
I'd like to create a bunch of routes with the Spring framework in the Netbeans IDE, I have created a test #Controller class:
#Controller
public class HelloController {
#RequestMapping("/test")
public ModelAndView thisIsATest(HttpServletRequest request) {
return (new ModelAndView("myTestPage.jsp"));
}
}
myTestPage.jsp is a JSP file in the WEB-INF/jsp/ folder, and the HelloController class is in the Source Packages/ folder within a controller java package.
When I start the server, I can acces the root '/index.htm' that displays the index.jsp page (from the redirect.jsp file), but when I try to access '/test' or '/test.htm' I get a 404 error...
I really don't know how to make a Spring controller to work, and I did many tutorials without success.
In your applications web.xml make sure you have something like this. This will allow access to all your jsp pages. Add any other filters you may need here too.
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 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_3_0.xsd">
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>

Spring Websocket, 404 error while connecting. App not using Spring MVC

I'm trying to get working the Spring Example tutorial:
https://spring.io/guides/gs/messaging-stomp-websocket/
But I need it working on an existing Application that I need to add WebSocket support. The idea is once I get the basic working, start building from there.
The differences I have with the example in the URL is:
I'm not using SpringBootApplication, but Tomcat instead (7.0.69)
That implies I do have a web.xml (included below)
I skipped the Application.java with the main... I'm building a WAR and deploying it manually into Tomcat.
Whem I start Tomcat I read the following which seems relevant:
03:06:52,908 INFO SimpleBrokerMessageHandler:157 - Starting...
03:06:52,908 INFO SimpleBrokerMessageHandler:260 - BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
03:06:52,913 INFO SimpleBrokerMessageHandler:166 - Started.
The problem is the following:
When I click on connect on the index.html, I get a 404 when I'm trying to reach the server at the mapping url "/hello" (not sure why info is there, I guess is part of the protocol..) http://localhost:8080/hello/info
I was googling this, even found some answers in stackoverflow. Some have fixed this addding as prefix the DispatcherServlet mapping to the websocket url...
However my app isn't using Spring MVC, so I don't have a DispatcherServlet configured... and I looks like an overkill to include it just for the WebSockets.
I tried adding the annotation #EnableWebMvc to the WebSocketConfig class (in the link is the code, I have the same lines)
Any suggestion will be much appreciated !
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_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>App</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
I give up trying to avoid having an MVC Dispatcher for an APP witch doesn't use Spring MVC.
This solved it:
web.xml
<servlet>
<!-- Only used by websockets -->
<servlet-name>SpringMVCDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/websockets-application-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVCDispatcherServlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
And then, in the index.html I only added the prefix /ws/ when connecting (only there, sinding messages without the prefix is ok).

Jetty CORS works fine on Heroku with cometd but fails when cometd returns

I am running a Java app with Jetty-Runner on Heroku (let's call it Website A)
Then I have a Web app running on Website B, connecting to A using Cometd.
Comet connection stays open for 30 seconds and then it returns if no data is received from the server.
I have setup CORS parameters on Jetty's web.xml so that B accesses A with no problem.
Now the problem: if the comet's 30 seconds finishes and the server does not return anything, then the browser throws this error:
XMLHttpRequest cannot load [Website A]/cometd.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin '[Website B]' is therefore not allowed access.
I am running the same Java Application using Embedded Jetty on another Website (Website C) with the same CORS settings and everything works fine. In particular, when comet connection returns after 30 seconds, the response has all the headers including the 'Access-Control-Allow-Origin'. But, on Website A, after comet returns, the response do not have the headers.
So, to me, the problem is caused by Jetty-Runner not returning a response after 30 seconds, versus embedded jetty returning the response with correct headers.
My web.xml content:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
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">
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>[Website B]</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,DELETE,PUT,HEAD,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>origin, content-type, cache-control, accept</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometdServlet</servlet-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>timeout</param-name>
<param-value>30000</param-value>
</init-param>
<init-param>
<param-name>jsonDebug</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--
To use async-supported in a servlet 3.0 compliant container,
uncomment the following tag:
<async-supported>true</async-supported>
and change the web-app tag of this document to:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
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_3_0.xsd"
version="3.0">
-->
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>admin</servlet-name>
<servlet-class>org.coweb.servlet.AdminServlet</servlet-class>
<load-on-startup>2</load-on-startup>
<init-param>
<param-name>ConfigURI</param-name>
<param-value>/WEB-INF/cowebConfig.json</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>admin</servlet-name>
<url-pattern>/admin/*</url-pattern>
</servlet-mapping>
</web-app>
Any idea how to fix this probem?
If A does not send the Access-Control-Allow-Origin header for B but it does for C, perhaps your CORS configuration is wrong ?
You did not specify how you have configured CORS on A (are you using Jetty's CrossOriginFilter ?).
I see no reason why Jetty Runner (which is just a Jetty embedded that deploys your war) should mess with the CORS configuration of a web application ?

Spring MVC but without a view resolver?

is it possible to use Spring 3.1 MVC without using a view resolver?
The reason why i ask is because i simply want to build and create a Web service, not a Website so i do not need to render any JSP or html pages at all. I want to build a RESTful Web service using Spring 3.1.
Is this possible?
this is how my servlett looks like which is taken from a tutorial:
Here is my mvc-config.xml
Here is my Web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>FreedomSpring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>FreedomSpring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
And here is my controller java class that simply want to return a String from a specific http REST request and not a "ModelAndView" object so to speak
package com.jr.freedom.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class Hello {
#RequestMapping(value = "/hello", method = RequestMethod.GET)
public String helloWorldInJson() {
return "hello";
}
}
Also, How can i capture a requests Parameters that a client may send me? is that possible using springs annototations? i know that i can in previous Spring 2.x use HttpServletRequest and HttpServletResponse to get any parameters sent from a client and also return a object back to the user as well such as a JSON object.
i am just looking for a simple example that does this:
Get parameters and possibly HTTP headers from a clients Request on my controller class and map them to some Java object "example, a client sends me details of a new user object registering to my backend service(username, password etc etc) and i want to be able to map this to my Java class Called User"
Return a response of any kind of object such as a String, json or xml data to a client.
Im quite new to Spring 3.0. i did a bit of work on Spring 2.0 long ago but annotations seems the way to go now and do not know how to do it via annotations.
Thanks
Also, To execute the above controller method of helloWorldInJson() do i simply call http://localhost/FreedomSpring/hello ?
You generally use #ResponseBody for this.
See 16.3.3.5 Mapping the response body with the #ResponseBody annotation.
This bypasses the view resolver stuff altogether.
use #RestController instead of #Controller.
This page shows what you want to achieve.
You would use the #PathVariable annotation to inject parameters encoded in the url as method parameter. If the parameters are in the post or the get, then you would use #RequestParam instead.
This doc also explain how to use a view resolver to marshall your model (set by your controller) into any format.
Yes, you can do. I just created spring mvc showcase project. you can find source code here.
https://github.com/mohansaravanan/spring/tree/master/springmvc-3.2.2
You may like this project!

Spring 3, Flex 4 Integration with SpringFlex 1.5.0.M2 api + configuration

We are working on a project where we are using Spring 3 to create a web platform and using Flex 4 to create a specific client side application. Currently, we need to integrate Spring project with Flex.
We are using Spring-Flex integration library version: 1.5.0.M2
I checked the older questions but the integration configurations defined at those entries are generally for previous versions of BlazeDS and Spring. And as I understad, there may be some differencies.
Can anybody tell me how to do the configuration in web.xml and any other xml files needed,and how the folder structures will be. Any up-to-date tutorial links will be appreciated.
Our business requirements are:
Two servlets should exist: 1) projectServlet that has mappings /.html
2) flexServlet that has mappings /messageBroker/
Our service classes that can be used in Flex side will be like:
package com.ecognitio.service;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.flex.remoting.RemotingInclude;
import org.springframework.stereotype.Service;
#Service
#RemotingDestination
public class Foo {
#RemotingInclude
public void sayHello(String name){
System.out.println("Hello: "+name);
}
}
Regards,
Ugur
My Flex 4, Hibernate 3, and Spring 3 Integration Refcard walks through the process of setting everything up and should work fine with 1.5.0.M2 (assuming you have changed the namespace in the Spring config file). But here is a basic web.xml example:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns
/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Project Template</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</liste
ner-class>
</listener>
<listener>
<listener-class>flex.messaging.HttpFlexSession</listener-class>
</listener>
<servlet>
<servlet-name>flex</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flex</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
</web-app>
That should be enough to get you started.

Resources