I'm creating an embedded server using JBoss RestEasy's embedded TJWS. The limited documentation is inaccurate, but I was able to create a server instance with a test JAX-RS resource:
#Path("test")
public class TestResource {
public static void main(String[] args) throws Exception {
TJWSEmbeddedJaxrsServer tjws = new TJWSEmbeddedJaxrsServer();
tjws.setPort(8080);
tjws.start();
tjws.getDeployment().getRegistry().addPerRequestResource(TestResource.class);
}
...
That allows me to browse to http://localhost:8080/test to test the GET method implementation (not shown here).
But how do I specify that the embedded server should be mounted at some other base path? For example, how do I get the test resource mounted to http://localhost:8080/example/test? Sure, I could hard code this into the #Path designation, but the base path shouldn't be part of the resource---I should be able to redeploy this resource class in a J2EE server at any base path.
I'm guessing there is something like a tjws.getDeployment().setBasePath("example") that I haven't found, yet. (If anybody has some in-depth documentation for this please let me know as well!) Thanks in advance.
So far I've found that I can simulate this by specifying a prefix when adding resources to the server:
tjws.getDeployment().getRegistry().addPerRequestResource(TestResource.class, "example");
That's not quite the same as I was looking for, but it does allow me to access the resource as http://localhost:8080/example/test without being forced to indicate this base path in the resource definition.
Related
I have two applications :
one spriig boot config server
the another one a spring boot config client
The client side have to use a file named certificate.json.
I want to store this file in the server side so another microprogram and my client programm who need it can retrieve it from the server side.
I try that :
copy the file certificate.json to classpath:/config
add this line to the application.properties :
certificate.location: classpath:config/certificate.json
call the value from client programm by :
#Value("${certificate.location}")
private String certificateLocation;
But the value of certificateLocation is classpath:config/certificate.json. The value I want is the file location like : /home/user/project/scr/main/resources/config/certificate.json.
Or, are there a way to directly retrieve my file by URI, for example locahost:8889/... (8889 is my config server port).
EDIT 1:
I cannot use absolute path from the server because I'm not the one who run it.
Thank you in advance.
I'd do
#Value("${certificate.location}") private Resource certificateLocation;
that way, your location is already a Resource that you can load, call getURI(), getFile().getAbsolutePath() etc. Since your value is prefixed with classpath:, you would have a ClassPathResource instance, which you can use for lot of things.
The classpath is just a protocol part of the URL. You can use file or any other supported protocol. For example, file://home/user/project/scr/main/resources/config/certificate.json.
Try this url
spring.cloud.config.server.native.searchLocations
=file://${user.home}/CentralRepo/
SPRING_PROFILES_ACTIVE=native
I am also get this way using microservice
OP you need to create a web service and return certificate.json as the response. Then you can send and receive data by sending a GET or POST request to a URI like https://12.12.12.12:8080/getCertificate. Please see:
https://spring.io/guides/gs/rest-service/
As a side note, you should never expose your inner files to the internet because it's very unsecure and opens you up to pirating and hacking.
What I would do in this case is
Add configuration for static folder
#SpringBootApplication public class DemoStaticresourceApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(DemoStaticresourceApplication.class, args);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/files/**").addResourceLocations("file:/fileFolder/")
.setCachePeriod(0);
}
}
Place certificate.json in fileFolder and try http://localhost:8080/files/certificate.json and it will be served directly from file system for you.
And now every file you add in this folder will be served only if called using /files/ path
I'm trying to create a Framework on top of Restlet and my question would be, is it possible to have a ServerResource to be "injected" from outside the org.restlet.Application code?
The standard way is to have a resource injected here:
public class FrameworkApplication extends Application {
private static final String ROOT_URI = "/";
/**
* Creates a root Restlet that will receive all incoming calls.
*/
#Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach(ROOT_URI, RootServerResource.class);
return router;
}
}
However since I am building a framework the use of FrameworkApplication is through including it as a dependency:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myframework</artifactId>
<version>0.0.1</version>
</dependency>
Going back to the question, I want to know if it is possible to have a ServerResource to be added in the Restlet routing like this:
public class PluggableResource extends ServerResource {
#Get("json")
public String represent() {
// stuff
return resp;
}
}
In the case of dependency injection, the solution was to do, SelfInjectingServerResource now can I make such a SelfAttachingServerResource?
I don't know what you exactly want to do but auto-discovering support of server resources isn't supported in Restlet. You need to implement by your own within a dedicated implementation of the class Application of Restlet. The method createInboundRoot would be responsible to scan the classpath to detect server resources. Moreover you need to add more metadata for server resources (with annotations for instance) to specify the attachement path.
However, the JAX-RS support provides this feature. It provides a set of annotations to make easy to identify server resources and provide metadata like attachement path, methods and exchanged media types for methods. Here is a sample of use: http://restlet.com/technical-resources/restlet-framework/guide/2.3/extensions/jaxrs. The classes for server resources need to be register by hand but you can go further. As a matter of fact, you can scan the classpath to detect classes having the annotation Path. See this link for the way to implement such ferature: Scanning Java annotations at runtime. In this case, they will be autodetected based on annotations. Is something can suit your needs?
Hope it helps.
Thierry
I've been going through this tutorial and they added a web service class instance to a hashSet, like this:
public class MessageApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public MessageApplication() {
singletons.add(new MessageRestService());
}
#Override
public Set<Object> getSingletons() {
return singletons;
}
}
I do not understand what the purpose of it is... I thought you could just access the web service with a URL
You made a class, this class is able to handle web requests. But this class has to be hosted somewhere. This means, this class has to be activated by a URL route. In this case you're using JBOSS.
In the first option of the tutorial, MKyong shows you how to configure RESTEasy Bootstrap (a bootstrap to load references) to map the URL with your class. This is done in web.xml and configures some kind of scanner that will map a certain URL with your class.
The second option is not using RESTEasy Bootstrap and you have to add your class to a collection of long living objects in your application manually. This is done defining the Application (MessageAplication) and defining it in the web.xml.
Yes, you can access the webservice via a URL, but the server needs to know what to do with calls to a certain URL.
Yours is one way (the bootstrap version) of telling the application server where to look for JAX-RS resources: http://www.mastertheboss.com/resteasy/resteasy-tutorial (Step #4)
There is a (newer) alternative, depending on which server and RESTeasy-version you use, which relies on autoscanning for certain annotations. For RESTeasy on JBoss, it's described at the bottom of the tutorial-page I linked.
I want to access static files, which are outside my web application in a known directory. I have read many options over the www, but I have still some questions about this.
Basically I want to declare a context for the defaultservlet of my application server. In my case I'm trying with the Tapestry Tutorial, which is a Maven based project and imported to eclipse.
The idea was to create a httpservlet, which gets the file from the location. Do someone of you know where I can grab an example of such a servlet and how I can call him? I know that the servlet must be probably declared as a service, because all pages of the application need to access the files, but I could also be mistaken and it is enough to import it, let say, in the layout page (All pages use the layout.tml file). I basically don't have any clue how to do it with a servlet. Can someone show me the light?
Tank you very much.
Another simpler solution is to create a page which returns a stream response
public class StaticFile {
StreamResponse onActivate(String fileName) {
return new StaticFileStreamResponse(fileName);
}
}
Then in another component / page
#Inject ComponentResources resources;
public Link getStaticFileLink() {
return resources.createPageRenderLinkWithContext("StaticFile", "path/to/myFile.jpg");
}
TML
<img src="${StaticFileLink}" />
But then you won't take advantage of tapestry's 304 NOT_MODIFIED response as in my other solution.
The tapestry way of doing this is by contributing an AssetRequestHandler and an AssetFactory.
AppModule.java
public static void contributeAssetDispatcher(
MappedConfiguration<String, AssetRequestHandler> config,
ResourceStreamer streamer)
{
config.add("staticfile", new StaticFileAssetRequestHandler(streamer));
}
public void contributeAssetSource(
MappedConfiguration<String, AssetFactory> config)
{
config.add("staticfile", new StaticFileAssetFactory());
}
Then in your tml you can use
<img src="${asset:staticfile:path/to/myFile.jpg}" />
Take a look at the ContextAssetRequestHandler, ClasspathAssetRequestHandler, ContextAssetFactory and ClasspathAssetFactory for inspiration.
Be careful not to open up a security hole where a hacker can access any file on your server by passing file paths prefixed with ../../
While trying to move an axis2 web-app from glassfish3 to tomcat6, I can't seem to find a way to get a config parameter from a static context.
In glassfish3, a system property was defined in a far away place and read from the application using System.getProperty(String name). Not only does the web agree that this is not the way to go for a web application, this trick is just not feasible for tomcat (tomcat docs).
Reading parameters from the ServletContext is also not feasible as the app uses axis2 and I can't seem to find a way to access any kind of servlet voodoo from the static context that initializes the app's configuration.
services.xml (the file containing the service description for axis2) can contain <parameter> nodes, so that seems a nice place to configure the configuration location, but I can't seem to find a way to read these parameters from the application.
So in short: any ideas on how to get a value configured outside the application's code available from a static context?
(answer listed here as StackOverflow does not allow me to answer my own question...)
After scouring the Internet some more, a solution was found using an implementation of org.apache.axis2.engine.ServiceLifeCycle, which could read a parameter in the startUp-method as such:
Parameter param = service.getParameter("name");
if (param != null) {
saveParamValue(param.getValue().toString());
} else {
// log warning on falling back to System.getProperty()
}
The life cycle class is attached using class="fully.qualified.ClassName" on the <service> node of the services.xml file used by axis2.
This works, now the application just crashes on something else (but that has little to with this issue).
The parameters in services.xml can be accessed by getting the ServiceContext object for the service, then calling ServiceContext.getParameter(). If your service implementation class implements the Lifecycle interface, then Axis2 will call Lifecycle.init() every time it creates a new instance of the service class. The argument to Lifecycle.init() is the service's ServiceContext. Your init() implementation could save the context object or look up the parameters that you're interested in.