Use Undertow to serve AngularJS - java

I would like to use Undertow as a simple web server for serving an AngularJS application. The rest services needed by the AngularJS application is served by Apache Camel so I would only need to serve the Angular App using Undertow.
I have read the documentation but cannot get it working, any ideas on what I am doing wrong?
Here is the code that I have now for starting Underow server
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(resource(new FileResourceManager(new File("../dist"),10))
.addWelcomeFiles("../dist/index.html")
.setDirectoryListingEnabled(true))
.build();
server.start();

File("../dist") is the problem. Use an absolute path or at least one without "..", then it should work.
(Undertow contains a sanity check comparing the computed file path for a resource with its canonical path, which breaks on "." and "..".)

You could also use ClassPathResourceManager.
ResourceManager rm = new ClassPathResourceManager(getClass().getClassLoader(), "dist");
ResourceHandler handler = new ResourceHandler(rm);

Related

Call multiple url with Http request

I have the following code.If my url[0] is down/had any issue i.e !200 then i need to call another url
url[1].how can i code it effeciently.I am using spring boot and java 8.
url[0] = server1.8080/get/data
url[1] = server2.8080/get/data
ResponseEntity<MyPojo> response =restTemplate().exchange(url[0],HttpMethod.GET, request, MyPojo.class)
You could use Ribbon for client side load balancing with ribbon.
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html
There are a few steps to make it work:
add the ribbon dependency to your pom.xml
configure the servers in the application.properties or
application.yaml.
Configure the Ribbon Client
Please find a complete tutorial here:
https://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon

how do I make spring boot embedded tomcat to return 200 OK for base url?

My app is deployed at http://123.87.65.23:8080. The context path is /myapp configured in application.properties. So if I access http://123.87.65.23:8080, I get 404. but if I access http://123.87.65.23:8080/myapp/health, I get 200 as expected.
Our operation team monitors base url (http://123.87.65.23:8080) for 200 OK.
I have two options:
Return 200 OK when I hit http://123.87.65.23:8080. No response is required.
Or somehow proxy the request http://123.87.65.23:8080 to http://123.87.65.23:8080/myapp/health within my Spring Boot application.
NOTE: I am using embedded tomcat. so the option of changing server.xml is not applicable
I don't how know how to do either options.
If you set the contextPath attribute in your .properties file then Spring does what it's supposed to do, everything gets moved there.
If you're packaging the app as a .war and running it in an external server then you can set that server up to redirect root requests to whatever URL inside your Spring Boot application.
If you're packaging the app as a runnable .jar with an embedded server and you want to keep the contextPath in the .properties-level then
a) you still need some kind of external server that can catch requests to root and redirect to your Spring Boot application
b) you need to set up two distinct DispatcherServlets where one's contextPath is /myapp and the other's is / which will redirect to your Spring Boot Application
However, the easiest solution would be to remove contextPath and just prepend each Controller's #RequestMapping with /myapp, move all the management endpoints to /myapp with management.context-path and write a single #Controller method mapped to / that redirects to the health endpoint.
In your tomcat container your app should be deployed into a directory named "ROOT", not "myapp", if you wanna use root urls. And I guess your Dispatcherservlet may be configured to process requests to /health, and you need to process just /
Or maybe you've got a Controller, mapped to /health.
Can't tell anything else without code
If you want to get 200 on http://123.87.65.23:8080 request, you need an application named ROOT.war in your webapps folder.
So http://123.87.65.23:8080 and http://123.87.65.23:8080/myapp are two different applications.
I suggest you two options:
Deploy your application as http://123.87.65.23:8080 (ROOT.war)
Use some Proxy Server like nginx or apache. You can configure the proxy server to redirect all ROOT requests to you application
Here are some examples for nginx:
location / {
proxy_pass http://123.87.65.23:8080/myapp/;
}
or just return 200:
location / {
return 200;
}

Is it possible to setup apache-cxf without web.xml?

Is it possible to create a webservice with apache cxf (soap/rest) by "using the servlet transport without Spring and without web.xml file"?
No Its not possible.
The service will be needing the web deployment descriptor.
You can extend
CXFNonSpringJaxrsServlet for REST
and
CXFNonSpringServlet for SOAP
web-services in Apache CXF to avoid using Spring, but then you need to register them in web.xml.
You have to either use Spring configuration or web.xml.
Refer: Apache CXF - How to register a SOAP service without Spring?
It is possible. Took me quite a bit of work to figure this out for my own project and thought I'd share.
In my context, we're using OSGi HTTP Service to publish JAX-RS resources using a Jersey Servlet container and I wanted to do the same thing with CXF for JAX-WS resources.
Your class extending CXFNonSpringServlet should include the following:
private Object obj; // JAX-WS resource singleton
#Override
public void loadBus(ServletConfig conf)
{
super.loadBus(conf);
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setBus(getBus());
factory.setAddress("/some/path");
factory.setServiceBean(obj);
Server cxfServer = factory.create();
}
Note that you may load as many resources within a single servlet as you find needful. Also note that the path in factory.setAddress() is appended to the path at which you register the servlet.
Also note that I'm using the singleton pattern, rather than the handler-class pattern. I'm sure this could be modified simply to fit the other paradigm.

