Invoking a spring web service - java

I'm trying to invoke a spring web service, using below url in browser the service "myservice" should return XML, ie based on the #RequestMapping annotations is the below URL correct?
> http://localhost:8080/mywebapp/myservice/feeds/allFeeds.xml/
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping("myservice")
public class TheController {
private TheService TheServiceWS;
public TheController(TheService TheServiceWS) {
this.TheServiceWS = TheServiceWS;
}
#RequestMapping(value = "feeds/allFeeds.xml", produces = MediaType.APPLICATION_XML_VALUE)
#ResponseBody
public String getValues() {
return TheServiceWS.getAllFeeds();
}
}

The problem for me was :
The #RequestMapping annotation value "myservice" was incorrect
should have been "mywebservice"

If the web service return as XML, it is the original the SOAP web service. In this case, you couldn't build the web service with #RequestMapping. The #RequestMapping is used when you want to build a REST web service.
In this case, you should use the Spring WS. You have to annotate the class with #Endpoint to create an web service endpoint. In the this endpoint, you create your request mapping with #Payloadroot. Please refer to this

Related

#RefreshScope Annotation return an empty data

I Was following this tutorial on YouTube I have been able to successfully run the config server where I host two properties files here File hosted. and on the client side when I tried to consume the value I get an empty response here is the dummy controller I have created.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/test")
#RefreshScope
public class TestController {
#Value("${test.name}")
private String product;
#GetMapping
public String test() {
return product;
}
}
but when I send a get request to route /api/test, I get a response of 200OK with no actual test value. name, What am I doing wrong?.
The tutorial in youtube uses the default naming convetion but you probably have changed it and now spring cloud config server does not know which property file expects your service to have.
In cloud config server the file is saved as product.properties.
For this reason if your client service has some other name, this will not work. To correct it go to the client application and in bootstrap.yaml add the property spring.application.name: product.

Getting data from Swapi API https://swapi.co/api/people/ using spring boot

when I use the RestTemplate and the Getforobject() method I get an error 500 code when running my spring boot. How can I consume this API using springboot?
package nl.qnh.qforce.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
#RestController
public class PersonController {
private static String url = "https://swapi.co/api/people/";
#Autowired
private RestTemplate restTemplate;
#GetMapping("/people")
public List<Object> getPeople(){
Object[] people = restTemplate.getForObject(url, Object[].class);
return Arrays.asList(people);
}
}
I would advise first checking if manually calling provided url returns expected response. You can use curl, postman or any other similar tool. In case call on provided url returns response, provide us with more context from your application, so we can assess which part is responsible for 500 error.

How to identify whether web service is REST or SOAP?

I am learning spring MVC and have wrote following code. I read some articles about SOAP and REST but in the beginner level controller code I have written I am not able to distinguish whether SOAP or REST is used. My controller code is as follows:
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.model.Customer;
#Controller
public class SelectController {
#RequestMapping("/")
public String display(){
System.out.println("Inside controller");
return "demo";
}
#RequestMapping("/index")
public String indexpage(HttpServletRequest req, Model m){
String name = req.getParameter("name");
String pass = req.getParameter("pass");
String random = req.getParameter("abc");
System.out.println("Index page"+name+pass+random);
Customer cust = new Customer();
cust.setUsername(name);
cust.setPassword(pass);
System.out.println("Index page"+name+pass);
m.addAttribute("customer", cust);
return "hello";
}
The Controller that you have written is
neither REST nor SOAP.
Its a MVC Controller.
In your case, your returning "hello" string at the end of controller method, which in-turn gets translated/mapped to a page(hello.jsp or hello.html based on the configuration) and returns the same. So, at the end, what you get is Page rendered in a beautiful way with all the necessary Stylings and scripts applied.
In contrast, REST and SOAP doesn't work in that way. Its main purpose is for transferring the data alone(Yet you can send HTML page also)
Writing a REST Service is almost similar to what you have currently and is fairly easy. If you use Springboot then all you have to do is just replace the #Controller annotation with #RestController and return Customer object directly. In REST Controller you wont have HttpServletRequest & Model arguments.
But writing a SOAP service is another topic which may seem entirely different.
There are tons of examples and tutorials scattered around the web, which you can find easily on these topics.
References :
Controller vs RestController in Spring
Difference between Controller & RestController in Spring
SOAP vs REST
Hope this gives some high level idea of what those three are.

404 on jQuery AJAX request in Spring boot

I have recently created a Spring boot project and am trying to work with jQuery AJAX to get data from Controller in Spring. It returns 404 for some reason.
My controller
import java.util.ArrayList;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HomeController {
#RequestMapping(value="/", method=RequestMethod.GET)
public String loadHome() {
return "index";
}
#RequestMapping(value="/getMajors", method=RequestMethod.GET)
public ArrayList<String> getMajors(){
ArrayList<String> majors = new ArrayList<>();
majors.add("Computers");
majors.add("Physics");
return majors;
}
}
The first method was to load the home page index.html the second was the method that maps to AJAX request.
My jQuery AJAX Request
$.ajax({
type:"get",
url:"/getMajors",
success:function(data){
console.log(data);
},
error:function(data){
console.log(data);
}
});
Please tell me why I'm getting a 404 here. TIA.
Edit: This app was created in Springboot. Standard config with web, dev-tools packages - from spring initializer.
I guess you are missing two things. One is the context name which usually is the name of the project or the war file deployed to the server, unless you are providing another context in web.xml. A sample servlet mapping from web.xml file:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
So when your ajax call hits /getMajors it usually points to "localhost:port/getMajors" instead of say "localhost:port/sampleproj/getMajors" .You are missing the context there.
So your method needs to look like this:
#RequestMapping(value = "/getMajors", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ArrayList<String> getMajors(){
ArrayList<String> majors = new ArrayList<>();
majors.add("Computers");
majors.add("Physics");
return majors;
}
One good method to debug these is to see the developer console(Chrome) for request response information.
Happy Coding!
Edit 1: removing #ResponseBody from method as the class is annotated with #RestController. But my statement stands correct in case the class is annotated with #Controller.

