Swagger UI and CXF No operations defined in spec - java

I am building Spring Boot app with Apache CXF . While trying to add swagger I get No operations defined in spec! error, though I specified via annotations 1-2 opeations.
The part of CXF config for Swagger is below:
factory.setFeatures(Collections.singletonList(createSwaggerFeature()));
public Swagger2Feature createSwaggerFeature() {
Swagger2Feature swagger2Feature = new Swagger2Feature();
swagger2Feature.setPrettyPrint(true);
swagger2Feature.setSupportSwaggerUi(true);
swagger2Feature.setScanAllResources(true);
swagger2Feature.setHost("localhost:8080");
swagger2Feature.setBasePath("/cxf/todo_list");
swagger2Feature.setTitle("TodoList Application");
swagger2Feature.setContact("https://www.github/abondar24");
swagger2Feature.setDescription("Another TodoList application with Spring Boot and Swagger");
swagger2Feature.setVersion("1.0.0");
return swagger2Feature;
}
I believe feature isn't set correctly.What am I missing?
The link for api-docs is like this: http://localhost:8080/cxf/todo_list/api-docs?url=/cxf/todo_list/swagger.json
In explore field on UI page: /cxf/todo_list/swagger.json

I have solved the problem. I forgot to put #Path annotation to my REST-service. After I did it swagger started working. The only thing I don't understand - how to get rid of default tag

I too had the same problem,
I fixed it by Modifying controller module
Here i changed from #Controller => to #RestController and it worked.

Related

Using Java and Spring Boot and my #Value annotation for my application-dev.properties is not being resolved?

This is my very first question so I apologize if it is not specific enough (please be gentle haha) and I have already gone through documentation, but I am new to the field and none of it helped.
I am making a simple project that uses Java 18 and Spring Boot to make a call to an external API call and I want to hide my API key that I use for obvious reasons.
As of right now, I have an application-dev.properties file in my resources directory with the following (I am making up the actual key for security) and I have application-dev.properties in my .gitignore file so it doesn't get committed:
api-key=someText
And I am trying to use that value in my controller like so:
#RestController
public class ImageController {
#Value("${api-key}")
private String API_KEY;
#RequestMapping(value = "/image")
public List<String> getImages(#RequestParam(defaultValue = "4") String request) {
String url = "https://api.nasa.gov/planetary/apod?" + API_KEY + request;
RestTemplate restTemplate = new RestTemplate();
The error I am receiving is this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'imageController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'api-key' in value "${api-key}"
Thanks in advance!
As mentioned in the other answer,
the name of the application-dev.properties file requires that
you activate the "dev" profile or Spring Boot will never read it and the
values therein will not be available to your #Value annotation.
Here is a link to a Baeldung article that discusses Spring Boot profiles:
Spring Boot Profiles at Baeldung
(I am not associated with Baeldung,
I just like much of their stuff).
If you are not planning to use profiles in your application,
change the name of the properties file to "application.properties".
As you mentioned you are using application-dev.properties therefore you have to do profiling correctly. In your application.properties add spring.profiles.active=dev to activate dev profile.

How to configure springdoc ui without mapping the root path?

I'm trying to configure springdoc-openapi-ui in a spring web app (non-springboot). In my application I have a controller that is mapped to "/" which conflicts with the Springdoc SwaggerUiHome Controller. I get an error similar to this:
java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'swaggerUiHome' method 'org.springdoc.webmvc.ui.SwaggerUiHome#index() to {GET [/]}: There is already 'loginLogoutController' bean method com.company.MyController#method() mapped.
If I disable my controller which is mapped to '/' then the swagger UI comes up as expected. However, I need to have my controller running in order for my web app to work.
Even if I set 'springdoc.swagger-ui.use-root-path=false' (which should be the default anyway) it is still causing an ambiguous mapping error.
Is there any way around this? Any way to disable the default mapping of the SwaggerUiHome.index() to '/'?
SwaggerUiHome is only invoked if you define: springdoc.swagger-ui.use-root-path=true
To disable it: springdoc.swagger-ui.use-root-path=false
Note that default path of the swagger-ui is not the root path, but: http://server:port/context-path/swagger-ui.html
I'm getting this error if using regular spring framework (not using spring-boot). After dig into the source /springdoc-openapi-starter-webmvc-ui-2.0.2.jar/org.springdoc.webmvc.ui/SwaggerConfig.class
#Bean
#ConditionalOnMissingBean
#ConditionalOnProperty(name = SPRINGDOC_USE_ROOT_PATH, havingValue = "true")
#Lazy(false)
SwaggerUiHome swaggerUiHome() {
return new SwaggerUiHome();
}
Found that String SPRINGDOC_USE_ROOT_PATH = "springdoc.swagger-ui.use-root-path". I guess there maybe a bug that this property is not working for springdoc.swagger-ui.use-root-path=false
Here is my working solution after reading https://www.baeldung.com/spring-requestmapping#4-ambiguous-mapping-error
#GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE)
public String index() {
return "home";
}

Spring app with React UI - how to serve when #EnableWebMvc is applied?

So I have a React app I want to serve from my Spring app (ala this blog). As part of my gradle build task, I run the npm build command and copy the resulting files to /build/resources/main/static. This works fine and I can access my app at mysite.com/index.html, but I want to control who has access more granularly. As such, I applied #EnableWebMvc to my app, but from there, I can't seem to get my API controller to actually serve the view from the build directory. It seems no matter where I put it, it doesn't like serving directly from /build. Any way to make this work?
The handler looks like:
#Controller
class MyController {
#RequestMapping("/")
fun index(): String {
return "index"
}
}
As indicated in the Spring Boot documentation, you do not need - in fact, it is not recommended - to use #EnableWebMvc when using Spring Boot. They state, when describing Spring MVC auto-configuration:
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
And:
If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own #Configuration class of type WebMvcConfigurer but without #EnableWebMvc.
In the guide, they continue when describing static content handling:
By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so that you can modify that behavior by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.
In your example, following this advice, you can indicate the static resource handling location with something like (sorry, I am not fluent in Kotlin, forgive for write the example in Java):
#Controller
public class MyController implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static")
;
}
#GetMapping(path = "/")
public String index() {
return "index";
}
}
Please, adapt the paths in addResourceHandlers to your needs.
You can of course place this method in an ad hoc #Configuration.
Having said that, if when you say granular you mean security, the best approach you can take is to configure Spring Security and provide the necessary authorization rules: please, see the relevant documentation.

