How to find the togglz url when integrating with spring-boot and jersey - spring-boot

My application based on spring-boot and jersey. I have configured togglz in my application. I can successfully launch my web application but running gradle bootRun. From the output during the startup, I am able to see below log message. But I am not able to access http://localhost:8080/togglz. My application root path is "/" which is managed by jersey. It seems that spring-mvc works well with togglz but failed to access it when integrating with jersey. What should I do in order to let jersey to accept the url?
2016-03-30 18:40:35.191 INFO 81748 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/togglz || /togglz.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()

For Jersey 2 to work along with Spring MVC endpoints in a Spring Boot application, I would suggest to make sure your application.yml (or .properties makes such distinction, something like:
...
# 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
...
You could read more about this at my blog: http://tech.asimio.net/2016/04/05/Microservices-using-Spring-Boot-Jersey-Swagger-and-Docker.html#implement-api-endpoints-using-jersey
If you are integrating Jersey 1 with Spring MVC endpoints in a Spring Boot app, Spring Boot doesn't provide a jersey 1 starter so everything needs to be "manually" configured, but basically if your Jersey servlet is mapped to "/", you would need to configure it to let pass 404 to the servlet container for further handling (maybe a Spring MVC or plain servlet endpoint). Something like:
Jersey 1 resources configuration:
#ApplicationPath("/")
public class DemoResourcesConfig extends PackagesResourceConfig {
private static final Map<String, Object> properties() {
Map<String, Object> result = new HashMap<>();
result.put(PackagesResourceConfig.PROPERTY_PACKAGES, "com.sun.jersey;com.asimio.api.demo1.rest");
// To forward non-Jersey paths to servlet container for Spring Boot actuator endpoints to work.
result.put("com.sun.jersey.config.feature.FilterForwardOn404", "true");
result.put(JSONConfiguration.FEATURE_POJO_MAPPING, "true");
return result;
}
public DemoResourcesConfig() {
super(properties());
}
...
}
Jersey 1 resource implementation:
package com.asimio.api.demo1.rest;
...
#Component
#Path("/actors")
#Produces(MediaType.APPLICATION_JSON)
public class ActorResource {
#GET
public List<Actor> findActors() {
...
}
#GET
#Path("{id}")
public Actor getActor(#PathParam("id") String id) {
...
}
...
}
ServletContextInitializer bean
#Bean
public ServletContextInitializer servletInitializer() {
return new ServletContextInitializer() {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
final ServletRegistration.Dynamic appServlet = servletContext.addServlet("jersey-servlet", new SpringServlet());
Map<String, String> filterParameters = new HashMap<>();
// Set filter parameters
filterParameters.put("javax.ws.rs.Application", "com.asimio.api.demo1.config.DemoResourcesConfig");
appServlet.setInitParameters(filterParameters);
appServlet.setLoadOnStartup(2);
appServlet.addMapping("/*");
}
};
}
application.yml
...
# For Spring MVC to enable Endpoints access (/admin/info, /admin/health, ...) along with Jersey
server.servlet-path: /admin
...
More about Jersey 1 and Spring Boot / Cloud could be found at my blog: http://tech.asimio.net/2016/11/14/Microservices-Registration-and-Discovery-using-Spring-Cloud-Eureka-Ribbon-and-Feign.html#create-the-demo-service-1

Related

Defining multiple endpoints for multiple soap web services in spring boot application

I have a servlet mapping issue in spring boot application with multiple soap web services. I have two (or more) WebServices with different mappings.
Service A -> Endpoint1
Service B -> Endpoint2
Once I deploy spring boot application with two MessageDispatcherServlets , Service A and B both can be accessed with Endpoint1 only. I don't know how I can map Endpoint1 url to ServiceA and Endpoint2 to ServiceB.
Please check sample of my code for Service-A. Code is similar for Service-B.
#Bean(name = "ServiceA")
public Wsdl11Definition wsdl11DefinitionImportAgent() {
SimpleWsdl11Definition simpleWsdl11Definition = new SimpleWsdl11Definition();
simpleWsdl11Definition.setWsdl(new ClassPathResource("/wsdl/ServiceA.wsdl"));
return simpleWsdl11Definition;
}
#Bean
public ServletRegistrationBean messageDispatcherServletServiceA(ApplicationContext
applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/ServiceA");
}

Spring boot MessageDispatcherServlet overriding DispatcherServlet. how to skip overriding and register both DispatcherServlet?

in a single application, I m trying to use soap as well as rest web service. and each servlet is given different URI, below is the code of config class.
The question is: only soap service URL is working fine but for the rest on getting 405 error.
#EnableWs
#Configuration
public class WebServiceConfig {
#Bean
public ServletRegistrationBean RsRegistrationBean(ApplicationContext applicationContext) {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(applicationContext);
return new ServletRegistrationBean(servlet,"/rest/*");
}
#Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(
ApplicationContext context) {
MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet();
messageDispatcherServlet.setApplicationContext(context);
messageDispatcherServlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(messageDispatcherServlet,"/");
}
}
Remove your WebServiceConfig class, as both are auto-configured by Spring Boot already (as of Spring Boot 1.4). Add the following to your application.properties
spring.mvc.servlet.path=/rest
spring.webservices.path=/
Now you leverage the Spring Boot proivded infrastructure instead of fighting with it.

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

Avoid automatic servlet mapping for a Servlet created as a #Bean in Spring Boot

I have a servlet to which I need to supply dependencies via autowiring (it's a class from an external library, I cannot change its code). I try to register it as a bean and later register it using programmatic registration (ServletContextInitializer). Here is what I have:
#Configuration
public class MyConfiguration {
#Bean
public MyServlet myServlet() {
return new MyServlet();
}
}
Also, SpringMVC-related autoconfiguration creates a usual DispatcherServlet and maps it at /.
When I try to start the application, I get the following:
Caused by: java.lang.IllegalStateException: Multiple servlets map to path /: dispatcherServlet[mapped:JAVAX_API:null],myServlet[mapped:JAVAX_API:null]
So it looks like Spring Boot (or Spring itself?) automatically maps the servlet at the default /. I would like to avoid the mapping at all as I just need to create the servlet instance; I will register it myself later.
Can this be done?
you should use a ServletRegistrationBean then you can provide an extra mapping
#Bean
public MyServlet myServlet() {
return new MyServlet();
}
#Bean
public ServletRegistrationBean myServletRegistration(MyServlet myServlet) {
    ServletRegistrationBean registration = new ServletRegistrationBean(myServlet,
"/myservlet/*");
registration.setLoadOnStartup(1);
    return registration;
}

Adding Jersey Configuration disables register view controller

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

Resources