Adding Jersey Configuration disables register view controller - spring

i am using springboot 1.5.2 and i am using jersey and jsf
i have mapping for default view / as follows:
#Bean
public WebMvcConfigurerAdapter defaultView() {
return new WebMvcConfigurerAdapter() {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/faces/public/login.xhtml");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}
};
}
before i added jersey configuration, it was working fine, and after i added the following jersey configuration it stopped working:
#Configuration
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(MyService.class);
}
}
when i remove the JerSeyConfig class, the mapping works fine, but when i add it, the mapping stops working, please advise how to make them both working together fine.

Could you try:
Annotate JerseyConfig with #Component instead of #Configuration and make sure package is being scanned via #ComponentScan in main class.
Make sure Spring MVC dispatcher servlet is mapped to a path different than Jersey servlet's, for instance:
# Spring MVC dispatcher servlet path. Needs to be different than Jersey's to enable/disable Actuator endpoints access (/info, /health, ...)
server.servlet-path: /
# Jersey dispatcher servlet
spring.jersey.application-path: /api
More details could be found at my blog post: Microservices using Spring Boot, Jersey, Swagger and Docker

Related

Configure path prefixes for different WebAPIs in one Spring Boot App

I have a Spring Boot App with several WebAPIs. How can I configure the path prefix of each WebAPI differently via application properties?
For example I have a UserRestController and a StarShipRestController. Both are part of different WebAPIs, but served by the same Spring Boot App. The RestControllers should only feature the last part of the URL to the resource. The path prefix should not be part of the RestController:
#RestController
#RequestMapping("users")
class UserRestController {
// methods...
}
and
#RestController
#RequestMapping("starships")
class StarShipRestController {
// methods...
}
The concrete path prefixes are in application.properties:
api.user.pathPrefix=/api/v1
api.starship.pathPrefix=/universe
The question is how to apply the path prefixes to the RestControllers?
If there was only one WebAPI in the Spring Boot App, I could use a WebMvcConfigurer. But that doesn't work because I have several WebAPIs.
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("api", HandlerTypePredicate.forAnnotation(RestController.class));
}
}
You can only have one context-path for a single Spring-Boot application (which can be configured using server.servlet.context-path). This means what you are asking is not possible.
The only way to achieve it is by changing the #RequestMapping annotations in your Controllers to include the full path that you want.
#RestController
#RequestMapping("/api/v1/users")
class UserRestController {
// methods...
}
#RestController
#RequestMapping("/universe/starships")
class StarShipRestController {
// methods...
}
To my knowledge, there is no other way.
Considering your request, I ask myself if you shouldn't have two different Spring-Boot applications instead of just one.

Spring Boot 2 Actuator without Spring Boot and #EnableAutoConfiguration

I am trying to set up Spring Actuator with existing Gradle Spring MVC project. I am not able to use #EnableAutoConfiguration.
Unfortunately, I am not able to reach actuator endpoints, I think I am missing something.
The Spring dependencies in the project are:
// springVersion = 5.1.+
implementation(
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-webmvc:$springVersion",
"org.springframework:spring-jdbc:$springVersion")
implementation 'org.springframework.boot:spring-boot-starter-actuator'
I am trying to configure project with following:
#Configuration
#Import({EndpointAutoConfiguration.class,
MetricsEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
MappingsEndpointAutoConfiguration.class,
InfoEndpointAutoConfiguration.class})
#EnableWebMvc
public class DI_App {
}
In properties file, I added:
management.endpoints.web.exposure.include=*
Non of actuator endpoints is enabled, I am getting 404 when trying to access them.
I went through many related questions, but non of the solutions worked for me.
I might need to define custom EndpointHandlerMapping but not sure how to do this, it seems unavailable.
(Ref: https://stackoverflow.com/a/53010693)
EDIT:
Currently, my app config looks like this:
#Configuration
#EnableWebMvc
#ComponentScan("com.test.springtest")
#Import({
ConfigurationPropertiesReportEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class,
InfoEndpointAutoConfiguration.class,
InfoContributorAutoConfiguration.class,
LogFileWebEndpointAutoConfiguration.class,
LoggersEndpointAutoConfiguration.class,
WebMvcMetricsAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class
})
public class DI_App {
private final ApplicationContext _applicationContext;
DI_App(ApplicationContext applicationContext) {
_applicationContext = applicationContext;
System.setProperty("management.endpoints.web.exposure.include", "*");
System.setProperty("management.endpoints.jmx.exposure.exclude", "*");
System.setProperty("management.endpoints.web.base-path", "/manage");
System.setProperty("management.server.port", "10100");
}
#Bean
public WebMvcEndpointHandlerMapping endpointHandlerMapping(Collection<ExposableWebEndpoint> endpoints) {
List<String> mediaTypes = List.of(MediaType.APPLICATION_JSON_VALUE, ActuatorMediaType.V2_JSON);
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes, mediaTypes);
WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(_applicationContext,
new ConversionServiceParameterValueMapper(),
endpointMediaTypes,
List.of(EndpointId::toString),
emptyList(),
emptyList());
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/manage"),
endpoints,
endpointMediaTypes,
new CorsConfiguration(),
new EndpointLinksResolver(discoverer.getEndpoints()));
}
}
I had to add dispatcherServlet bean, in order to be able to add ManagementContextAutoConfiguration.class to Imports:
#Component
public class AppDispatcherServlet implements DispatcherServletPath {
#Override
public String getPath() {
return "/";
}
}
Current state is that when going to /manage endpoint I get this:
{"_links":{"self":{"href":"http://localhost:10100/dev/manage","templated":false},"info":{"href":"http://localhost:10100/dev/manage/info","templated":false}}}
But http://localhost:10100/dev/manage/info returns 404 and no other endpoints are available.
I'm using Maven, not Gradle, but was in a similar situation. I had a working spring-boot-actuator 1.4.2.RELEASE Health actuator endpoint with Spring MVC 4.3.21. Upgraded to spring-boot-starter-actuator 2.6.1 and Spring MVC 5.3.13 and the following works for me to reach /myAppContext/health.
The DispatcherServletAutoConfiguration import may be able to replace your explicit DispatcherServlet bean. My case doesn't include the Info actuator endpoint but the key thing for me was the specific Imports below. Order is somewhat important for certain imports, at least in my testing.
I know very little about spring boot so this is the result of enabling auto configuration, pouring through spring boot TRACE log output, and trying lots of different import combinations.
#Configuration
#EnableWebMvc
#Import({
DispatcherServletAutoConfiguration.class,
WebMvcAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
WebMvcEndpointManagementContextConfiguration.class
})
#PropertySource("classpath:/health.properties")
public class MyAppActuatorConfig {
// 1.x version had EndpointHandlerMapping and HealthMvcEndpoint beans here.
// There may be a more spring-boot-ish way to get this done : )
}
And a minimal health.properties that suited my deployment specifics where security was already in place:
management.endpoints.web.base-path=/
management.endpoint.health.show-details=when-authorized
management.endpoint.health.show-components=when-authorized