Enable schemaCreationSupport in spring-boot-starter-data-solr

I use spring-boot-starter-data-solr and would like to make use of the schmea cration support of Spring Data Solr, as stated in the documentation:
Automatic schema population will inspect your domain types whenever the applications context is refreshed and populate new fields to your index based on the properties configuration. This requires solr to run in Schemaless Mode.
However, I am not able to achieve this. As far as I can see, the Spring Boot starter does not enable the schemaCreationSupport flag on the #EnableSolrRepositories annotation. So what I tried is the following:
#SpringBootApplication
#EnableSolrRepositories(schemaCreationSupport = true)
public class MyApplication {
#Bean
public SolrOperations solrTemplate(SolrClient solr) {
return new SolrTemplate(solr);
}
}
But looking in Wireshark I cannot see any calls to the Solr Schema API when saving new entities through the repository.
Is this intended to work, or what am I missing? I am using Solr 6.2.0 with Spring Boot 1.4.1.
I've run into the same problem. After some debugging, I've found the root cause why the schema creation (or update) is not happening at all:
By using the #EnableSolrRepositories annotation, an Spring extension will add a factory-bean to the context that creates the SolrTemplate that is used in the repositories. This template initialises a SolrPersistentEntitySchemaCreator, which should do the creation/update.
public void afterPropertiesSet() {
if (this.mappingContext == null) {
this.mappingContext = new SimpleSolrMappingContext(
new SolrPersistentEntitySchemaCreator(this.solrClientFactory)
.enable(this.schemaCreationFeatures));
}
// ...
}
Problem is that the flag schemaCreationFeatures (which enables the creator) is set after the factory calls the afterPropertiesSet(), so it's impossible for the creator to do it's work.
I'll create an issue in the spring-data-solr issue tracker. Don't see any workaround right now, other either having a custom fork/build of spring-data or extend a bunch of spring-classes and trying to get the flag set before by using (but doubt of this can be done).

Spring Security #Secured annotation and Scala controller

In a mixed Java/Scala Spring (v3.2) project I want to create a scala-based controller, and secure it with #Secure annotation. For java controllers this works just fine, but when I add #Secure annotation to the scala controller it disappears from URL mapping on application startup.
Sample code:
#Controller
#Secured(Array("ROLE_USER"))
class TestController {
#RequestMapping(value = Array("/show"), method = Array(RequestMethod.GET))
def show = {
"helloTemplate"
}
}
The same if I put secure annotation per method - the whole controller class will disappear from URL mapping (even if there are unsecured methods). No exceptions or warnings in the log. If I secure this URL via spring-security intercept-url in xml configuration - all things works fine (without #Secure annotation on controller). Spring and spring-security configuration via xml files and annotation-driven configuration is turned on. Thank you for any help.
In Spring 4/Spring you must enable proxyTargetClass = true to use CGLIB class proxying. This is superior to java class Proxying when working with scala.
SpringBoot
#EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)

Categories

Resources