Embedded Jetty 8 hot deploy classes (using Maven)

I have a standard Maven webapp structure defined, and it uses Spring MVC.
I am using an embedded Jetty server (java class) for testing the application in development.
The code used to create the Jetty server is outlined below. If I make changes to any JSP files, the changes are immediately visible in the browser.
However if I change any class files, e.g Controllers, the changes are not hot deployed?
What do I have to do get this to work?
I have searched this and I think I need to use the class org.eclipse.jetty.util.Scanner and specifically the setScanInterval method, but not sure how to wire this up?
Here is the code to create the Server
String webAppDir = "src/main/webapp/";
Server server = new Server(8080);
WebAppContext webApp = new WebAppContext();
webApp.setContextPath("/");
webApp.setDescriptor(webAppDir + "/WEB-INF/web.xml");
webApp.setResourceBase(webAppDir);
webApp.setParentLoaderPriority(true);
HandlerCollection hc = new HandlerCollection();
ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
hc.setHandlers(new Handler[] { contextHandlerCollection });
hc.addHandler(webApp);
server.setHandler(hc);
return server;
Thanks in advance
For hot deployment you need to use the WebAppProvider and the DeploymentManager. Those you can configure to manage the scanning for changes and the reloading of the webapp. So it is clear, the WebappContext is not what manages the deployment of a webapp, it is merely the container class that is gets deployed so there is another mechanism that works outside of that which can handle the concepts of deploy/redeploy.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-deploy/src/test/resources/jetty-deploy-wars.xml
You can take that chunk of xml there and convert into the java calls you need to do this embedded.
Or use something like the jrebel jvm plugin which provides for automatic class reloading.

How do I find the URL of my web service?

I know this might seem a stupid question but I am just not able to find any information regarding this question.
I have a java web service (generated using NetBeans) and inside the web service class I would like to know the URL at which the web service was deployed.
For example, if I am deploying the web service on my local glassFish server, the web service is available at "http://localhost:8080/MyService/" where "MyService" is the name of my service.
The reason I need to know this URL is because my web service generates some files that I need to make available at this URL. For example, the web service call returns a URL "http://localhost:8080/MyService/report.html"
I have found some links about "WebServiceContext" but I am not able to get the URL at which my web service is running.
Edited
To clarify: Inside MyWebService.java class I want to find out the URL at which my web service was deployed (in this case, my web service is running at "http://localhost:8080/MyService/", but once it is deployed on a production server, this URL will change)
Easier in my opinion, for example:
#GET
public URI redirectSendMail(#Context UriInfo ui) {
return ui.getBaseUri();
}
If we want to send a String back to the client, indicating the exact path of some resource, we might want something like this.
#GET
public String getResourcePath(#Context UriInfo ui) {
return ui.getAbsolutePath();
}
If you are asking how to find the hostname (e.g. 'localhost' or 'www.example.com') that your servlet container is listening to you have a few options:
Add a configuration point that is set at deployment time (e.g. config file, system property)
Look into if your servlet container exposes any 'virtual host' configuration via JMX or read its config files (e.g. tomcat hosts)
Find the IP Address of the server and do a DNS lookup to get its configured hostname
Inspect the 'Host' header of the incoming HttpServletRequest
String hostname = request.getRequestHeader("Host");
Add the below property in your webservice class.
#Resource
private WebServiceContext wsCtxt;
Now below code snippet will give you the values you are looking for:
MessageContext msgCtxt = wsCtxt.getMessageContext();
HttpServletRequest request =
(HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
String hostName = request .getServerName();
int port = request .getServerPort();
to check from where the webservice was invoked, use the below code.
String clientIP = request .getRemoteAddr();
Related imports are below:
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
Hopefully I am able to help you, I have just recently started working with webservices (Jersey REST) and I have found that the url to your endpoint is :
'http://localhost:8080/MyService/XXX/YYY'
where XXX = the URL pattern in the servlet mapping in your web.xml file (eg. file below)
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
and the YYY is the path defined by your webservice's #Path() parameter so in the case of this example it would be something like:
'http://localhost:8080/MyService/rest/myPathDefinition'
Another thing to note is that you can in fact change the web context root in eclipse, though it will default to the name of your Java project. Please let me know if you need further clarification or if this did not help / someone can expand on it.
It could be found on your wsdl file as:
therefore: http://localhost:8080/TestSOAPWebservice/services/TestClassImpl?wsdl would be the url to your wsdl file.

Categories

Resources