Starting JVM REST service, what is the stack should I use? - java

If starting from scratch, with only requirements of JVM and existing MySQL database of medium complexity, and with the goal of doing only REST, nothing else, what is a good example of components I should use?
Want to keep it as simple as possible.

A few simple options can be:
Spark Framework, Sinatra-inspired + uses nice Java 8 features. Quick start example:
import static spark.Spark.*;
public class HelloWorld {
public static void main(String[] args) {
get("/hello", (req, res) -> "Hello World");
}
}
Spring Boot, a simple way to start in Spring ecosystem. Quick start:
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
#Controller
#EnableAutoConfiguration
public class SampleController {
#RequestMapping("/")
#ResponseBody
String home() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleController.class, args);
}
}
Spring has Spring MVC module for building RETSful APIs, here's an example: http://spring.io/guides/gs/rest-service/
You can also take a look at other JVM languages, for example Play Framework in Scala or Grails in Groovy.
UPDATE
I forgot to mention Dropwizard. It uses JAX-RS for RESTful APIs, which can look very verbose, but it's very mature and stable. Here's quick start guide: http://www.dropwizard.io/0.9.2/docs/getting-started.html

Related

At what stage is #SpringBootApplication executed in spring boot application?

When writing a Spring Boot application, we have code like this:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Which means, it can run as a standalone application(having main method) - so far, so good.
My doubt starts here:
The main would be invoked by JVM, so it will see main method, and then execute the line:
SpringApplication.run(Application.class, args);
Then, who does check the annotation #SpringBootApplication - is it interpreted on-the-fly once control goes into Spring framework when JVM executes the first line?
This took me a while to figure out as well...
Your class Application is the 'main' class. It is calling a static method on SpringApplication.
It is the SpringApplication class that actually starts the entire Spring Boot process and all the code that will check for the Spring Annotations and things like that.
I have never looked at the code behind that class, but it has to be tremendous.

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.

Spring Boot - infinite loop service

I want to build a headless application which will query the DB in infinite loop and perform some operations in certain conditions (e.g. fetch records with specific values and when found launch e-mail sending procedure for each message).
I want to use Spring Boot as a base (especially because of Actuator to allow expose health-checks), but for now I used Spring Boot for building REST web-services.
Is there any best practices or patterns to follow when building infinite loop applications ? Does anyone tried to build it based on Spring Boot and can share with me his architecture for this case ?
Best regards.
Do not implement an infinite loop yourself. Let the framework handle it using its task execution capabilities:
#Service
public class RecordChecker{
//Executes each 500 ms
#Scheduled(fixedRate=500)
public void checkRecords() {
//Check states and send mails
}
}
Don't forget to enable scheduling for your application:
#SpringBootApplication
#EnableScheduling
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
}
See also:
Scheduling Tasks
What I'm using is a message broker and a consumer put at the spring boot application to do the job.
There are several options. My approach is to start a loop on an ApplicationReadyEvent, and abstract away the loop logic into an injectable service. In my case it was a game loop, but this pattern should work for you as well.
package com.ryanp102694.gameserver;
import com.ryanp102694.gameserver.service.GameProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
#Component
public class GameLauncher implements ApplicationListener<ApplicationReadyEvent> {
private static Logger logger = LoggerFactory.getLogger(GameLauncher.class);
private GameProcessor gameProcessor;
#Autowired
public GameLauncher(GameProcessor gameProcessor){
this.gameProcessor = gameProcessor;
}
#Override
public void onApplicationEvent(ApplicationReadyEvent event) {
logger.info("Starting game process.");
gameProcessor.start();
while(gameProcessor.isRunning()){
logger.debug("Collecting user input.");
gameProcessor.collectInput();
logger.debug("Calculating next game state.");
gameProcessor.nextGameState();
logger.debug("Updating clients.");
gameProcessor.updateClients();
}
logger.info("Stopping game process.");
gameProcessor.stop();
}
}

Using Spring in a standalone application