Integrating GWT with Spring

I know that this topic was discussed many times, but I found that the most of information on this is not up to date.
I am looking for tutorial/example on how to integrate GWT with Spring framework.
I have found many examplex (some of them even working), but only with older libraries. I am looking for a solution with newest libraries (or at least compatible with the newest).
Also many examples use spring4gwt library (for creating "glue" servlet) - is there another way?
I want to create simple example application using GWT + Spring + Hibernate + Maven. I started by creating Web Application Project (from Eclipse). I converted project to Maven project. And to be honest I am stuck here. I can create simple service (+ async), but have no idea how to configure proper servlet and go further. Examples I found relay on spring4gwt, but I would like not to use it (no new version since 2009 I think).
It would be great if someone could explain integration step-by-step.
Sorry if this one is a duplicate, but after long search I haven't found clear solution that suits my needs.
You have many ways to integrate with Spring, but i think the best option is use RestyGWT Framework
Since you are using HTTP protocol and JSON format for serializing objects, you won't have problem to comunicate with the Spring Controllers using RestyGWT.
You could also use your own controllers to respond to GWT RPC Requests. Instead of using GWT Dispatcher, you use the Spring MVC Request Dispacher and map the URLS on controllers to your services in GWT client.
if you use the RESTY GWT API, you could just write your interface, map the methods using JAX-RS annotations like #POST, #GET, #DELETE, #PathParam, etc.
Here's what I'm doing on my project using RestyGWT:
The project is compose of 2 projects:
project-client
project-server
The client contains all files related to GWT and RestyGWT.
The server contains all files from the back end implementation using Spring.
Maven overlay is used to merge the 2 projects on the package compile phase, so you end with a final war with the GWT *js files and the server files.
To use RestyGWT you have to create an interface who extends RestService:
public interface MyRestService extends RestService{
#GET
#Path("/foo")
public void getFoo(MethodCallback<List<Foo>);
#POST
#Path("/foo")
public void saveFoo(Foo foo ,MethodCallback<MessageResponse>);
}
To use the service you write something like this:
MyRestService service = GWT.create(MyRestService.class);
and you will have something like this to use the service:
service.getFoo(new MethodCallBack<List<Foo>>(){
public void onSucess(List<Foo> foos){
/* You will get foos, you dont have to worry about serialization, RESTYGWT does it for you */
}
public void onError() ...
});
And you will have a controller to respond to this request like this:
#Controller
class myController{
#Autowired FooService svc;
#RequestMapping(value = "/foo", method = RequestMethod.GET, produces= "application/json")
public #ResponseBody List<Foo> getAllFoos(){
return svc.all();
}
#RequestMapping(value = "/foo", method = RequestMethod.POST, produces= "application/json", consumes="application/json")
public #ResponseBody MessageResponse save(#ResponseBody Foo foo){
svc.save(foo);
return new MessageResponse("Foo saved with sucess", 200);
}
}
I've created many projects with this setup, you don't need spring4gwt!
My solution is to use a "bridge" class that allow you to call async services like spring controllers:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public abstract class BaseRemoteService extends RemoteServiceServlet implements
ServletContextAware {
private static final long serialVersionUID = 2470804603581328584L;
protected Logger logger = Logger.getLogger(getClass());
private ServletContext servletContext;
#RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
doPost(request, response);
return null; // response handled by GWT RPC over XmlHttpRequest
}
#Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
#Override
public ServletContext getServletContext() {
return this.servletContext;
}
}
Now, your *RpcServiceImpl should be something like:
#Controller
#RequestMapping("/*/action.service")
public class ActionRpcServiceImpl extends BaseRemoteService implements ActionRpcService {
//this class is managed by spring, so you can use #Autowired and other stuffs
//implementation of your rpc service methods,
}

Categories