How to identify whether web service is REST or SOAP? - java

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.

Related

How to set up Spring Controller to handle a backpressured request

Spring MVC controller is to be used as a proxy for another service to serving possibly large files.
To avoid storing the whole WebClient response from another service in memory at any given time I wanted to use reactive properties of Spring 5 + Reactor project and stream its response as it's consumed by the browser.
The current code looks like
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.reactive.function.client.ClientResponse
import org.springframework.web.reactive.function.client.WebClient
import reactor.core.publisher.Mono
#Controller
class ReportController {
#GetMapping("/reports")
fun getReport(): Mono<ClientResponse> {
val webCient = WebClient.create()
return webCient
.get()
.uri("http://localhost:3333/file")
.exchange()
}
}
And it causes
java.lang.IllegalStateException: Could not resolve view with name 'reports'.
at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$3(ViewResolutionResultHandler.java:277) ~[spring-webflux-5.0.6.RELEASE.jar:5.0.6.RELEASE]
How to configure the controller to handle Mono<ClientResponse>?
If the response is of type Mono will the request be backpressured? Is there a need to convert it to bytes chunks and make it Flow?
Spring documentation says a lot of benefits of backpressure but doesn't answer the question above, nor gives any warning about Mono response. Is it still reactive?

I can't use yoccaddon in Hybris 5.5.1

I am using an Hybris 5.5.1 trial for learning purposes. I want to create a ycommercewebservice addon with yoccaddon like the documentation points, but I don't see that module, just the yaddon.
Iis it the same? I followed the documentation steps but using yaddon insteado of yoccaddon.
I tried with yaddon and after following the documentation and building successfully, my new api resource throws "There is no resource for path /rest/v2/apparel-uk/testing"
My controller has:
package com.test.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping(value = "/{baseSiteId}/testing")
public class TestController
{
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public String getTesting()
{
String testText = "Hello Test";
return testText;
}
}
You need to add #ApiVersion("v2) or #ApiVersion("v1).
Hmm... I am not big familiar with the addon logic of hybris, but what I see here is that you do a request on /rest/v2/apparel-uk/testing, but you have only the following Request Mapping:
#RequestMapping(value = "/{baseSiteId}/testing")
So the part /rest/v2/ is missing.
Interesting. I've got hybris 5.5.1 here and I'm trying to find the yoccaddon myself - I can't. Makes me wonder if it's been deprecated (and if so, why the wiki documentation still refers to it...
Does the API respond if you hit /{baseSiteId}/testing ? I'd suggest adding a web module (with the relevant webfoot configured) in your extensioninfo.xml - e.g.
<webmodule jspcompile="false" webroot="/rest/v2"/>
This should then mean that your controller will be available on the expected URL.

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,
}

How can i create a java web service that supports multiple client requests using only java SE?

I have the task of creating a web service that takes requests from multiple clients. I am new to web services so i used this tutorial:
http://www.java-forums.org/blogs/web-service/1145-how-create-java-web-service.html
This is exactly what i am looking for. A web service with no java ee.
It is preferable that is stick with java se, it's a policy that is prefered to be kept.
Now i would like to go one step further and implement the service so that it processes requests from multiple clients that operate on a shared resource.
Ideally i would like something like this:
Client client = new Client();
client.processRequest(string);
And the web service will process the requests in the order they arrive. The requests will come in as an request is processed so it will be kept in a stack.
The problem is i just on't know how to send the response back to the specific client. The response will be a string. The only thing i came up with, at least in principle, is to send a object that remembers where it came from but that just seems the web services job.
I have searched the internet but did not find a solution.
If possible using only SE please help.
If you think it is not possible without EE you can say so, but i would very much like an answer using only SE
I think what you are trying to implement is an Asynchronous Webservice. The following link tells you how to implement it in Java SE.
http://java.dzone.com/articles/asynchronous-java-se-web
You can do this using the Endpoint.publish methods in Java SE. First, you create a simple "endpoint interface":
package com.example;
import javax.jws.WebService;
#WebService
public interface ExampleService {
String getDateTime();
}
Then you specify that interface in an implementation class. As you can see, both classes must be annotated with #WebService.
package com.example;
import java.io.IOException;
import java.net.URL;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Service;
import javax.xml.namespace.QName;
#WebService(endpointInterface = "com.example.ExampleService",
serviceName = "ExampleService",
portName = "timeService",
targetNamespace = "http://example.com/time")
public class ExampleServiceImpl
implements ExampleService {
public String getDateTime() {
return String.format("%tc", System.currentTimeMillis());
}
public static void main(String[] args)
throws IOException {
// Create server
Endpoint endpoint =
Endpoint.publish("http://localhost:8080/example",
new ExampleServiceImpl());
URL wsdl = new URL("http://localhost:8080/example?wsdl");
// Create client
Service service = Service.create(wsdl,
new QName("http://example.com/time", "ExampleService"));
ExampleService e = service.getPort(ExampleService.class);
// Test it out
System.out.println(e.getDateTime());
endpoint.stop();
}
}
By default, JAX-WS will treat all public methods of an endpoint interface as web methods (since that is commonly what developers will want). You can have more control by placing the #WebMethod annotation on only the methods you want exposed as web services.
See the JAX-WS specification for all the details.

Invoking a spring web service

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

Categories