I'm building a web service that's supposed to register on another server by sending its wsdl URL to that server.
I built a very basic web service in Netbeans,
#WebService
public class RegisterTest{
#WebMethod(operationName = "emphasize")
public String emphasize(#WebParam(name = "inputStr") String input){
return input + "!!!";
}
}
and Netbeans automatically directs me to localhost:8080/RegisterTest/RegisterTestService?Tester, and naturally, the wsdl can be found at localhost:8080/RegisterTest/RegisterTestService?wsdl.
How would I programmatically get this URL?
Edit:
I've noticed that the only place that seems to store this URL is the glassfish server itself. The context-root seems to only be found in glassfish/domain//config/domain.xml.
Is there a nice way of accessing the glassfish server APIs? I can easily get the endpoint address through the UI in applications > serviceName > View Endpoint, is there a programmatic way of doing this?
I've tried looking through asadmin commands, but can't seem to find anything there that gets the context-root or the endpoint URL either.
Untested, but should be pretty close to what you're looking for:
#WebService
public class RegisterTest
{
#Resource
private WebServiceContext context;
#WebMethod(operationName = "emphasize")
public String emphasize(#WebParam(name = "inputStr") String input)
{
return input + "!!!";
}
#WebMethod(operationName = "getWsdlUrl")
public String getWsdlUrl()
{
final ServletContext sContext = (ServletContext)
this.context.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
final HttpServletRequest req = (HttpServletRequest)
this.context.getMessageContext().get(MessageContext.SERVLET_REQUEST);
final StringBuilder sb = new StringBuilder();
sb.append(req.isSecure() ? "https" : "http");
sb.append("://");
sb.append(req.getLocalName());
if ((req.isSecure() && req.getLocalPort() != 443) ||
(!req.isSecure() && req.getLocalPort() != 80))
{
sb.append(":");
sb.append(req.getLocalPort());
}
sb.append(sContext.getContextPath());
sb.append(RegisterTest.class.getSimpleName());
sb.append("Service?wsdl");
return sb.toString();
}
}
Related
I am recording rest api's with wiremock... in my case for SharePoint.
So I set up a recorder:
java -jar wiremock-standalone-2.18.0.jar
Now I go to http://localhost:8080/__admin/recorder/ and I enable recording for my http://sharepointhost.
Now I make some requests to sharepoint rest apis through http://localhost:8080.
But the rest api responses still reference the http://sharepointhost.
Is there a way to turn on some sort of reverse proxy or URL pattern string replace so I can avoid this issue? What is the way to do that in my case? Do I need to use the Java variety of the recorder instead of using the standalone?
WireMock supports "Extensions." And there are some pre-packaged extension types called "Transformers."
There is an extension type that allows you to intercept responses of http requests. Here you can then replace contents of responses.
See http://wiremock.org/docs/extending-wiremock/
I created a GitHub repository with a response body URL rewrite extension:
https://github.com/nddipiazza/wiremock-response-body-url-rewriter
public class ResponseBodyUrlRewriteTransformer extends ResponseTransformer {
final int wiremockPort;
final String wiremockBindAddress;
final private List<String> urlsToReplace;
public ResponseBodyUrlRewriteTransformer(String wiremockBindAddress, int wiremockPort, List<String> urlsToReplace) {
this.urlsToReplace = urlsToReplace;
this.wiremockBindAddress = wiremockBindAddress;
this.wiremockPort = wiremockPort;
}
private String replaceUrlsInBody(String bodyText) {
for (String urlToReplace : urlsToReplace) {
bodyText = bodyText.replaceAll(Pattern.quote(urlToReplace),
"http://" + wiremockBindAddress + ":" + wiremockPort);
}
return bodyText;
}
#Override
public Response transform(Request request, Response response, FileSource files, Parameters parameters) {
if (response.getStatus() == 200) {
ContentTypeHeader contentTypeHeader = response.getHeaders().getContentTypeHeader();
if (contentTypeHeader != null && contentTypeHeader.mimeTypePart().contains("xml")) {
return Response.response()
.body(replaceUrlsInBody(response.getBodyAsString()))
.headers(response.getHeaders())
.status(response.getStatus())
.statusMessage(response.getStatusMessage())
.fault(response.getFault())
.chunkedDribbleDelay(response.getChunkedDribbleDelay())
.fromProxy(response.isFromProxy())
.build();
}
}
return response;
}
#Override
public String getName() {
return "ResponseBodyUrlRewriteTransformer";
}
}
Yes. You can launch WireMock as a proxy with automatic record mode. The command you need is this:
java -jar wiremock-standalone-2.18.0.jar --port 8787 --print-all-network-traffic --verbose --enable-browser-proxying --record-mappings
The important params there are enable-browser-proxying and record-mappings
The proxy is running on port 8787 and you have to configure your browser to use proxy localhost:8787
Now you can browse any web site, and all the trafic will be recorded.
I want to build Jax-ws web service using Wildfly 10.0 and I want this web service with stateful session (read and write on session ),
I have searched for that, and I see the below link:
https://docs.oracle.com/cd/E14571_01/web.1111/e13734/stateful.htm#WSADV234
Unfortunately the session code did'n work
When I call sayHello method that use session, the time finished and returned (Exception: java.lang.NullPointerException Message: java.lang.NullPointerException ).
I'm using Eclipse Mars, Dynamic web service, Wildfly 10.0, and the web service (server: using Wildfly 10.0, web service run-time: Apache Axis, and using ear file for this project)
The code is:
package com.sample;
#WebService(targetNamespace = "http://sample.com/", serviceName = "Test1Service", portName = "Test1Port")
#Stateful
public class Test1 {
#Resource
private WebServiceContext wsContext;
#WebMethod
public String sayHello() {
MessageContext mc = wsContext.getMessageContext();
HttpSession session = ((javax.servlet.http.HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST))
.getSession();
if (session == null)
throw new WebServiceException("No HTTP Session found");
String item = "";
try {
item = (String) session.getAttribute("name1");
} catch (Exception e) {
e.printStackTrace();
}
if (item == null || item.equals(""))
item = "good";
session.setAttribute("name1", item);
return "Hello " + session.getAttribute("name1");
}
#WebMethod
public int setValue(int x) {
return x;
}
}
Please note the setValue method worked successfully, but the sayHello method did'nt work
Thanks everybody,
The problem: I was using Axis not Axis2 where Axis2 support Http session.
I am working on a client server application. I was using Restlet 2.0.3. Due to a heavy load task my client was getting timed-out. I searched on the forum and found that switching over to Restlet 2.2 would help. So I did that. I upgraded my Restlet to 2.2.1. But now my code has stopped working at precisely this method.
public synchronized UUID generateUniqueSessionId(String userAtDomain)
{
UUID newSessionId = UUID.randomUUID();
SessionAttributes sessionAttributes = new SessionAttributes();
sessionAttributes.setAlive(true);
sessionAttributes.setFQUserName(userAtDomain);
loggedInUsers.put(newSessionId, sessionAttributes);
return newSessionId;
}
So I am returning the UUID at last.
This code is on the server and invoked during login. Following is the error that I am getting from the logs.
16 Mar 2015 11:23:18 WARN - Unable to find a converter for this object : f3d2edda-443c-454d-856a-fb4e7ed9c535
And this object referred in the log belongs to java.util.UUID
The code on the client side which invokes the server looks like this.
public UUID authenticateUser(String username, String passwd) {
try {
String url = RESTLetWebSvcsFactory.getFactoryInstance().getServer_URL() + "login/" + username + "/" + passwd;
Context context = new Context();
Client client = new Client(context, Protocol.HTTP);
ClientHelper helper = new ClientHelper(client);
helper.getHelpedParameters().set("socketConnectTimeoutMs", "60000");
ClientResource cr = new ClientResource(url);
LoginLogoutResource resource = cr.wrap(LoginLogoutResource.class);
return resource.loginUser();
} catch (ResourceException re) {
if (re.getStatus().isConnectorError()) {
try {
RESTLetWebSvcsFactory.enableFallBackServer();
String url = RESTLetWebSvcsFactory.getFactoryInstance().getServer_URL() + "login/" + username + "/" + passwd;
ClientResource cr = new ClientResource(url);
LoginLogoutResource resource = cr.wrap(LoginLogoutResource.class);
return resource.loginUser();
} catch (ResourceException re1) {
int statusCode = new RESTLetErrorHandler().handleServerError(re);
if (statusCode != -1) {
throw new UserCRUDException(statusCode);
}
}
} else {
throw new UserCRUDException(new RESTLetErrorHandler().handleServerError(re));
}
}
return null;
}
Note: USERCRUDException is my own exception and not one of JAVA
Please help me resolve this problem which probably prevents returning the UUID from the server and thus my application isn't moving ahead.
Thanks in advance
Restlet uses under the hood a generic bean conversion to convert bean to representation (and representation to bean). So your problem depends on the converter you use.
I made a test with the extension org.restlet.ext.jackson (that contains such bean converter) and with version 2.2.1 of Restlet. My test bean is described below:
public class TestBean {
private String name;
private String message;
private UUID uuid;
(...)
public UUID getUuid() {
return uuid;
}
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
}
and the following test server resource:
public class MyServerResource extends ServerResource {
#Get
public TestBean ping() {
TestBean bean = new TestBean();
bean.setMessage("pong");
bean.setUuid(UUID.randomUUID());
return bean;
}
}
I received the following content for a GET method:
{
"name":"my name",
"message":"my message",
"uuid":"be9e5381-d5c9-4e45-b5c8-4af1f8bdca16"
}
Can you provide the converter you use? and the list of the Restlet dependencies you have in your application?
Hope it helps you,
Thierry
I have a simple WSDL for a webservice. With wsimport I generated the java wrappers. And I have implemented the generated interface in a class "MyService". Then I publish this webservice with the built-in features of Java6:
MyService myService = new MyService();
Endpoint endpoint = Endpoint.publish("http://localhost:80/servicetest/services/MyServiceINSoap", myService);
When I let this code run, everything works perfect - I am able to connect to the service with a soapclient and can execute the methods.
Now I want the built-in webserver of the javavm to use basic authentication - so the client has to provide an userid and a password. How do I accomplish this? Is this possible? Or do I need an application server (tomcat, jboss, whatever...)?
I have searched for some time but only found solutions for webservice which are hosted in an application server.
Many thanks in advance!
erwrock
As I found your answer I was quite relieved because I searched hours for a solution. But as I tried to follow your link I noticed that the page is not available any longer. Fortunately, I found the old version with the help of the Wayback Machine (https://archive.org/web/). Although, this article is great I had some problems with getting the basic auth to work at the client side. In the end I got it working with the help of java.net.Authenticator. Here are the code snippets which I hope to be useful for others.
Server:
javax.xml.ws.Endpoint serverEndpoint = Endpoint.create(new MyService());
com.sun.net.httpserver.HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
com.sun.net.httpserver.HttpContext httpContext = server.createContext("/myservice");
server.start();
AuthenticatorServer authenticatorServer = new AuthenticatorServer("myRealm", "myName", "myPwd");
httpContext.setAuthenticator(authenticatorServer);
serverEndpoint.publish(httpContext);
Where AuthenticatorServer is:
private static class AuthenticatorServer extends com.sun.net.httpserver.BasicAuthenticator {
private final String user;
private final String pwd;
public AuthenticatorServer(String realm, String user, String pwd) {
super(realm);
this.user = user;
this.pwd = pwd;
}
#Override
public boolean checkCredentials(String userNameInput, String passwordInput) {
return StringUtils.equals(user, userNameInput) && StringUtils.equals(pwd, passwordInput);
}
}
And on the Client side:
AuthenticatorClient authenticatorClient = new AuthenticatorClient("myName", "myPwd");
Authenticator.setDefault(authenticatorClient);
javax.xml.namespace.QName qName = new QName(namespaceURI, WS_SERVICE_NAME);
java.net.URL wsdlAddress = new URL(namespaceURI + WS_SERVICE_NAME + "?wsdl");
MyService service =(Service.create(wsdlAddress, qName)).getPort(MyService.class);
Where AuthenticatorClient is:
private static class AuthenticatorClient extends java.net.Authenticator {
private final String user;
private final String pwd;
public AuthenticatorClient(String user, String pwd) {
this.user = user;
this.pwd = pwd;
}
#Override
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication(user, pwd == null ? null : pwd.toCharArray()));
}
}
Found a solution here:
https://today.java.net/pub/a/today/2007/07/03/jax-ws-web-services-without-ee-containers.html
after hours of trial-and-error finally the right searchwords in google :)
Im new to Rest web services and say Ive created this web service using Netbeans
#Path("browse")
#Stateless
public class ArticleBrowseResource {
#EJB
private ArticleSearcherLocal ejbRef;
#GET
#Produces(MediaType.APPLICATION_XML)
public List<Article> browse(#DefaultValue("") #QueryParam("username") String username,#QueryParam("sd") String sd) {
// convert sd string to date
List<Article> articles = ejbRef.search(username, date);
return articles;
}
}
where Article is an entity which is anotated with #XmlRootElement
Now how am I supossed to retreive this list of articles in my client which for simplicity lets just say it is a java standard application? In SOAP web services I know that these objects are automatically generated but not in Rest.
This is the client class generated for this service by Netbeans
public class ArticleBrowseClient {
private WebResource webResource;
private Client client;
private static final String BASE_URI = "http://localhost:8080/cityblog/rest";
public ArticleBrowseClient() {
com.sun.jersey.api.client.config.ClientConfig config = new com.sun.jersey.api.client.config.DefaultClientConfig();
client = Client.create(config);
webResource = client.resource(BASE_URI).path("browse");
}
public <T> T browse(Class<T> responseType, String username, String sd) throws UniformInterfaceException {
WebResource resource = webResource;
if (username != null) {
resource = resource.queryParam("username", username);
}
if (sd != null) {
resource = resource.queryParam("sd", sd);
}
return resource.accept(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType);
}
public void close() {
client.destroy();
}
}
What is the best and simplest way to resolve this issue?
Any help is appreciated and
thx in advance
Please try fewer code generation and more understanding of what you are actually doing. On the server, you generate a XML message with help of JAXB. On the client side, you can consume this XML with a programming language and library you like. Just use tools like curl to see what is going actually over "the wire". Your generated client site looks fully reasonable. You just need your Article class from the server side on the client side. The generated code uses Jersey which can read XML messages per JAXB per default. So just drop your server side Article class in your client side classpath and use it. But please also have a look at the wire level protocol to understand the portability of your REST API.