Use Jersey Filter in Spring Boot Jersey

I have a Jersey rest API which we are planning to migrate to Spring boot.
I have a filter that implements ContainerRequestFilter and had #Provider annotation in the filter. I registered the filter in ResourceConfig. But still i don't see the filter executing.
However I do get a warning message:-
A provider "My Filter class" registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider "My Filter class" will be ignored.
I wanted to use jersey as servlet so changing the jersey to behave as filter is not working for my app.
Can someone help me on this?
Here is my code
Jersey filter
#Provider
public class CustomJerseyLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
#Override
public ContainerRequest filter(ContainerRequest request) { }
#Override
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { }
}
#Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(CustomJerseyLoggingFilter.class);
}
}
You're implementing the wrong ContainerRequestFilter. The one you are using is from Jersey 1.x. I don't know why you even have Jersey 1.x jars in your project. The ContainerRequestFilter (for 2.x) that you should be implementing is
javax.ws.rs.container.ContainerRequestFilter
javax.ws.rs.container.ContainerResponseFilter

Spring Boot with Custom Converters breaks Swagger & how to move it

I have a very simple Spring Boot application. I launch this through the basic SpringApplication.run(Startup.class, args); and have a custom #Configuration class in there that overrides the default converters. I decided to add Swagger to the mix of things so that I can generate better documentation for our internal user base as there are gads of endpoints.
When I started things up, Swagger simply wouldn't work.
I decided to start a front-scratch Spring Boot with just one endpoint to document to see what went wrong. Out-of-the box this worked perfectly fine and I was able to get Swagger running via just hitting the http://localhost:8080/swagger-ui.html base URL.
When I implemented my custom #Configuration class that extended WebMvcConfigurationSupport, Swagger no longer worked.
My configuration overrode a single method:
#Configuration
public class StartupConfiguration extends WebMvcConfigurationSupport {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(getJsonConverter());
}
}
That's it. I decided to add the default converters as well without any luck. Then I just emptied the class and left it as:
#Configuration
public class StartupConfiguration extends WebMvcConfigurationSupport {
}
Swagger is still broken - if I remove the class completely, then it works.
What can I do to keep my custom configuration data and run Swagger? I would also love to move it to something like http://localhost:8080/swagger/ rather than the default file it uses, but that is a completely separate issue for now.
My launch of Swagger looks like this:
#Configuration
#EnableSwagger2
public class SwaggerConfiguration {
#Bean
public Docket getDocket() {
// ...
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Core API")
.apiInfo(infoBuilder.build())
.select().paths(PathSelectors.regex("/*"))
.build();
}
}
Overriding the default resource handler worked for me. I added the following to the configuration class extending WebMvcConfigurationSupport:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

Add interceptor to spring boot mongodb rest example

I am trying to add an interceptor to a simple Spring-boot-mongodb-rest app, as can be seen here : http://spring.io/guides/gs/accessing-mongodb-data-rest/, in order to perform certain actions after the default rest handler is invoked. Here is my MongoRepository, whose CRUD operation is called upon a POST request to the server:
#RepositoryRestResource(collectionResourceRel = "reminder", path = "reminder")
public interface ReminderRepository extends MongoRepository<Reminder, String> {
List<Reminder> findBySendee(#Param("sendee") String sendee);
}
I am trying to register an interceptor for all HTTP requests by extending the WebMvcConfigurerAdapter class like this:
#Configuration
#ComponentScan
public class RemindxWebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new RemindxInterceptor());
}
}
As mentioned in the spring boot docs, I have not added the #EnableWebMvc annotation to this. While running the application, the addInterceptors function does get called and adds the interceptor. However, the given interceptor is not called after the POST handler is invoked. I am unable to figure out a way to have spring use this RemindxWebConfig for all MongoRepository http requests. Any inputs are appreciated.

Resources