Spring boot app to accept user input and saving without any database - java

I do have a requirement to create a spring boot and angular application without the use of any database, not even in memory db.The application should accept user input and be displayed in Angular.
// The controller class looks like bellow
#CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping({ "/api" })
public class UserController {
#Autowired
userService userService;
#PostMapping
public Computer create(#RequestBody Computer computer) {
return computerService.save(computer);
}
#GetMapping
public List<Computer> findAll() {
return computerService.findAll();
}
}
#Service
public class UserServiceImpl implements UserService{
private static List<User> users = new ArrayList<>();
private static int Count = 3;
static {
user.add(new User(34, 2000.22,new Date()));
user.add(new User(60, 3000.44,new Date()));
user.add(new User(45, 2000.22,new Date()));
}
And of course there is a userService class with the methods in the implementation class.Is it possible to use hashMap to accept data and then display in Angular without first storing the data in a file or database?. Any ideas would be highly appreciated.
}

Related

How to add #Repository to non-controller class in Spring?

I'm working on a simple Spring Boot application that creates and stores XML files that contain customer licensing information.
But now I would like to add a separate module which imports similar XML files (which were created previously) into the app's database.
For that, I need to use the same repository which is used in the app's controller. The repository gets passed into the controller's constructor as follows:
#RestController
#RequestMapping("/api")
class LicenseController {
private LicenseRepository licenseRepository;
private UserRepository userRepository;
public LicenseController(LicenseRepository licenseRepository,
UserRepository userRepository) {
this.licenseRepository = licenseRepository;
this.userRepository = userRepository;
}
Presumably, the controller annotation informs Spring-Boot to pass repositories to the constructor. However, the separate module used for import isn't a controller, it's just a POJO with a main class.
How do I get the license repository into this POJO?
Mark your POJO as #Component and DI with constructor will be allowed for LicenseRepository as in the code above.
#Component // or #Service | #Repository | #Controller
class YourPOJO {
private LicenseRepository licenseRepository;
public YourPOJO(LicenseRepository licenseRepository) {
this.licenseRepository = licenseRepository;
}
}
Create a Business Object(BO) class rather than a normal POJO or DTO where you can have a custom method to pass repository from your custom Controller.
But still I would consider it as a bad design because DAO actions are never performed in BO, DTO and POJO as their works are totally different. I would tell you to find a way to do it in some other way.
For the requirement, this design can be picked up for now.
For example:
#RestController
#RequestMapping("/api")
class LicenseController {
#Autowired
private LicenseRepository licenseRepository;
#Autowired
private UserRepository userRepository;
#RequestMapping(value="/license", method=RequestMethod.POST)
public void storeLicense() {
SimpleBO bo = new SimpleBO();
bo.doSomethingWithLicenseRepository(licenseRepository);
// do stuff
}
}
Now, create an example SimpleBO class.
public class SimpleBO {
private String someField;
public SimpleBO() {
super();
}
public void doSomethingWithLicenseRepository(LicenseRepository licenseRepository) {
.....
}
// getter and setters and toString() method.
}
I think this will be ok for you.
Package scan and will initialize its instance by calling the #Autowired annotated constructor.
#Service
public class UserLicenseService {
private final LicenseRepository licenseRepository;
private final UserRepository userRepository;
public UserLicenseService (LicenseRepository licenseRepository, UserRepository userRepository) {
this.licenseRepository = licenseRepository;
this.userRepository = userRepository;
}
// ...
}
Controller.
#RestController
#RequestMapping("/api")
class LicenseController {
#Autowired
private UserLicenseService userLicenseService;
#RequestMapping(value="/license", method = RequestMethod.POST)
public void storeLicense() {
// using UserLicenseService.
}
}
Main.
ApplicationContext context = SpringApplication.run(YourMainApplication.class, args);
UserLicenseService userLicenseService = context.getBean(UserLicenseService.class);
// using UserLicenseService.
using-boot-spring-beans-and-dependency-injection

Spring Boot does not recognize MongoDB RestController class

I am new to MongoDB and I am trying to use it with my SpringBoot application. I have followed my tutorials online and have downloaded their code and got it execute.
However for whatever reason my project fails to be able to print out
RequestMappingHandlerMapping : Mapped “{[/findAllBooks/{id}],methods=[GET]}”
I was wondering if anyone would be able to advise me if it is due to the nature of my project structure .
I wasn’t sure if my SpringBootMain could see my Controller class.
My project structure is best viewed here
https://github.com/emuldrew855/backend/tree/A/B-Testing/src/main/java/com/ebay/queens/demo
My Controller class
package com.ebay.queens.demo.resource;
#RestController
#RequestMapping("/v2")
public class UserController {
#Autowired
private UserRepository userRepository;
#PostMapping("/AddUser")
public String saveUser(#RequestBody User user) {
userRepository.save(user);
return "Added user with id: " + user.getId();
}
#GetMapping("/all")
public List<User> getAll(){
List<User> users = this.userRepository.findAll();
return users;
}
}
My main class
package com.ebay.queens.demo;
#SpringBootConfiguration
#SpringBootApplication
public class SpringBootMain implements CommandLineRunner {
#Autowired
private TokenUtilityClass tokenUtilityClass;
#Bean ResourceConfig resourceConfig() {
return new ResourceConfig().registerClasses(Version1Api.class, Login.class, SignUp.class, Paypal.class); }
#Override
public void run(String... args) throws Exception {
// test.authenticationToken();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class, args);
}
}
I've figured out why is not working... You are using 2 different WebService API which are incompatible...
Spring-Boot has native API to work with API Rest with #RestController annotation. You don't need to use Glassfish server.
Solution #1
From SpringBootMain remove #Bean ResourceConfig resourceConfig() {...}. Now, you API /v2 will work as expected.
Your API /v1 won't work because it uses other library. You need to change #Path to #GetMapping or #PostMapping and add #RestController into your Version1Api class.
Solution #2
You ignore Spring-Boot native Rest API and implement Glassfish Server.
Add UserController.class reference
#Bean ResourceConfig resourceConfig() {
return new ResourceConfig().registerClasses(Version1Api.class, Login.class, SignUp.class, Paypal.class, UserController.class); }
For UserController change #RestController to #Path("/v2")
#Path("/v2")
public class UserController {
#Autowired
private UserRepository userRepository;
#POST
#Path("/AddUser")
#Produces(MediaType.TEXT_PLAIN)
public String saveUser(#RequestBody User user) {
userRepository.save(user);
return "Added user with id: " + user.getId();
}
#GET
#Path("/all")
#Produces(MediaType.APPLICATION_JSON)
public List<User> getAll(){
List<User> users = this.userRepository.findAll();
return users;
}
}
Now both API will work as expected

