Write a Spring Web Socket project without SpringBoot or Maven/Gradle - java

How to create a Spring Java Web socket project with XML or Java Config but without Spring Boot. Where can I find a step-by-step tutorial. I dont know how to use spring boot in ecliplse. Also I dont want to use gradle or maven. I did not find a tutorial to use spring boot in eclipse. As I am new to spring I am unable to start a project without maven or gradle. I need to learn how to create a spring project without any built tool provided I need to use Eclipse. This is purly for learning puropse.
Below is the classes I used to replace Spring boot related main class
AppConfig Class
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan("hello")
#EnableWebMvc
public class AppConfig {
}
WebAppInitializer Class
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer{// extends AbstractAnnotationConfigDispatcherServletInitializer {
public void onStartup(ServletContext servletContext) throws ServletException
{
try
{
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(servletContext);
Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
dynamic.addMapping("/");
// dynamic.addMapping("/springStomp/");
dynamic.setLoadOnStartup(1);
//dynamic.setAsyncSupported(true);
//ctx.refresh();
System.out.println("config done");
}
catch(Exception e)
{
e.printStackTrace();
System.out.println("error");
}
}
}
WebSocketConfig Class
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
System.out.println("inside websocket config class");
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/hello").withSockJS();
}
}
Remaining is same as in spring web socket tutorial

I know how that feels, my company network is unfriendly towards my maven calls to download dependencies. If you had to do things the hard way like me goto www.mvnrepository.com and just type spring in the search and you can download the jars you need. If you encounter any NoClassDef errors during deployment or compilation it usually tells you what you are missing, then search for the keywords again in the link.

Just:
add gradle plugin in eclipse
import following project from spring site as gradle project
???
Profit!
Than if you don't want use spring boot remove any spring boot dependincies, add regular deps like spring-context, spring-webmvc, etc. And finally add spring-websocket and spring-messaging libraries.

Related

Debugging SpringBoot MVC service application 404 error

