I am new to CXF and hence kindly spare me if my question is too dumb.
I intend to develop a REST service using Grails which accepts a custom JAVA Object. Hence I intend to use grails-cxf plugin.
In my controller, I need a method (POST) which accepts a Java Object and return a Java Object
def UserDetails getUserDetails(User user)
{
// Logic
return new UserDetails();
}
I don't see any good example in the Plugin's documentation. I am not very particular about using this plugin. If you can suggest any way of achieving it with grails, its fine with me.
Please Help. Can we use grails-cxf pluggin to develop REST APIs ?
You have to define in the config.groovy where the cxf Plugin is looking for the Service.
Fore Example:
cxf {
servlet {
loadOnStartup = 10
}
servlets = [
CxfServlet: '/services/*'
]
endpoint {
soap12Binding = false
}
}
So the Plugin looks in the Service folder for some WebServices, but you need to define a Service as a WebService.
For your example the Service maybe looks like this :
class UserDetailsService {
static expose = EndpointType.JAX_RS
#WebResult(name = 'getUserDetails')
#WebMethod
UserDetails getUserDetails(#WebParam(name = 'user')User user)
{
// Logic
return new UserDetails();
}
}
I'm not sure if it works with the User Object, I never did that with an Java Object.
If it doesn't work you could use the UserId and get the User inside the method.
HTH
I didn't need a cxf pluggin to achieve Rest Service accepting Java Objects as arguements.
Command Object served my purpose
Related
I have recently started out with Spring and am unsure about how to approach this issue. I have a Spring boot program which makes calls to remote REST APIs. For example an AddressService class with getAddress(String user) method, which makes a HTTP call and returns a JSON response. I would like to set up Spring profiles for development purposes local, dev, uat, prod.
When the program is running with the local profile, I would like to "mock" these external API calls with an expected JSON response, so I can just test logic, but when it is run in any of the other profiles I would like to make the actual calls. How can I go about doing this? From what I read, there's many ways people approach this, using WireMock, RestTemplate, Mockito etc. I'm confused about which is the way to go.
Any advice would be greatly appreciated. Thanks.
WireMock,Mockit is for unittest, to mock the real request. Example here:
How do I mock a REST template exchange?
When you need a running implementation with a mock, i think the easiest way is that you have a interface
public interface AdressAdapter {
public List<Adress> getAddress(String name);
}
And two different implementations depending on the profile.
#Profile("local")
public class DummyAdress implements AdressAdapter{
#Override
public List<Adress> getAddress(String name) {
//Mock here something
return null;
}
}
! means NOT locale profile in this case.
#Profile("!local")
public class RealAdress implements AdressAdapter{
#Override
public List<Adress> getAddress(String name) {
//Make Restcall
return null;
}
}
What you could do is use different application.properties files depending on your profile. That way, you just change the url to a mock server for your local profile.
So what you have to do is :
Create another application.properties in your resources folder named : application-local.properties.
Change the url of the desired service.
Start your application with the VM option -Dspring.profiles.active=local.
Here is a link that describe well what you want to achieve.
For your mock server, you could use Wiremock, Mountebank, Postman,... that can be start separately and mock specific endpoints to return what you want.
I am totally new to the whole Google Cloud Endpoint/Google App Engine world. If you have gone through the Hello World example that Google provides(and you probably have), you might remember that there are 2 classes that are auto-generated for you: MyBean and MyEndpoint.
These are something like this:
/**
* The object model for the data we are sending through endpoints
*/
public class MyBean {
private String myData;
public String getData() {
return myData;
}
public void setData(String data) {
myData = data;
}
}
And,
/**
* An endpoint class we are exposing
*/
#Api(
name = "myApi",
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "backend.myapplication.DJ.example.com",
ownerName = "backend.myapplication.DJ.example.com",
packagePath = ""
)
)
public class MyEndpoint {
/**
* A simple endpoint method that takes a name and says Hi back
*/
#ApiMethod(name = "sayHi")
public MyBean sayHi(#Named("name") String name) {
MyBean response = new MyBean();
response.setData("Hi, " + name);
return response;
}
}
Now, I examined the code in index.html(which gets opened on deploying the backend). I found the following call in the javascript:
gapi.client.myApi.sayHi({'name': name}).execute(
Now, I can see that myApi is the name through annotation and sayHi() is the corresponding method, What I don't understand is the concept of exposing an API and annotation is aiding in that. There isn't any information about exposing APIs.
Could anyone help me understand this?
I think your question can be divided in 3 parts:
1/ What is exposing an API?
Basically, you are offering an access to your business logic through an Interface (the API), with full control on what you want to show or not. This Stack Exchange answer is a great explanation: https://softwareengineering.stackexchange.com/questions/203844/what-does-it-mean-to-expose-something
2/ What are these annotations in the auto-generated endpoints class?
If I can summarize it like that, Google endpoint is a "framework" which generates "default" APIs based on your java beans. By default you get CRUD operations in the API, but you can modify and/or enrich the endpoint to offer more complex business logic. The Endpoints classes that are generated include specific annotations that are used by the framework (in particular while generating a corresponding servlet) and define the URI you will call to interact with the methods of the APIs. See https://cloud.google.com/appengine/docs/java/endpoints/
3/ What is this gapi.client call?
gapi stands for Google API Client Library. It is the library that is offered by Google to interact with Endpoints from a web browser. See https://developers.google.com/api-client-library/javascript/
You could use other methods to call the Endpoint APIs, like jquery Ajax methods (http://api.jquery.com/jquery.ajax/), since Endpoints follow the REST architectural style. Note that you can call your endpoints from other "clients" than a web browser, e.g. an Android or iOS App. In these cases, you would not use the Google API Client Library but some other libraries.
I hope this clarifies a bit. Do not hesitate to ask for more details.
This question already has an answer here:
How to invoke a REST service
(1 answer)
Closed 7 years ago.
I have this web service http://qa-takehome-creyzna.dev.aetion.com:4440 that I would like to test. I have the authentication details (username and password) and the service has the following end points: /login, /user/, /user/{id} and /user/search. For all endpoints other than /login an authorization token needs to be passed as an HTTP Header.
The service exposes a login endpoint ( /login) which takes a POST request with two parameters: username and password. Following a successful login, an authentication token will be returned which must be used to make additional requests to the service. For example,if the request is as following,
{
"username": "admin",
"password": "admin"
}
It may return { "token": "1234-0009-999" } and this token will required for making additional request.
I will need to authenticate the web service, create 10 users and then, retrieve that information to validate the users was created correctly. I would like to develop a test plan and implement in Eclipse. How can I get started ?
A web service is basically an extension of the Java Servlet, where the input is processed a bit more and the output is rarely an HTML page.
Netbeans has an excellent tutorial on how to stand up a web service, and if you follow it, you can have a basic web service running within the hour.
https://netbeans.org/features/java-on-server/web-services.html
Don't be fooled by thinking that you must use one IDE (I like netbeans, but others don't) or another. The fancy GUI tools are just writing plain Java classes that might use other plain Java facilities (like JAXB if using XML, etc).
A web service is not much more than a web server that accepts particular kinds of requests, and responds with particular kinds of responses. In Java, web servers are made easier to use by leveraging Servlets. The internal contents of the Servlet will look like
Unpack the request
Validate the request is complete, report an error response if not
Act on the reqeust
Generate a response in the appropriate format
Send the response back as the reply.
--- Edited in response to request ---
Sorry, It seemed too obvious to me. Let me fill in the gaps. Sorry for glossing over the details.
public class MockHttpServletRequest implements HttpServletRequest {
#Override
public String getAuthType() {
throw new UnsupportedOpertationException("unexpected method use");
}
#Override
public String getContextPath() {
throw new UnsupportedOpertationException("unexpected method use");
}
... repeat for all methods ....
}
public class ItemRequestWithBadEncoding extends MockHttpServletRequest {
#Override
public String getMethod() {
return "GET";
}
#Override
public String getHeader(String name) {
if ("content-type".equals(name)) {
return "text/plain-ish"; // this is not a mime-type
}
throw new IllegalArgumentException(String.format("this mock doesn't support %s", name);
}
... fill out the rest of the required request details ...
}
public class CapturingServletResponse implements HttpServletRespose {
private final ArrayList<Cookie> cookies = new ArrayList<Cookie>();
#Override
public void addCookie(Cookie cookie) {
cookies.add(cookie);
}
public List<Cookie> getCookies() {
return Collections.unmodifiableList(cookies);
}
... override other methods and capture them into per-instance fields
with ability to return unmodifiable references or copies to them ...
}
Now back in the testing framework
#Test
public void testItemFetch() {
try {
MockRequest request= ItemRequestWithBadEncoding();
CapturingServletResponse response = new CapturingServletResponse();
Servlet itemRequestServlet = new ItemRequestServlet();
itemRequestServlet.service(request, response);
Assert.assertEquals("unexpected cookies in response", 0, response.getCookies().size());
... other asssertations ....
} catch (Exception e) {
Assert.assertFail(String.format("unexpected exception: %s", e.getMessage());
}
}
Depending on what items you care about, and how much work you need to put into it, you can then flesh out the needed parts of the capture and perhaps parameterize and refine the way you construct your input handling.
Look into spring frameworks.
They go well with other testing frameworks like Mockito and Junits.
Use something like SpringMVCTest or SpringRestAssured, note RestAssured would let you write integration tests.
Read this and this
This question related to cross site submission across JSP/Servelet based web application and ASP.NET MVC based web application. I could able to submit a NameValueCollection object from an ASP.NET Web project to another ASP.NET MVC project like below.
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultNetworkCredentials;
string transId = Guid.NewGuid().ToString(); //In Java we may use UUID class
var data = new NameValueCollection
{
{ "TransId", transId },
{ "Name", "Regi" },
{ "DOB", "10/17/2013" },
{ "ZIPCode", "673010" },
};
var result = client.UploadValues("http://localhost:50976/api/Trans/Trans", data);
string s = Encoding.ASCII.GetString(result); //May be Base64.encodeToString(fileData, Base64.CRLF) in Java?
if (s == "1")
{
Response.Redirect("http://localhost:50976/Product/ProductList?TransId=" + transId + "");
}
}
ASP.NET MVC project has a WebAPI which is catching this submission like below.
public int Trans(TransViewModel transViewModel)
{
return 1;
}
My ViewModel definition like below
public class TransViewModel
{
public string TransId { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
So now I need to replace my 1st WebProject where ASP.NET MVC
application is calling, with a Java based web application. How can I
accomplish the same submission using alternate JAVA classes in place
of WebClient and also to submit a NameValueCollection type to the same
ASP.NET MVC application? This submission should be accepted by ASP.NET
MVC application like above through a ViewModel
Hmm.. I haven't tried but if you just use regular HTTP GET or POST it doesn't matter what web framework you are using. What ASP.NET MVC want is just a NORMAL request (for example: http://yourwebsite.com:8081/Main/Index?name=Me&email=me#gmail.com).If you send it from any java or other web frameworks your MVC router will be able to map them to a particular action method. In my example this is the Main controller and Index action (HTTP GET) with parameters name and email (string type). The same for Post (add HTTP POST attribute for the action). Problems could have place if you were using models. In this case I always use fiddler to see what exactly I am sending to MVC and also you have to understand how standard MVC model binding works. If you find that your java data structure can't be handled with the MVC standard model binder you can whether change the data structure or implement custom model binder and directly get access to all request data. MVC is a very pluggable framework and I believe this is one of the best web frameworks ever created!
I am not sure that you are trying to do. But I think that there is no way to DIRECTLY pass data between MVC and let's say plain java servlet. You always send data as HTTP requests and it's up to web framework how to handle them. If you need a similar to MVC you can use Spring MVC (java). Again I am not really sure what you are trying to achieve. However, you can make any HTTP based calls from server as well. For example, you have a servlet mapped to /doSomething in your java environment. In the servlet inside get method you have all access to request parameters. So in your MVC project you are free to just make a server side http based call to the servlet mapped address and pass any parameters. In the servlet you generate output and return to the mvc server. After it's up to you what to do with it!
I've written an an API giving some methods like
runApp();
stopApp();
doSomethingElse();
currently I have a jar file with which I run these methods.
I want to be able to invoke these method by http.
For example, going to : http://localhost:8080/something/runApp
will invoke runApp() method.
I've heard that this should be done with webservices, and particularly REST API.
Is webservices the only way to achieve this?
And if so, can someone summarize the simplest ways to implement this ability, or point me to an existent summary?
Thanks.
Here's a RESTful API example based on your pseudocode, with JAX-RS:
#Path("/something")
public class MyApp {
#GET
#Path("/runApp")
public Response runApp() {
return Response.ok("Running app").build();
}
#GET
#Path("/stopApp")
public Response stopApp() {
return Response.ok("Stopping app").build();
}
#GET
#Path("/doSomethingElse") {
return Response.ok("Doing something else").build();
}
}
Which when built and deployed into any JEE5 or JEE6 web capable container will allow you to access services those services at:
http://localhost:8080/something/runApp
http://localhost:8080/something/stopApp
http://localhost:8080/something/doSomethingElse
Assuming your server is running on localhost:8080, of course. Having said that, nothing in this example is really RESTful, and would be better implemented using JAX-WS.
You've pretty much described exactly what a web service is. Code gets run when you hit a particular URL with a particular type of request.
As to how to build a web service in Java, there's a huge amount of documentation out there on the web (and SO) on that. You should not have any trouble finding useful articles.