Swagger UI displays Error still after using validatorUrl as null - java

Though the scenario, if I was to describe, is similar to
Swagger UI Displays but I get an "ERROR" indicator. Everything works fine for me, my routes are listed properly, but the Error is displayed and the solution suggested on all such similar threads is pertaining to setting validationUrl=null.
I am using the following dependencies -
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>io.federecio</groupId>
<artifactId>dropwizard-swagger</artifactId>
<version>0.7.0</version>
</dependency>
This is what my register code looks like -
#Override
public void initialize(Bootstrap<CustomServiceConfig> bootstrap) {
bootstrap.addBundle(new SwaggerBundle<CustomServiceConfig>() {
#Override
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(
CustomServiceConfig customServiceConfig) {
return customServiceConfig.getSwaggerBundleConfiguration();
}
});
}
where these configuration in the config.yml are -
swagger:
title: Custom Service
description: APIs for Test
contact: me#alias.com
uriPrefix: /
resourcePackage: com.x.y.package
I've tried updating the SwaggerBundleConfiguration in the above .yml to add
validatorUrl=null
But this doesn't seem to be fixing the issue either. How can this be solved?

Inserting validatorURL: null into the constructor for the swagger ui has to happen in the swagger index.html file, not the Dropwizard yaml configuration file [see the SO post you referenced].
So you have a couple options, but to start I wouldn't recommend the dropwizard-swagger package because it seems to have fallen rather far behind Dropwizard itself. According to the version documentation on its page, it only supports up to Dropwizard 0.8 and swagger-ui 2.4. Dropwizard is at 1.x and the swagger-ui 3.x.
Option 1
If you do away with the dropwizard-swagger lib you can put the swagger-ui assets directly into your project under resources directory and add an AssetBundle to your Dropwizard application. This bundle allows serving of static content on your classpath. The static html you'll need is all in the dist folder here (i.e. copy it to /resources in your dropwizard project).
You'd have something like
#Override
public void initialize(Bootstrap<CustomServiceConfig> bootstrap) {
bootstrap.addBundle(new AssetsBundle("/assets/swagger", "/swagger", "index.html"));
}
which will serve the swagger UI on localhost:<port>/swagger like the dropwizard-swagger lib does.
For this solution to work, you'll need to generate the swagger json file as well and put that into the correct path in your build directory (resources path too). The swagger-maven-plugin can help do this for you. Here is a link to some discussion around how to bundle the static swagger ui and swagger json in your app. You'll need to modify the index.html to point at your swagger json file. The line of code is here.
const ui = SwaggerUIBundle({
url: "/path/relative/to/your/java/jar/swagger-api.json",
validatorUrl: null,
...
}
Option 2
You can fork the dropwizard-swagger code, modify the index.html file that is include to have validatorUrl: null set. The place you need to add this is in the constructor for the SwaggerUI js object. You can see it here.
In brief:
window.swaggerUi = new SwaggerUi({
url: url,
validatorUrl: null,
...
}
You'll then need to rebuild the library and include in your project this modified version of dropwizard-swagger library. Note that the dropwizard-swagger project just happens to create an AssetBundle for you.
Summary
Either way you'll need to modify the index.html file that is part of the swagger ui distribution. The easiest way forward may be to just ignore the error icon for now.

Related

Including DevTools in Spring Boot's JAR with Gradle during development

I've been looking for an answer but pretty much everything I found so far is either outdated or didn't work. I'd like to include Spring DevTools inside my JAR so that I can use live reloading feature.
What I did so far;
Built a Docker image with ./gradlew bootBuildImage.
Created a docker-compose.yml which uses this image.
Changed configuration in IntelliJ to use org.springframework.boot.devtools.RemoteSpringApplication as the main class.
However, when I change something and build the project I always get the same error:
Exception in thread "File Watcher" java.lang.IllegalStateException: Unexpected 404 NOT_FOUND response uploading class files
Do I need to change the way I build the image or apply some additional Gradle configuration for this to work? With Maven it was enough to just set excludeDevTools to false but looks like it doesn't work with Gradle.
Solved it by adding this in the build.gradle.kts;
tasks.getByName<BootJar>("bootJar") {
classpath(configurations["developmentOnly"])
}

Configure Swagger UI (Jersey REST API with Maven/Tomcat)

I have found similar Stack Overflow posts for configuring Swagger + SwaggerUI + Jersey, but almost all of these use Spring and I have not been able to find a solution for what I am trying to do.
I have Swagger + Jersey working, and have copied the swagger-ui/dist folder from: https://github.com/swagger-api/swagger-ui to my webapp directory, and have edited swagger-ui/dist/index.html file to point to my swagger.json output. I can properly access Swagger UI at http://localhost:{port}/{base-path}/dist/index.html
However, I do not want to have to copy the pre-build dist files to my webapp directory every time I need to fetch updates. I would like to automate this with Maven (which I am new to as well as Jersey/Swagger), and found this dependency online: https://mvnrepository.com/artifact/org.webjars/swagger-ui/2.0.12
However, I do not understand how to configure the path from my webserver to this webjar dependency.
To recap, I have Swagger UI working on my local machine, but only by manually copying the pre-build files to my webapp directory and would like some way to automate this (I have found solutions using Spring, but I am not using this).

Spring boot serving static resource

I work on spring boot application. I'm trying to serve static content with spring.
want to serve a resource stored in the /c:/frontend/files/ directory whenever a request comes in for the URL matching the pattern: /file/**:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/file/**")
.addResourceLocations("file:///C:/frontend/files/" );
}
but when i try to access to this resource using this url: http://localhost:9999/file/app.min.js
I have this problem
There was an unexpected error (type=Not Acceptable, status=406).
Could not find acceptable representation
I resolved the problem. it's related to "spring-cloud-config-server". I just delete this config: org.springframework.cloud spring-cloud-config-server
It sounds like your project's folder structure is wrong.
Code should go under src/main/java and resources (like your javascript) should go under src/main/resources. You have a few different options where you can actually serve the files from. This post on the spring.io blog has the following to say:
Spring Boot will automatically add static web resources located within any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
Another option you also have is using webjars.
Personally, I've found it easiest to put those kind of files under src/main/resources/public. It always works without any issues for me. The interesting thing is you can put a folder named /public anywhere in your project and spring-boot will serve files out of it. You have to be really careful that it's under src/main/resources/public though if you're using a build tool like maven, as when you come to build your .jar the files won't be in the right place otherwise.

Disable caching of static assets in Dropwizard

I have a Dropwizard webserver with a rest api which also serves some static content like html, css, javascript and jpg images. Unfortunately, when I change the html or add another image, the server always needs to be restarted to turn changes into effect.
As I thought that it might be a problem of caching, I explored bazaarvoice's Configurable Assets Bundle.
That's what I added to the configuration class:
#Valid
#NotNull
#JsonProperty
private final AssetsConfiguration assets = new AssetsConfiguration();
And in the main class
#Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
// ...
CacheBuilderSpec cacheBuilderSpec = CacheBuilderSpec.disableCaching();
bootstrap.addBundle(new ConfiguredAssetsBundle("/html", cacheBuilderSpec, "/", "index.html", "Static assets"));
}
#Override
public void run(MyConfiguration config, Environment env) {
env.jersey().setUrlPattern("/api/*");
// ...
}
No changes in the yaml configuration.
The static files are located in src/main/resources/html.
How can caching be disabled such that Dropwizard shows changes instantly?
And second question, how can I make Dropwizard follow symbolic links from the assets directory?
Update
I found this in the ConfiguredAssetsBundle source:
// Let the cache spec from the configuration override the one specified in the code
CacheBuilderSpec spec = (config.getCacheSpec() != null)
? CacheBuilderSpec.parse(config.getCacheSpec())
: cacheBuilderSpec;
This certainly overrides the cache builder spec which was set in the code with the configuration from the yaml file. After append
assets:
cacheSpec: maximumSize=0
to the configuration, the debugger shows that maximum size is now 0. However, behaviour did not change.
Static content doesn't change not because you need to restart, but because the running server actually serves files under the target directory. Changing the files in this directory only confuses things (so it's not really a solution), but change a few lines and wait a second to verify that the server now serves the modified file with no need to restart.
As a solution, I prefer opening the dropwizard project as a maven project in eclipse and run the project with mvn exec:java on a terminal, using the exec-maven-plugin. Eclipse updates the target directory as files change, but it takes a few seconds, depending on the size of the project.

How to write Jersey Multipart webapp, Tomcat Server

I've been doing a lot of REST tutorials and enjoying them. Recently, I tried writing a jersey multipart webapp with Netbeans but I can't seem to because it seems something's missing my jersey library.
I downloaded the jersey-multipart.jar file, but still that didn't help:
#Path("/file")
public class UploadFileService {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileDetail) {
This code is from blog. I'm trying to put it in my webapp, but the #FormDataParam tag and the FormDataContentDisposition class are not recognised. I downloaded the jersey-multipart.jar and that seemed to solve the #FormDataParam tag problem, but not the FormDataContentDisposition class.
I'm using Tomcat 7.0.
How do I go about successfully creating a jersey multipart webapp without any problems? And how come the jersey-multipart jar file isn't included in the jersey library in Netbeans?
Thanks.
Lutz Horn has a point, but for the sake of those using Netbeans 7.4 (Java EE 6) and are still struggling with this issue, here's a step by step on how to create your very own multipart rest web service and deploying on Tomcat, with Netbeans. (Note, deploying on Glassfish requires a slightly different configuration which isn't covered in this answer).
First off, my suggestion is to create a maven web application and not a normal web application. Reason is, the JAX-RS and Jersey libraries that come with Java EE 6 are not sufficient enough, and once you start fiddling around with external jars, things tend to get messy, especially with Jersey. (Hopefully, this has been corrected in Netbeans 8.0 (Java EE 7)).
(1) Create a maven web-app, choose Java EE 6 and Tomcat 7. Once you're done, you'll notice you don't have a web.xml. Most multipart tutorials will tell you to include certain configurations in your web.xml file. Don't bother with that. You don't need a web.xml file.
(2) Create a RESTfull web service by either writing it manually or using the wizard (right click on your maven web-app -- New -- Other -- Web Services -- [choose the RESTful web service you want])
(3) Open your pom.xml (you can find it under the Project Files folder in your maven web-app) and add these dependencies:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.7</version>
</dependency>
If you're doing this for the first time, you need an active internet connection, as maven will download the dependencies from its central repository.
(4) Go to your ApplicationConfig class or whatever class that holds that contains your #ApplicationPath(). It should look like this:
#javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
resources.add(MultiPartFeature.class);
addRestResourceClasses(resources);
return resources;
}
/**
* Do not modify addRestResourceClasses() method.
* It is automatically populated with
* all resources defined in the project.
* If required, comment out calling this method in getClasses().
*/
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.mycompany.mavenrestuploader.UploaderResource.class);
}
Note: resources.add(MultiPartFeature.class); That has to be included, otherwise Jersey multipart won't work.
The reason I put that line of code in the getClasses method and not the addRestResourceClasses method is because the addRestResourceClasses method gets modified whenever there's a change to your resource class, and if you include the MultiPartFeature code in there, it will get erased.
Once you've done all these things, you are good to go.
If you're just looking to create a RESTful web service without multipart, follow steps 1 to 3, but in step 3 do not include the jersey-media-multipart dependency.
I hope this helps you ;)
The imports for these two are
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
If you use Maven, add this dependencies:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.0</version>
<type>jar</type>
</dependency>
Together with jersey-media-multipart dependency, instead of Application (see below) you can configure ResourceConfig:
#ApplicationPath("/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("packages.to.scan");
register(MultiPartFeature.class);
}
}
or Jersey REST configuration in web.xml:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

Categories