I have a CustomerController.java:
package com.satisfeet.http;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.satisfeet.core.model.Address;
import com.satisfeet.core.model.Customer;
import com.satisfeet.core.service.CustomerService;
#RestController
#RequestMapping("/customers")
public class CustomerController {
#Autowired
private CustomerService service;
#RequestMapping(method = RequestMethod.GET)
public Iterable<Customer> index() {
return this.service.list();
}
#RequestMapping(method = RequestMethod.POST)
public Customer create(#RequestBody Customer customer) {
this.service.create(customer);
return customer;
}
#RequestMapping(method = RequestMethod.GET, value = "/{id}")
public Customer show(#PathVariable Integer id) {
return this.service.show(id);
}
#RequestMapping(method = RequestMethod.PUT, value = "/{id}")
public void update(#PathVariable Integer id, #RequestBody Customer customer) {
this.service.update(id, customer);
}
#RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void destroy(#PathVariable Integer id) {
this.service.delete(id);
}
}
and a ExceptionController.java:
package com.satisfeet.http;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.satisfeet.core.exception.NotFoundException;
#ControllerAdvice
public class ExceptionController {
#ExceptionHandler(NotFoundException.class)
public ResponseEntity notFoundError() {
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
}
I would now like to add some sort of HTTP request-response middleware which is executed before the response is written and write the HTTP status code in json:
HTTP/1.1 404 OK
Connection: close
Content-Type: application/json
{"error":"not found"}
I know how to convert a HttpStatus to a String but I do not know where I could do this globally with #ControllerAdvice.
So how do I register a global handler which has access to a response object?
i think what you are looking for is spring Interceptor .
please check this tutorial which is describing how to use interceptors .
and check spring documentation Intercepting requests with a HandlerInterceptor .
finally check this answer here
Hope that helps .
To whom ever this may concern regarding the answer, the class HandlerInterceptorAdapter is now deprecated. You can implement the HandlerInterceptor which comes in the form of an interface instead. You can then implement preHandle, postHandle, or afterCompletion methods. See this question.
Related
I tried following the documentation tutorial, but I have some issues with depracated method. Specially in this line
.then(item-> ServerResponse.ok().contentType(APPLICATION_JSON).body(fromObject(item)))
The error is : Target type of a lambda conversion must be an interface.
Below is whole code. Thanks for your help
package com.learnreactivespring.learnreactivespring.handler;
import com.learnreactivespring.learnreactivespring.document.Item;
import com.learnreactivespring.learnreactivespring.repository.ItemReactiveRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
#Component
public class ItemsHandler {
#Autowired
ItemReactiveRepository itemReactiveRepository;
public Mono<ServerResponse> getAllItems(ServerRequest serverRequest) {
return ServerResponse.ok()
.contentType(APPLICATION_JSON)
.body(itemReactiveRepository.findAll(), Item.class);
}
public Mono<ServerResponse> getOneItem(ServerRequest request) {
String itemId = request.pathVariable("id");
Mono<ServerResponse> notFound = ServerResponse.notFound().build();
Mono<Item> itemMono = this.itemReactiveRepository.findById(itemId);
return itemMono
.then(item -> ServerResponse.ok().contentType(APPLICATION_JSON).body(fromObject(item)))
.otherwiseIfEmpty(notFound);
}
}
I am running a simple Spring boot application, In console its running successfully. But when I am trying by postman it gives this error message.
{
"timestamp": "2020-07-26T04:22:15.626+00:00",
"status": 404,
"error": "Not Found",
"message": "",
"path": "/loginRegistration/user/"
}
My project structure is...
My Main class is
import org.example.controller.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
System.out.println("Welcome");
}
}
My Controller is....
import com.fasterxml.jackson.core.JsonProcessingException;
import org.example.entity.Registration;
import org.example.model.UserDto;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
#RequestMapping("/user")
public class User {
#Autowired
UserService userService;
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registerUser(#Validated UserDto userdto) throws JsonProcessingException {
userService.registerUser(userdto);
return "success";
}
#RequestMapping(value = "/getUserList", method = RequestMethod.GET)
public List<Registration> getUserList() {
List<Registration> list = userService.getUserList();
return list;
}
#RequestMapping(value = "/")
public String test() {
return "testing";
}
}
Please guide me what changes need to be done to run on postman.
spring application name does not use as context path. You will have to
define below property in your application.properties file to use
'loginRegistration' as your context path.
server.servlet.context-path=/loginRegistration
And now you can use it as /loginRegistration/user/
Let me know if that helps. Thanks
You have to make sure, you providing war name along with your given URL... And see packages should be under you main class... if not u have to add in main class using componentscan
Another alternative to what #Jimmy described is to define #RequestMapping in your User class as -
#RestController
#RequestMapping("/loginRegistration/user/")
public class User {
i want to make my springboot application can connect into twitter through API using my secret and client key. Here it is my code
package com.backend.siap.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.social.twitter.api.Tweet;
import org.springframework.social.twitter.api.Twitter;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class TestTwitter {
#Autowired
private Twitter twitter;
#RequestMapping(value="twitter/{hashTag}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<Tweet> getTweets (#PathVariable final String hashTag)
{
return twitter.searchOperations().search(hashTag, 5).getTweets();
}
#RequestMapping(value="timeline", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<Tweet> getTimeline()
{
return twitter.timelineOperations().getHomeTimeline();
}
}
if i call getTweet method controller it return json that contain some tweet that i search using hashtag. so it work
but if i call getTimeline method controller it return something like this
org.springframework.social.MissingAuthorizationException: Authorization is required for the operation, but the API binding was created without authorization.
I also have added my secret and client code in my application properties.
how to solve that problem? thanks
I am having difficulty injecting a CrudRepository into a service annotated with the #Service annotation. I have two packages one "core" package containing #Service definitions and reusable controller definitions.
My main application in the x.y.application package is as follows:
package x.y.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan({ "x.y.application", "x.y.core" })
public class Application {
public static void main( String[] args ) {
SpringApplication.run( Application.class, args );
}
}
Then an example Controller.
package x.y.application.controller;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import x.y.application.model.User;
import x.y.core.controller.Controller;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.data.repository.CrudRepository;
#RestController
#RequestMapping("/test")
public class HelloController extends Controller<User> {
}
Then my re-usable controller class
package x.y.core.controller;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.http.HttpStatus;
import org.springframework.data.repository.CrudRepository;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.beans.factory.annotation.Autowired;
import x.y.core.service.Service;
public class Controller<T> {
#Inject
Service<T> service;
#RequestMapping(value = "/index.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public T create( #RequestBody T item ) throws Exception {
return service.create( item );
}
#RequestMapping(value = "/{id}.json", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public T update( #PathVariable Long id, #RequestBody T item ) throws Exception {
return service.update( item );
}
#RequestMapping(value = "/{id}.json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public T read( #PathVariable Long id ) throws Exception {
return service.findOne( id );
}
#RequestMapping(value = "/index.json", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<T> readAll() throws Exception {
return service.findAll();
}
#RequestMapping(value = "/{id}.json", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void delete( #PathVariable Long id ) throws Exception {
service.delete( id );
}
}
Then my service interface
package x.y.core.service;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.lang.reflect.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.http.HttpStatus;
import org.springframework.data.repository.CrudRepository;
import org.springframework.dao.DataIntegrityViolationException;
public interface Service<T> {
/**
* create.
* Creates a new entity in the database.
*/
public T create( T item );
/**
* update.
* Updates an existing entity in the database.
*/
public T update( T item );
public T findOne( Long id );
public List<T> findAll();
public void delete( Long id );
}
And finally the problematic implementation of service.
package x.y.core.service;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.lang.reflect.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.http.HttpStatus;
import org.springframework.data.repository.CrudRepository;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.beans.factory.annotation.Autowired;
#org.springframework.stereotype.Service
public class RepositoryService<T> implements Service<T> {
#Inject //Throws exception
CrudRepository<T,Long> repository;
/**
* create.
* Creates a new entity in the database.
*/
public T create( T item ) throws DataIntegrityViolationException {
/*try {
Field field = item.getClass().getDeclaredField( "id" );
field.setAccessible( true );
if( repository.exists( field.getLong( item ) ) ) {
throw new DataIntegrityViolationException( "Entity object already exists." );
}
} catch ( Exception exception ) {
throw new DataIntegrityViolationException( "Entity class does not contain Id attribute." );
}
return repository.save( item );*/ return item;
}
/**
* update.
* Updates an existing entity in the database.
*/
public T update( T item ) throws DataIntegrityViolationException {
/*try {
Field field = item.getClass().getDeclaredField( "id" );
field.setAccessible( true );
if( !repository.exists( field.getLong( item ) ) ) {
throw new DataIntegrityViolationException( "Entity object does not exists." );
}
} catch ( Exception exception ) {
throw new DataIntegrityViolationException( "Entity class does not contain Id attribute." );
}
return repository.save( item );*/ return item;
}
public T findOne( Long id ) {
/*if( !repository.exists( id ) ) {
throw new DataIntegrityViolationException( "Item with id does not exists." );
}
return repository.findOne( id );*/ return null;
}
public List<T> findAll() {
final List<T> resultList = new ArrayList<>();
/*/ final Iterator<T> all = repository.findAll().iterator();
while( all.hasNext() ) {
resultList.add( all.next() );
}*/
return resultList;
}
public void delete( Long id ) {
/*if( !repository.exists( id ) ) {
throw new DataIntegrityViolationException( "Item with id does not exists." );
}
repository.delete( id );*/
}
}
The exception
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.repository.CrudRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.inject.Inject()}
It seems that any spring registered Component, Service, Resource cannot inject CrudRepository?
However if i do not annotate the CrudRepository in the x.y.application package it compiles and the CrudRepository is injected?
For dependency injection to work application context has to know a recipe for creating an instance of a specific class. Classes whose instance creation recipes are known are referred to as "beans". You can define beans either via XML configuration file (old school) or annotations (new school).
The error message you are receiving states that the application context does not have CrudRepository bean, i.e. it does not know how to create an instance of a class that implements this interface.
To create a bean definition in a new way you may annotate a class or a specific method which return instance of a specific class with #Bean or any other meta-annotation that includes it (#Service, #Controller, etc.).
If you intend to use Spring Data suite of projects to automate repository implementation generation, you need to annotate an interface which extends one of the core Spring Data interfaces (Repository, CrudRepository, PagingAndSortingRepository) with #Repository annotation like so
#Repository
public interface MyRepository extends CrudRepository<Entity, Long> {
}
This provides a bean definition for the application context and makes it aware that you want the repository implementation to be generated for you.
Then you can inject MyRepository to the service class.
The only doubt I have is about the generic type to be used in repository type definition. I would expect the repository implementation (the one you want to be generated for you) to be entity-specific rather than abstract.
This is probably because CrudRepository is not part of your package scan. And hence spring is unable to inject a proxy implementation for it.
I try connect SpringMVC, apache tiles, angular and boostrap. After typing: http://localhost:8080/testrest menu appears with Bootstrap, the table in which they appear videos and does not pass even a second it gets a white screen.
Check my video here: https://youtu.be/V9FvL0yUWXU
Rest returns the data, so it's ok.
Code AngularJs:
https://github.com/giecmarcin/[...]/main/webapp/WEB-INF/static/js
View file:
https://github.com/giecmarcin/[...]B-INF/pages/MovieManagment.jsp
RestController:
package com.springapp.mvc.controller;
import com.springapp.mvc.entities.Movie;
import com.springapp.mvc.services.MovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* Created by Marcin on 19.04.2016.
*/
#RestController
public class MovieRestController {
#Autowired
MovieService movieService;
#RequestMapping(value = "/movies/all", method = RequestMethod.GET)
public ResponseEntity<List<Movie>> listAllMovies() {
List<Movie> movies = movieService.findAll();
if(movies.isEmpty()){
return new ResponseEntity<List<Movie>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
}
return new ResponseEntity<List<Movie>>(movies, HttpStatus.OK);
}
}
Kontroler zwracajÄ…cy widok
#Controller
public class IndexController {
#RequestMapping("/")
public String index() {
return "index";
}
#RequestMapping("/testrest")
public String getTest(){
return "MovieManagment";
}
}
Thank you for help.