A web application I've been working on recently the past like 2 weeks maybe for whatever reason when I finally tested it - won't seem to even enter the method that I have to return a JSON list of objects. I have included the Jackson library and Spring Boot Web, Tomcat, Data-JPA, Hibernate, MySQL, and a library to allow me to access JSP files. The index.jsp comes up but I almost feel like Spring Boot is giving me that free of charge as it's not even entering that method. I have been having the issue for a few days but trying to resolve it on my own - I found another answer that suggested to put a breakpoint inside one of the Spring classes but when I "debugged" it through Eclipse, it didn't even stop at that class - something about pattern matching - One answer suggested adding a context to the application.properties file - didn't help. I've reduced it to as simple as I think I can get it. Can anyone tell me what I might be doing wrong? Before my code, the project is on Github at: https://github.com/sfulmer/Scheduler.git
Here's my controller:
package net.draconia.schedule.controllers;
import java.util.List;
import net.draconia.schedule.beans.Event;
import net.draconia.schedule.dao.EventDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class ScheduleController
{
private static final Logger logger = LoggerFactory.getLogger(ScheduleController.class);
#Autowired
private EventDAO mObjDAO;
protected EventDAO getDAO()
{
return(mObjDAO);
}
//#GetMapping("/events")
#RequestMapping(value = "events", method = RequestMethod.GET)
public #ResponseBody List<Event> getEvents()
{
logger.debug("I got here");
return(getDAO().getList());
}
#GetMapping("/")
public String index()
{
return("index");
}
}
Here is the DAO interface - I'll show the class if necessary but this is what the controller looks at:
package net.draconia.schedule.dao;
import java.util.List;
import javax.persistence.EntityNotFoundException;
import net.draconia.schedule.beans.Event;
public interface EventDAO
{
public Event getEventById(final long lId) throws EntityNotFoundException;
public List<Event> getList();
public void remove(final Event objEvent);
public void removeById(final long lId);
public Event save(final Event objEvent);
}
The Event class is so long but if I need to include it, I will. The application.properties file is here:
spring.datasource.url = jdbc:mysql://localhost:3306/schedule
spring.datasource.username = root
spring.datasource.password = R3g1n# M1lL$ 1$ My Qu3eN!
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
server.servlet.contextPath=/scheduler
and here is my Application class(with the SpringBootApplication annotation):
package net.draconia.schedule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#SpringBootApplication(scanBasePackages = {"net.draconia.schedule.controller"})
public class ScheduleApp implements WebMvcConfigurer
{
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
{
return(builder.sources(ScheduleApp.class));
}
public static void main(String[] args)
{
SpringApplication.run(ScheduleApp.class, args);
}
}
I'm relatively new to Spring Boot but haven't ever ran into this problem ever before as I work with it at work and it works fine but we use entirely REST services there and I am using JSP files as well as sorta end-points that respond with JSON but you can't respond from REST services with JSP views so unfortunately I can't copy work's project to get that working or I would sigh Any thoughts on how I can get this working or what I am omitting?
My guess is that you're mixing things from Spring and Spring boot, and that's getting problems on loading beans, as you're probably changing the annotations load order or loading other beans rather than spring boot defaults as expected. For example, you implements WebMvcConfigurer, but you aren't providing any WebMvc Configuration, like a ViewResolver bean
My advice is to follow this guide: https://spring.io/guides/gs/spring-boot/
and use only the annotations from spring boot if using spring boot, or spring if using spring (they're similar, but not exactly the same, configuration is different).
Anyways, you can check loaded beans in Spring application context (Inject it in Application class) with ctx.getBeanDefinitionNames() method and see if your controller is there (i guess not).
By looking into code, my first impression is that, you have some typo in here:
#SpringBootApplication(scanBasePackages = {"net.draconia.schedule.controller"})
Your controller class package name has net.draconia.schedule.controllers.
So can you please correct your scanBasePackages with proper package name.
If that is not the case, please update full stack trace along with GET request which you are submitting into application. Will take a look & update answer accordingly.

How can I get a list of all sessions in Spring?

I'm developing a web app using Spring Boot 2 and Gradle. I currently implemented a custom remember me mechanism (WITHOUT Spring Security), and I added also a series cookie, as described here.
Now I want to invalidate all user's session in case the token does not match. I would get all sessions of the user (a Bean that I save in "userSession" attribute). How can I do?
PS: I'm not using Spring Security.
You have to create a custom HttpSession holder object that will hold active sessions that you can iterate and invalidate based on your conditions.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class HttpSessionConfig {
private static final Map<String, HttpSession> sessions = new HashMap<>();
public List<HttpSession> getActiveSessions() {
return new ArrayList<>(sessions.values());
}
#Bean
public HttpSessionListener httpSessionListener() {
return new HttpSessionListener() {
#Override
public void sessionCreated(HttpSessionEvent hse) {
sessions.put(hse.getSession().getId(), hse.getSession());
}
#Override
public void sessionDestroyed(HttpSessionEvent hse) {
sessions.remove(hse.getSession().getId());
}
};
}
}
There is module for that in Spring called Spring Session which can easily manage all actual sessions. Link for Spring Session documentation
To run it basically you must add dependency in pom.xml:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
and add some config properties to application.properties:
spring.session.store-type=jdbc
spring.session.jdbc.initializer.enabled=true
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-qlserver.sql
spring.session.jdbc.table-name=SPRING_SESSION
In "spring.session.jdbc.schema=" you can pick your own type of DB or use a embedded one like H2. Spring will automatically create tables for sessions from inbuilt scripts where the sessions will be stored.

Spring Boot - how to include REST endpoint from dependency?

I am new to Spring / Spring Boot, so please pardon if what I am asking is trivial.
I have created Spring Boot application which exposes the REST endpoint:
package com.atomic.contentguard;
...
#Controller
#RequestMapping("/rest")
public class AcgController {
#RequestMapping(value="/acg-status",method=RequestMethod.GET)
#ResponseBody
public String getStatus(){
return "Hi there!";
}
}
It all works fine when you run it as standalone Spring Boot application, the endpoint is testable by going to http://localhost:8080/rest/acg-status.
What I want to achieve is to "bring it" into another application, which would be including my application as a dependency in the pom.xml, expecting this REST endpoint to show up in it.
What I've done so far is included it in another project pom.xml as:
</dependencies>
...
<dependency>
<groupId>com.atomic</groupId>
<artifactId>contentguard</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
And then included it in that other application #ComponentScan section of config file:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.atomic.contentguard"})
public class EnvInfoWebConfig extends WebMvcConfigurerAdapter {
}
It does not however show up when you run target application:
No mapping found for HTTP request with URI [/other-application-context/rest/acg-status] in DispatcherServlet with name 'envinfo-dispatcher'
What am I missing / doing wrong?
You can do this simply by using the spring boot Application Launcher class in your main project as below (You don't need WebMvcConfigurerAdapter class):
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = { "com.atomic.contentguard"})
public class AcgLauncher extends SpringBootServletInitializer {
//This method is required to launch the ACG application
public static void main(String[] args) {
// Launch Trainserv Application
SpringApplication.run(AcgLauncher.class, args);
}
}
Spring Boot uses this class during the server startup and scans the specified packages for all spring components (controllers, services, components).

Using SpringFox to document my Spring RestController

I'm trying to use SpringFox to document a #RestController in my application but so far I've been met with stout resistance.
I've been following this example but whenever I start I get the following exception:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentationPluginsBootstrapper'
I know that's not much to go on so I managed to reproduce it on a pretty simple standalone application:
package example.swagger;
import org.springframework.boot.builder.SpringApplicationBuilder;
public class Main {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(AppConfig.class);
builder.child(SwaggerConfiguration.class).run(args);
}
}
The configuration classes used are as follows:
package example.swagger;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
#SpringBootApplication
public class AppConfig {
}
And finally:
package example.swagger;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class SwaggerConfiguration {
}
I've been struggling with this for days. Any help would be most appreciated! ;)
If I were to take a guess, it's probably because you are not running with the latest version of springfox. Could you try upgrading to 2.5.0. It may fix your problem.
PS: Don't have the link to the issue that fixes this handy, but I'll update this answer when I do.

Is it possible to reuse the pre-defined controllers in spring annotation configured mvc projects?

Is it possible to reuse the predefined controllers, like the SimpleFormController, with annotation configured spring mvc projects?
I downloaded a project that looks like what I want; however, the writer did not use the annotations that are predefined in Spring.
The controller of the downloaded project:
package net.sourceforge.sannotations.example2;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.sannotations.annotation.Bean;
import net.sourceforge.sannotations.annotation.UrlMapping;
/**
* User: Urubatan Date: 24/10/2006 Time: 08:49:09
*/
#Bean
#UrlMapping("/test")
public class ExampleController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("example", "message", request.getParameter("tainted"));
}
}
The project is downloaded from SourceForge
You can make them part of the spring-context faily easily - just annotate the #Bean annotation with #Component, and spring will detect it as a spring bean. Like:
#Component
public #interface Bean { .. }
For the URL-mapping, however, you might want to use a custom BeanPostProcessor to handle the value of the annotation.

Categories

Resources