Web SocketConfigurer - How to add controller - java

I'm new to web sockets so iv'e a few question. Since im using WebSocketConfigurer Interface with code implemented below:
#Configuration
#EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer{
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(this.socketHandler(), "/socket")
.addInterceptors(new AuthInterceptor())
.setAllowedOrigins("*")
.withSockJS();
}
#Bean
public WebSocketHandler socketHandler() {
return new PerConnectionWebSocketHandler(socketHandler.class);
}
}
1) Can i somehow add Controller that will listen to my /socket and execute commands when some1 sends message with destination /topic/user
something like:
#Controller
public class TestController {
#MessageMapping("/user")
#SendTo("/topic/user")
public String test() {
//TODO: do something usefull
}
}

You have to create one more configuration
#Configuration
#RequiredArgsConstructor
public class WebConfiguration implements WebMvcConfigurer {
....
}

Related

How to make viewController ignore server.servlet.context-path

I have the following configuration for serving static content from Spring Boot.
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Value("${frontend.location}")
private String frontendLocation;
#Override
public void addViewControllers(ViewControllerRegistry reg) {
reg.addViewController("/").setViewName("forward:/index.html");
reg.addViewController("/{x:[\\w\\-]+}").setViewName("forward:/index.html");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(frontendLocation);
}
}
This works fine as long as there is no server.servlet.context-path. When server.servlet.context-path is configured, it is being passed down to the frontend router as part of the URL.
The solution would be not to forward context path to index.html. How can I achieve that?

Injected Spring Bean is NULL in Spring Boot Application

I am using Spring Boot(1.5.3) to develop a REST Web Service. In order to take some action on incoming request I have added an interceptor shown below.
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Autowired
RequestParser requestParser;
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//HandlerMethod handlerMethod = (HandlerMethod) handler;
requestParser.parse(request);
return true;
}
}
RequestInterceptor has an autowired Spring Bean RequestParser responsible for parsing the request.
#Component
public class RequestParserDefault implements RequestParser {
#Override
public void parse(HttpServletRequest request) {
System.out.println("Parsing incomeing request");
}
}
Interceptor registration
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/usermanagement/v1/**");
}
}
And my Spring Boot Application
#SpringBootApplication
public class SpringBootApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
Now when a request comes in, it lands in preHandle method of RequestInterceptor but RequestParser is NULL. If I remove the #Component annotation from RequestParser I get an error during Spring context initialization No bean found of type RequestParser. That means RequestParser is registered as Spring bean in Spring context but why it is NULL at the time of injection? Any suggestions?
Your problem lies in this new RequestInterceptor().
Rewrite your WebMvcConfig to inject it, e.g. like this:
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Autowired
private RequestInterceptor requestInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor)
.addPathPatterns("/usermanagement/v1/**");
}
}

Add Bean and Interceptor to the context of an application from an external jar

I have a web application with the following configuration class:
#Configuration
#EnableWebMvc
#EnableSpringDataWebSupport
class CustomMvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public MyBean myBean() {
return new MyBean();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
}
I want to add a dependency of a jar on the application, add another bean and another interceptor to the context.In another project I have another WebMvcConfigurerAdapter class but it does not run:
#Configuration
#EnableWebMvc
#EnableSpringDataWebSupport
class OtherCustomMvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public OtherBean otherBean() {
return new OtherBean();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor());
}
}
If I try to inject the OtherBean into a class of the application web does not exist in context:
#Inject
private OtherBean otherBean;
And the CustomInterceptor does not run. How can I add beans and interceptors to an application from an external module?
I think you just need to add proper #Include annotation to your MVC Configuration.
#Include(OtherCustomMvcConfiguration.class)
class CustomMvcConfiguration extends WebMvcConfigurerAdapter {
...
}

How to register dynamique URL Handler for Spring WebSocket with #EnableWebSocket configuration?

Suppose that I have a WebSocket on the url:
wss://hostname:port/myapp/websocket
I have a Spring Configuration with an handler:
#Configuration
#EnableWebMvc
#EnableWebSocket
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer implements WebSocketConfigurer {
#Bean
public MySocketHandler mySocketHandler() {
return new MySocketHandler();
}
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(mySocketHandler(), "/websocket").setAllowedOrigins("*");
}
}
All fine, it works.
But how to implement a dynamique URL?
What I have to do if I have something like:
url1: wss://hostname:port/myapp/websocket/call01
url2: wss://hostname:port/myapp/websocket/call02
Thanks

Java config for spring interceptor where interceptor is using autowired spring beans

I want to add spring mvc interceptor as part of Java config. I already have a xml based config for this but I am trying to move to a Java config. For interceptors, I know that it can be done like this from the spring documentation-
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor());
}
}
But my interceptor is using a spring bean autowired into it like follows-
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
#Autowired
ISomeService someService;
...
}
The SomeService class looks like follows-
#Service
public class SomeService implements ISomeService {
...
}
I am using annotations like #Service for scanning the beans and have not specified them in the configuration class as #Bean
As my understanding, since java config uses new for creating the object, spring will not automatically inject the dependencies into it.
How can I add the interceptors like this as part of the java config?
Just do the following:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
LocaleInterceptor localInterceptor() {
return new LocalInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeInterceptor());
}
}
Of course LocaleInterceptor needs to be configured as a Spring bean somewhere (XML, Java Config or using annotations) in order for the relevant field of WebConfig to get injected.
The documentation for general customization of Spring's MVC configuration can be found here, and specifically for Interceptors see this section
When you handle the object creation for yourself like in:
registry.addInterceptor(new LocaleInterceptor());
there is no way the Spring container can manage that object for you and therefore make the necessary injection into your LocaleInterceptor.
Another way that could be more convenient for your situation, is to declare the managed #Bean in the #Configuration and use the method directly, like so:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public LocaleInterceptor localeInterceptor() {
return new LocaleInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor( localeInterceptor() );
}
}
Try to inject your service as a constructor parameter. It is simple.
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
ISomeService someService;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleInterceptor(someService));
}
}
Then reconfigure your interceptor,
public class LocaleInterceptor extends HandlerInterceptorAdaptor {
private final ISomeService someService;
public LocaleInterceptor(ISomeService someService) {
this.someService = someService;
}
}
Cheers !

Categories