Using an ArrayList as a datasource in an ephemeral Spring Boot project

I am building a REST provider with Spring Boot. It is ephemeral by design i.e. the data can be lost when the application is killed. So, I decided to use an ArrayList to make CRUD operations on: it should be like a singleton -created with the app and used along the way.
I have this rest controller, with the service layer autowired:
#RestController
public class MyController {
#Autowired
private MyServiceInterface myService;
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public List<MyEntity> retrieveAll() {
return myService.getAll();
}
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public MyEntity create(#RequestBody MyEntity entity) {
return myService.insert(entity);
}
}
and the MyService implementing MyServiceInterface is as follows:
#Service
public class MyService implements MyServiceInterface {
// This is my ArrayList to live while the Spring Boot app runs
private List<MyEntity> myList = new ArrayList<MyEntity>();
#Override
public MyEntity insert(MyEntity entity) {
this.myList.add(entity);
return entity;
}
#Override
public List<MyEntity> getAll() {
return this.myList;
}
}
So, is it fine to use a humble private myList object in the serive class as shown above, or should I take a different approach (inject that myList after assigning it as a #Bean, add #Configuration or whatsoever Spring stuff)?
EDIT: Not to sail away from my concern, my primary point is not discussing databases instead of lists, but how to declare a variable used by multiple methods of a Spring Bean.

reload spring bean during the runtime

I am trying to change bean property value during the runtime.
WebConfig
#Configuration
public class WebConfig extends WebMvcConfigurationSupport {
#Autowired
private SecurityService service;
#Bean
public SecurityPolicy securityPolicy() {
SecurityPolicy policy = new SecurityPolicy();
//takes data from db, it works fine
policy.setMaxAttempt = service.getMaxAttempts();
return policy;
}
}
Controller
#Controller
public class SecurityPolicyController {
#Autowired
private SecurityPolicy policy;
#Autowired
private ApplicationContext context;
#Autowired
private SecurityService service;
#RequestMapping(value = "/security")
public ModelAndView update() {
ModelAndView model = new ModelAndView();
//set data to db, it works fine aswell
service.setMaxAttempts(7);
//now i am trying to reload my beans
((ConfigurableApplicationContext)context).refresh();
//something reloading but i still get the same value
System.out.println(policy.getMaxLoginAttempts());
model.setViewName("security");
return model;
}
}
Changing the value occurs only when the server is rebooted.
Can you suggest example how to achieve bean reloading during the runtime or tell what I'm doing wrong? All help appreciated
why not inject the service into policy? and everytime you call the policy.getMaxLoginAttempts() the call gets delegated to service.getMaxAttempts(). So you get new values returned, without having to reload.
So the config looks like this:
#Bean
public SecurityPolicy securityPolicy() {
return new SecurityPolicy(service);
}
And the SecurityPolicy.getMaxLoginAttempts() like this:
public int getMaxLoginAttempts(){
return service.getMaxAttempts();
}

Why do I get 404 for rest with spring-boot

I am implementing rest services with Spring Boot. The entity classes are defined in a separate package. So I added that with Component annotation in Application.java.
#Configuration
#EnableAutoConfiguration
#ComponentScan("org.mdacc.rists.cghub.model")
#EnableJpaRepositories(basePackages = "org.mdacc.rists.cghub.model")
public class Application
{
public static void main( String[] args )
{
SpringApplication.run(Application.class, args);
}
}
Here is my controller class:
// SeqController.java
#RestController
public class SeqController {
#Autowired
private SeqService seqService;
#RequestMapping(
value = "/api/seqs",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<SeqTb>> getSeqs() {
List<SeqTb> seqs = seqService.findAll();
return new ResponseEntity<List<SeqTb>>(seqs, HttpStatus.OK);
}
}
I also created a JPA data repository that extends JPARepository in which I added custom query code.
// SeqRepository.java
#Repository
public interface SeqRepository extends JpaRepository<SeqTb, Integer> {
#Override
public List<SeqTb> findAll();
#Query("SELECT s FROM SeqTb s where s.analysisId = :analysisId")
public SeqTb findByAnalysisId(String analysisId);
}
Below is the servicebean class that implements a service interface
// SeqServiceBean.java
#Service
public class SeqServiceBean implements SeqService {
#Autowired
private SeqRepository seqRepository;
#Override
public List<SeqTb> findAll() {
List<SeqTb> seqs = seqRepository.findAll();
return seqs;
}
public SeqTb findByAnalysisId(String analysisId) {
SeqTb seq = seqRepository.findByAnalysisId(analysisId);
return seq;
}
}
When I started the application and type the following url in the browser "http://localhost:8080/api/seqs" , I got 404 error. What did I miss?
Edit #1:
I decided to take out the JPA repository stuff and change the controller class to the following:
#RestController
//#RequestMapping("/")
public class SeqController {
private static BigInteger nextId;
private static Map<BigInteger, Greeting> greetingMap;
private static Greeting save(Greeting greeting) {
if(greetingMap == null) {
greetingMap = new HashMap<BigInteger, Greeting>();
nextId = BigInteger.ONE;
}
greeting.setId(nextId);
nextId = nextId.add(BigInteger.ONE);
greetingMap.put(greeting.getId(), greeting);
return greeting;
}
static {
Greeting g1 = new Greeting();
g1.setText("Hello World!");
save(g1);
Greeting g2 = new Greeting();
g1.setText("Hola Mundo!");
save(g2);
}
#RequestMapping(
value = "/api/greetings",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Greeting>> getGreetings() {
Collection<Greeting> greetings = greetingMap.values();
return new ResponseEntity<Collection<Greeting>>(greetings, HttpStatus.OK);
}
}
When I started the application and put "localhost:8080/api/greetings" in my browser I still got 404.
==>Did you make sure that your Spring Boot application class and your Rest Controller are in the same base package? For Example if your package for Spring Boot application class is com.example.demo, then your Rest Controller should be in same base package as com.example.demo.controller.
==>I think that is the reason boot is unable to map to the uri of your rest controller. Because #SpringBootApplication has #ComponentScan and #Configuration embedded in it already. Try doing this. I hope it works.
If spring boot starter web is not there in your pom.xml then add the same as the reason could be the code not being able to map the endpoints.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
The first thing I would try is to put #RequestMapping("/") on the class definition of the controller. Keep the same value on the method.
Another thing, unrelated to your problem, is that you do not need to define that custom query. JPA is actually smart enough to do the query you defined just by using that method name. Check out the findByLastName example here: https://spring.io/guides/gs/accessing-data-jpa/.

Categories