I am using spring boot application mvc with graphDb (Neo4j) as my database.
And I have problem when I have to do internationalization for my app.
I have this code on my application.java
public class Application extends Neo4jConfiguration {
#Autowired
GraphDatabase graphDatabase;
#Bean
GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("my-graphdb");
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When I tried to implement internationalization, the tutor says that I need to implement:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
This code above need the class is extended by WebMvcConfigurerAdapter.
This is the problem, I didn't use WebMvcConfigurerAdapter so I cannot add the method above.
Do I have another option to make my internationalization work well with Neo4jConfiguration?
I just found out how to make it work.
I just have to add new file that extend WebMvcConfigurerAdapter and put the addInterceptors module into that new file.
Which tutorial are you referring to?
you can also create your own Neo4jConfiguration subclass and #Import it onto your boot application context
Related
I'm developing a jar library and trying to inject an interceptor from external jar library to Application.
For example:
External Lib
MyExternalInterceptor.java
public class MyExternalInterceptor implements HandlerInterceptor {
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// Do something
}
}
I tried to using AOP in external libs but it's not working.
InterceptorAspect.java
#Around("execution(* org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.addInterceptors(..))")
public Object aspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// Tried to inject MyExternalInterceptor here
Object result = proceedingJoinPoint.proceed();
return result;
}
In Application using that lib:
Application
MyConfiguration.java
#Configuration
public MyConfiguration extends WebMvcConfigurationSupport {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SpringTestInterceptor()); // client's own interceptor
/* Add MyExternalInterceptor not explicitly but implicitly using AOP or other things */
}
}
Is there any way to inject an interceptor from external lib to App?
I know the question is very obscure (sorry for that), but could you give me any advice or hint to make it work?
Thank you for anyone who read my question :)
(I updated few more details for clarification)
Summary
Use WebMvcConfigurer in both Client and library side instead of WebMvcConfigurationSupport
AoP is not needed
I use WebMvcConfigurer instead of WebMvcConfigurationSupport and change some codes like below:
External Lib
MyExternalInterceptor.java
Same as before
InterfaceAspect.java
Don't needed it anymore
MyExternalLibConfiguration.java
#Configuration
public class MyExternalLibConfiguration implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyExternalInterceptor());
}
}
Application (client)
MyConfiguration.java
#Configuration
public MyConfiguration implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SpringTestInterceptor()); // client's own interceptor
/* No need to add MyExternalInterceptor in here */
}
}
That's all! Everything is working well as M. Deinum said in comment.
Thank you again Deinum!
I'm trying to create a demo AOP application but it just does not work right.
I read through all tutorials and got it working with #RestController but as I tried it with a plain java spring driven application I just can't get it to work. Please review my files and tell me where my mistake lies in.
Application Class
#SpringBootApplication
#ComponentScan("com.xetra.experimental")
#EnableAspectJAutoProxy
public class AoptryoutnowebApplication {
public static void main(String[] args) {
SpringApplication.run(AoptryoutnowebApplication.class, args);
DefaultClassToAspectImpl defaultClassToAspectImpl = new DefaultClassToAspectImpl();
defaultClassToAspectImpl.doStuff();
}
}
ClassToAspect Interface
public interface ClassToAspect {
void doStuff();
}
ClassToAspect Implementation
#Component
public class DefaultClassToAspectImpl implements ClassToAspect {
#FooAnnotation
public void doStuff(){
System.out.println("DoStuff!");
}
}
Annotation for Pointcut
public #interface FooAnnotation {
}
Aspect Class
#Aspect
public class FooAspect {
#Pointcut("#annotation(FooAnnotation)")
public void methods(){
}
#Before("methods()")
public void doAspect(){
System.out.println("FooAspect before");
}
}
Try this:
replace #EnableAspectJAutoProxy with #EnableAspectJAutoProxy(proxyTargetClass = false)
change pointcut to
#Pointcut("execution (* your.package..*.*(..)) && #annotation(fooAnnotation))")
The problem is you are using a non Spring managed instance by doing new DefaultClassToAspectImpl(). Spring AOP only works for Spring managed beans, because by default Spring AOP is proxy based.
So instead of doing new DefaultClassToAspectImpl() you should be obtaining the instance from the ApplicationContext. When using Spring Boot the SpringApplication.run call returns an ApplicationContext. Here you can use one of the getBean methods to obtain the instance you want.
ApplicationContext ctx = SpringApplication.run(AoptryoutnowebApplication.class, args);
ClassToAspect bean = getBean(ClassToAspect.class);
bean.doStuff();
This way you get the Spring managed
I am using Spring boot with jersey. Here, I extend SpringBootServletInitializer with my Application class
#SpringBootApplication
#ComponentScan({"com.pqr.configuration", "com.pqr.other"})
class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApplication .class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication .class);
}
}
/*jersey config class*/
#Configuration
#ApplicationPath("/rest")
class JerseyConfig extends org.glassfish.jersey.server.ResourceConfig{
public JerseyConfig() {
packages("com.pqr.service");
}
}
I want to understand how the controller communicates with DispatcherServlet here and url are handled? If there is another flow, please mention. There are many concepts involved like Restcontrollers, InternalViewResolver, UrlHandler etc. I need to know what exactly happens in background?
I notice that Spring Boot application classes can extend other classes, but that the main(String[] args) methods generally all use SpringApplication.run(Application.class, args). The examples often use different annotations above the Application class definition.
This OP asks for a simple summary of three closely related questions:
1.) What are the possible classes that a Spring Boot Application.java class can extend?
2.) What are the intended uses of each of the extension options?
3.) And does the choice of a given extension also dictate specific annotations that must be added to the class definition?
From my research, I have identified the following three extension options:
1.) Extend nothing at all, as per this example:
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2.) Extend WebMvcConfigurerAdapter, as per this example:
#SpringBootApplication
#Controller
public class UiApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(UiApplication.class, args);
}
}
3.) Extend SpringBootServletInitializer, as per this example:
#Configuration
#EnableAutoConfiguration
#EnableScheduling
#ComponentScan
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String... args) {
System.setProperty("spring.profiles.default", System.getProperty("spring.profiles.default", "dev"));
final ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
}
}
Notice that I kept the annotations and minimal other stuff from the examples. This OP asks simply if specific annotation choices or minimal other stuff are dictated by the choice of extension.
Another one, which is not inheritance but it's composition, is to implement the CommandLineRunner interface so that you can perform some operations when the Spring Boot application starts up, like so:
#SpringBootApplication
public class DevopsbuddyApplication implements CommandLineRunner {
/** The application logger */
private static final Logger LOG = LoggerFactory.getLogger(DevopsbuddyApplication.class);
#Autowired
private UserService userService;
#Value("${webmaster.username}")
private String webmasterUsername;
#Value("${webmaster.password}")
private String webmasterPassword;
#Value("${webmaster.email}")
private String webmasterEmail;
public static void main(String[] args) {
SpringApplication.run(DevopsbuddyApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
User user = UserUtils.createBasicUser(webmasterUsername, webmasterEmail);
user.setPassword(webmasterPassword);
Set<UserRole> userRoles = new HashSet<>();
userRoles.add(new UserRole(user, new Role(RolesEnum.ADMIN)));
LOG.debug("Creating user with username {}", user.getUsername());
userService.createUser(user, PlansEnum.PRO, userRoles);
LOG.info("User {} created", user.getUsername());
}
}
Not sure if this is what you're looking for though.
I have a Spring Rest controller and its NOT spring boot application. Its just a REST API Project. I want to integrate swagger2 in my project. I tried all the examples in Net and in demo but with no luck. When i try to execute http://localhost:8085/context/swagger-ui.html i get 404 error. Please find my confugration below and let me know if there is any discrepencies. Any help is highly appreciated.
jars - under /WEB-INF/lib
google-collections-1.0.jar
springfox-core-2.2.2.jar
springfox-schema-2.2.2.jar
springfox-spi-2.2.2.jar
springfox-spring-web-2.2.2.jar
springfox-staticdocs-2.2.2.jar
springfox-swagger-common-2.2.2.jar
springfox-swagger-ui-2.2.2.jar
springfox-swagger2-2.2.2.jar
My swagger config class -
#EnableSwagger2
public class SwaggerConfiguration {
}
My springconfig class
#EnableWebMvc
#ComponentScan(basePackageClasses = controller.class)
#Import(SwaggerConfiguration.class)
public class SpringConfiguration extends WebMvcConfigurerAdapter {
#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/");
}
}
My Application initializer class below as per springfox-java demo . I tried with and without the below class and its not working either way.
Application Initializer class
public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{controller.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/*"};
}
}
I can access my rest urls but not swagger-ui.html in the same context.
Please let me know what i am missing here?
I add the manual selection of controllers:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("my.package.to.api"))
.paths(regex("/product.*")) //optional
.build();
}
}
given details are not sufficient to reproduce/analyse the issue.
But, today I faced similar problem, ofcourse used SpringBoot, and solved myself as below:
as my sample have one controller class and an application class having main method, I created packages as below, and it got solved:
hello
controllers
HelloController
swagger
SwaggerConfig2
HelloApplication