I have a simple Spring back-end. It has a folder that contains controllers.
package com.movieseat.controllers;
// Java imports
import java.util.List;
// Spring imports
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
// Project imports
import com.movieseat.models.Movie;
import com.movieseat.services.MovieService;
#RestController
#RequestMapping("/api/movies")
public class MovieController {
#Autowired
private MovieService movieService;
#RequestMapping(value = "/allMovies", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Movie> getAllMovies() {
return movieService.getAllmovies();
}
}
In my Angular service I have a getAll() method:
public getAll<T>(): Observable<T[]> {
return this.http.get<T[]>('/api/movies/allMovies');
}
When I run the application I get a:
GET http://localhost:8090/api/movies/allMovies 404 ()
I have the server running on port 8090.
The following structure is used:
com
movieseat
Application.java
controllers
MovieController.java
models
MovieModel.java
repositories
MovieRepository.java
services
impl
MovieServiceImpl.java
MovieService.java
See if your controller class is picked up by spring scanning and performs mapping correctly. For example - If you are using Spring Boot, put a #SpringBootApplication on your main class that runs the app. The best way to know if your endpoint is scanned is to look for it when spring launches (in the log). You should look for something like
2017-09-17 14:45:49.522 INFO 2873 --- [main] RequestMappingHandlerMapping : Mapped "{[/allMovies],methods=[GET]}" onto public java.lang.String com.movieseat.controllers.MovieController.getAllMovies...
Related
Hi I m beginner and I have a simple problem, my url doesn't work. localhost:8080 work but not with /api. The project is built properly.
Localhost:8080
I put #ComponentScan("com.tutojwt.test.repository") because without it doesn't work.
Here my code
Controller :
package com.tutojwt.test.api;
import com.tutojwt.test.model.User;
import com.tutojwt.test.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
#RequestMapping("/api")
#RequiredArgsConstructor
public class UserController {
private final UserService userService;
#GetMapping("/users")
public ResponseEntity<List<User>>getUsers(){
return ResponseEntity.ok().body(userService.getUsers());
}
Testapplication :
package com.tutojwt.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan("com.tutojwt.test.repository")
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Project structure
MAJ : Some of you say that is ComponentScan the prob but there are error if I dont put com.tutojwt.test.repository or just com.tutojwt.test
#ComponentScan("com.tutojwt.test") error
Without ComponentScan
You should call http://localhost:8080/api/users . #ComponentScan shouldn't be necessary and might actually cause problems (I don't think your controller class is scanned now, and some default hateoas endpoint is the one you're calling). #SpringBootApplication annotation has #EnableAutoConfiguration annotation by default and should scan all component annotated classes. If not, check your class structure again.
I am new in the spring/boot word and have a working JAX-WS based web-service declared in a springboot project. It is started and configured via web.xml and sun-jaxws.xml. So, no beans included there only endpoints declarations and servlet definitions and mappings.
I just now want to save the items i get in the webservice into the mysql database using spring-boot-starter-jdbc which is not working:
I can't achieve this as the repository is not injected in the webservice implementation.
Followed all steps in other question, but not achieving this!
Normally declaration of the datasource parameters in application.properties and annotating #webservice and #Repository would suffice to get the injection of the repository working in the webservice class. What am i missing ?
Here details of the steps I followed:
the webservice implementation is a package X and i created a #SpringBootApplication in order to use a mysql datasource declared in application.properties.
So i annotated the webservice as a #Component and the data access repository with #Repository and #Component
parent version: spring-boot-starter-parent : 1.5.10.RELEASE
webservice service implementation:
BServiceManager.java
package X;
....
#Component
#WebService(name = "***",***)
#BindingType("http://schemas.xmlsoap.org/wsdl/soap/http")
#XmlSeeAlso({
packagesxxx.class,
....
})
public class BServiceManager
implements xxxxx
{
....
#Autowired
private ItemRepository irepo;
....
#WebMethod(**)
#WebResult(***)
public ResponseDataInfo sendInfo( ){
....
trepo.saveitem(item)
....
}
}
ItemRepository.java
package Y.Z;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
#Component
#Repository
public class ItemRepository {
#Autowired
private JdbcTemplate jdbcTemplate ;
....
public boolean saveitem(Item item) {
....
}
}
Item.java
package Y.Z;
public class Item {
....
}
GetItemsApplication
package Y;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
//#ComponentScan(basePackages={"Y","Y.Z","X"})
#SpringBootApplication
public class GetItemsApplication {
....
public static void main(String[] args) {
SpringApplication.run(GetItemsApplication.class, args);
log.info("--Spring Boot inits done--");
}
}
application.properties
spring.data.jpa.repositories.enabled=false
spring.data.jdbc.repositories.enabled=true
# MySQL properties
spring.datasource.url=****
spring.datasource.username=****
spring.datasource.password=****
....
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
logging.level.org.springframework.jdbc.core.JdbcTemplate=debug
NB: even having datasource bean is not helping :
File: DataSourceConfig.java
package Y.Z;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
//#EnableJdbcRepositories for Spring
#Configuration
public class MDataSourceConfig {
#Bean
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
return dataSourceBuilder.build();
}
#Bean
public JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(dataSource());
}
}
Your Webservice doesn't seem to get created by Spring.
Therefore Spring has no control over its dependencies, so you have to get the dependency programmatically.
There are many ways to do this.
Easy but not very elegant and uses global variables which might cause problems, especially with tests: https://stackoverflow.com/a/18486178/66686
More elegant but requires weaving Spring autowiring using #Configurable
I am trying a demo file transfer program using Spring Boot and Apache Camel file component. I have exposed a REST Controller using Spring Boot which is calling an Apache Camel route and it is doing the file transfer. I have three files in the directory C:\CamelDemo\inputFolder namely input1.txt, input2.txt and input3.txt. I want to only transfer the file input2.txt in the output folder. My Spring Boot controller is as below:
package com.example.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.apache.camel.ProducerTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/camel")
public class FileTransferController {
#Autowired private ProducerTemplate producerTemplate;
#RequestMapping(value="/file", method=RequestMethod.GET)
public String callCamelRoute() {
String fileName = "input2.txt";
Map<String, Object> headerMap = new HashMap<String, Object>();
headerMap.put("fileName", fileName);
producerTemplate.sendBodyAndHeaders("direct:transferFile", null, headerMap);
return "Route invoked";
}
}
My Route is as below:
package com.example.demo.route;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class FileTransferRoute extends RouteBuilder {
#SuppressWarnings("deprecation")
#Override
public void configure() {
errorHandler(defaultErrorHandler()
.maximumRedeliveries(3)
.redeliverDelay(1000)
.retryAttemptedLogLevel(LoggingLevel.WARN));
from("direct:transferFile")
.log("Route reached")
.log("file:C:\\CamelDemo\\inputFolder?fileName=${in.headers.fileName}&noop=true")
.pollEnrich("file://C:/CamelDemo/inputFolder?fileName=${in.headers.fileName}&noop=true")
.to("file://C:/CamelDemo/outputFolder?autoCreate=false")
.end();
}
}
But the first time I invoke this route, the file input1.txt is getting transferred even when I have specified the fileName parameter. Please help.
I think the issue is that your file name isn't being set, because you're not telling Camel that you're using a Simple expression, rather than a fixed URI.
Looking at the manual (https://camel.apache.org/manual/latest/pollEnrich-eip.html#_using_dynamic_uris), it implies that you will need
.pollEnrich().simple("file://C:/CamelDemo/inputFolder?fileName=${in.headers.fileName}&noop=true")
to be able to use the dynamic endpoint.
newbie pb on Spring Boot, I cannot get a RestController to be added to my application.
Here are the 2 files used to build this very simple app with maven:
1) Application.java
package com.learn.hello;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages = "com.learn.hello.controller")
#RestController
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
HelloController.java
package com.learn.hello.controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
public class HelloController {
#RequestMapping("/titi")
public String index() {
return "Greetings from titi Boot!";
}
}
Structure of the project
/src/main/java/com/learn/hello/Application.java
/src/main/java/com/learn/hello/controller/HelloController.java
/target/*
/pom.xml
localhost:8080 works
but localhost:8080/titi does not (404 not found)
Any idea ?
Thx
You forgot to provide request method RequestMethod.GET :
#RequestMapping(value = "/students", method = RequestMethod.GET)
You can use #GetMapping("/titi") instead of #RequestMapping("/titi") :
#GetMapping("/titi")
To all, thanks a lot to all for your answers.
#Valerio,
you were right it was correct!!! In fact an invisible char got added at the end of the filename: HelloController.java (me probably messing-up with Sublime...), thus it was not processed as a java file by maven...
Sorry for the noise.My apologies.
BTW if anybody knows about any sort of options to actually warn that a file located in the /src/main/java/* directories was not processed as a "regular java project" file I'm interested to know about it even though I doubt that this is really feasible and thus existing...
I am new to Hystrix Dashboard. I have written sample application with Hystrix.
I want to see the Hystrix chart (command metric stream). But I am getting the below error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...
I am using STS with Maven.
Below is the code used:
Simple server microservice application (Spring boot web running in port 8085)
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
#SpringBootApplication
public class BookstoreApplication {
#RequestMapping(value = "/recommended")
public String readingList(){
return "Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)";
}
public static void main(String[] args) {
SpringApplication.run(BookstoreApplication.class, args);
}
}
Simple client microservice application (Spring boot web running in port 8095) I have included the dependency of Hystrix and Hystrix Dashboard along with Web, so all the Hystrix dependencies are in classpath
package hello;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
#Service
public class BookService {
private final RestTemplate restTemplate;
public BookService(RestTemplate rest) {
this.restTemplate = rest;
}
#HystrixCommand(fallbackMethod = "reliable")
public String readingList() {
URI uri = URI.create("http://localhost:8090/recommended");
return this.restTemplate.getForObject(uri, String.class);
}
public String reliable() {
return "Cloud Native Java (O'Reilly)";
}
}
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.web.client.RestTemplate;
#EnableHystrixDashboard
#EnableHystrix
#EnableCircuitBreaker
#RestController
#SpringBootApplication
public class ReadingApplication {
#Autowired
private BookService bookService;
#Bean
public RestTemplate rest(RestTemplateBuilder builder) {
return builder.build();
}
#RequestMapping("/to-read")
public String toRead() {
return bookService.readingList();
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
By running the above code, the hystrix is working fine, when the BooKStoreApplication is down, it is going to fallback method.
Both the urls are working fine.
Normal Case:
http://localhost:8085/recommended
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
http://localhost:8095/to-read
Output: Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
When BookStoreApplication is down (http://localhost:8085/recommended) accessing http://localhost:8095/to-read returns "Cloud Native Java (O'Reilly)" as expected.
But when I tried to invoke this url http://localhost:8095/hystrix, I am getting the Hystrix DashBoard Page and asking for the stream value.
I have tried given http://localhost:8095/ or http://localhost:8095/to-read, and clicked "Monitor Stream" and it is going to next page with error:
Circuit: Unable to connect to Command Metric Stream
Thread Pools: Loading...
I've experienced the same. The main problem was, that I didn't have the actuator dependency in my maven pom. So I could not get the hystrix stream.
Include the spring-boot-actuator.
Check if localhost:8085/health is running.
Try to enter localhost:8085/hystrix.stream to stream value in Hystrix Dashboard.
Execute the service few times -> the dashboard should show the monitored method/command.