i am looking for samples or tutorials of using Spring in a standalone (desktop/swing) application, i searched a lot but couldn't get to something useful, all the examples and tutorials are for web applications, please advise.
Create the standalone application with maven, as pointed here:
Create a standalone application with Maven
Put the applicationContext in classpath, and load it in the main class as follows:
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml");
See full article here:
http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application
Here's a simple example with 2 classes. Wrote in groovy for ease of reading, but will run for you in java too with proper syntax tweaks
Here's your main:
class Main {
static void main(String[] args) {
def ctx = new AnnotationConfigApplicationContext()
ctx.register(AppConfig.class)
ctx.refresh()
def runner = ctx.getBean("mainRunner")
runner.run()
}
void run() {
println "running from bean"
}
}
Here's your config bean:
#Configuration
class AppConfig {
#Bean
Main mainRunner() {
new Main()
}
}
AppFuse provides different demo applications, all the source code can be downloaded using maven. You can get the complete code of this demo application which is build using Spring MVC,Spring, Hibernate.
Yes this is a web application, you can dig into it and convert it to a stand alone one.
create a Maven project
it will create an Application class for your project
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
//SpringApplication.run(YourClass.class, args);
YourClass.main(args);
}
}
put YourClass main method in there instead of SpringApplication.run(YourClass.class,args);
it works that way just fine.
When I first started to learn spring I followed these tutorials:
tutorialspoint
They are fairly basic but will get you up and running quickly. After this is ultimately
comes down to what you are going to use it for. Are you looking for IOC, JMS, JDBC/Hibernate support etc etc?
As mentioned already:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext");
will bring all your spring beans into your app regardless of what type it is.
This is the first thing I found on google. It looks fair good too.
http://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/
Take a look at "Barebones Spring". I think it's a nice, up to date example of how to use Spring 3.
This is the tutorial of Spring which I found to be very useful. This explains Spring based on a Standalone application.
https://www.youtube.com/watch?v=GB8k2-Egfv0
Author of this videos also has updated the Maven and Struts videos and explained it in a simple but in an effective way.
I hope it helps.
I have managed to run a standalone Spring Boot application with Swing.
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SwingApp.class)
.headless(false).run(args);
EventQueue.invokeLater(() -> {
SwingApp ex = ctx.getBean(SwingApp.class);
ex.setVisible(true);
});
}
We need to use the SpringApplicationBuilder and turn off the headless mode.
#SpringBootApplication
public class SwingApp extends JFrame {
The SwingApp is decorated with #SpringBootApplication annotation.
See my Spring Boot Swing integration tutorial for a full working example.
So, to boil it down: what makes your application (any type) a Spring application is the presence and use of at least one BeanFactory, usually extended as an ApplicationContext. In a web application you'd likely declare in web.xml a servlet such as DispatcherServlet which takes care of instantiating and initializing the context; in a standalone application your own code just makes and initializes a context, as shown above. The web framework stuff that magically gives you a context is doing pretty much the same thing under the covers.
Following 4 libraries are needed for a minimal standalone Spring application :
commons-logging.jar (see http://commons.apache.org/logging)
org.springframework.core-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.beans-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.context-2.5.6.A.jar (see
http://www.springsource.org/download)
A good example is given here.

Is there an equivelant to spring's ContextLoader for a non-webapp

I would like a class analogous to spring's ContextLoader/ContextLoaderListener/ContextLoadServlet. These classes are invoked when the application server initializes and puts your configured context into memory.
What is the analogy of this for an application that does not have a container wrappering it?
This would preclude multiple instantiations, provide a unified retrieval location, and not suffer Double Checked Locking lameness either.
An alternative solution can be found here:
Simple Spring, use of ClasspathApplicationContext for standalone apps, how to reuse?
for using SingletonBeanFactoryLocator.
The classic one is ClassPathXmlApplicationContext:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scripting.Messenger;
public final class Boot {
public static void main(final String[] args) throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("scripting/beans.xml");
Messenger messenger = (Messenger) ctx.getBean("messenger");
System.out.println(messenger);
}
}
See more here

Categories

Resources