Postman showing empty JSON object from spring boot rest api - mysql

public class UserController {
#Autowired
private UserRepository userRepository;
#GetMapping
public List<User> findAllUsers() {
return (List<User>) userRepository.findAll();
}
}
This is the code of the controller class

you specified the url in the #RequestMapping("...") annotation
#RequestMapping("url")
public class UserController {
#Autowired
private UserRepository userRepository;
#GetMapping
public List<User> findAllUsers() {
return (List<User>) userRepository.findAll();
}
and add the #RestController annotation above the class

Related

How to mock Abstract class using Mockito?

I am trying to mock abstract class which is called within another class. I mocked the abstract class however mocked abstract class is not being injected.
Any advise on how to mock the abstract class and inject it?
public abstract class MyAbstractClass {
public HelloBean getHelloBean(HelloBean bean){
return bean;
}
}
public class MyBusinessClass extends MyAbstractClass {
public String getBusinessData(){
HelloBean bean = getHelloBean(new HelloBean()) //I want to mock this method while testing getBusinessData()
}
}
My JUnit Class
public class MyBusinessClass {
private MyAbstractClass myAbstractClass = mock(MyAbstractClass.class);
private MyBusinessClass myBusinessClass = mock(MyBusinessClass.class);
#Test
public String getBusinessData(){
when(myAbstractClass.getHelloBean(any(HelloBean.class))).doReturn(new HelloBean());
myBusinessClass.getBusinessData();
}
}
By using Inject Mock it works
Here the test class is
#SpringBootTest
#AutoConfigureMockMvc
public class HelloServiceMockTest {
#InjectMocks
MyBusinessClass myBusinessClass;
#Mock
MyAbstractClass myAbstractClass;
#Mock
HelloBean helloBean;
#Test
public void getBusinessData(){
when(myAbstractClass.getHelloBean(helloBean)).thenReturn(new HelloBean());
myBusinessClass.getBusinessData();
Assert.assertEquals("ggg",myBusinessClass.getBusinessData());
}
}
HelloBean class is
public class HelloBean {
public String get()
{
return "ggg"; }
}
MyBusinessClass is
public class MyBusinessClass extends MyAbstractClass {
public String getBusinessData(){
HelloBean bean = getHelloBean(new HelloBean()); //I want to mock this method while testing getBusinessData()
return bean.get();
}
}

While try to authenticate my login I am getting error "Handler dispatch failed; nested exception is java.lang.StackOverflowError "

I am getting error "Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null"
I try to debug my code but cant understand cause of this error.
I am getting this error in my AuthService class in line ;
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
Here is my AuthService class ;
#Service
public class AuthService {
#Autowired
private UserRepository userRepository;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private JwtProvider jwtProvider;
.........................................
public String login(LoginRequest loginRequest){
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(),
loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authenticate);
return jwtProvider.generateToken(authenticate);
}
}
SecurityConfig file:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean(BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
AuthController class :
#RestController
#RequestMapping("/api/auth")
public class AuthController {
#Autowired
private AuthService authService;
#PostMapping("/login")
public String login(#RequestBody LoginRequest loginRequest){
return authService.login(loginRequest);
}
}
LoginRequest dto :
public class LoginRequest {
private String username;
private String password;
...getters and setters...
}
User model:
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String userName;
#Column
private String password;
#Column
private String email;
...getters and setters...
}
UserRepository Interface:
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUserName(String username);
}
JwtProvider:
#Service
public class JwtProvider {
private Key key;
#PostConstruct
public void init(){
key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
}
public String generateToken(Authentication authentication){
User principal = (User) authentication.getPrincipal();
return Jwts.builder()
.setSubject(principal.getUsername())
.signWith(key)
.compact();
}
}
UserDetailsServiceImpl class:
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUserName(username).orElseThrow(()->
new UsernameNotFoundException("No user name found named " + username));
return new org.springframework.security.core.userdetails.User(user.getUserName(),
user.getPassword(),
true,true,true,true,
getAuthorities("ROLE_USER"));
}
private Collection<? extends GrantedAuthority> getAuthorities(String role_user) {
return Collections.singletonList(new SimpleGrantedAuthority(role_user));
}
}
and my application.properties :
spring.datasource.url=jdbc:mysql://localhost/photoblog?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=...username...
spring.datasource.password=...password...
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
In your SecurityConfig class you are overriding the method authenticationManager() which is responsible to fetch the AuthenticationManager but inside this method, you are calling the beansuper.authenticationManagerBean() which creates the AuthenticationManager bean.
Change authenticationManager() to authenticationManagerBean()
#Bean(BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html#authenticationManager--
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html#authenticationManagerBean--

How to make #JsonView annotated Rest apis serializes all fields

I have a rest api like "/users/{userId}"
This api returns User data but filters out password by #JsonView(ResourceView.Public.class) annotation.
But I want to get password when the unit test runs.
Is there a way to igore #JsonView annotation when test is running.
Or any other options for me?
public class ResourceView {
public interface Public {}
public interface Friends extends Public {}
public interface Family extends Friends {}
}
public class User {
#JsonView(ResourceView.Public.class)
private String name;
#JsonView(ResourceView.Family.class)
private String password;
}
#RestController
public class UserController {
#Autowired
private UserService userService;
#JsonView(ResourceView.Public.class)
#GetMapping(value = "/users/{userId}")
public User getUser(#PathVariable("userId") String userId) {
return userService.getUser(userId);
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
#ActiveProfiles(profiles = "test")
public class UserServiceTest {
#Autowired
protected TestRestTemplate restTemplate;
#Value("${local.server.port}")
private int port;
protected String apiEndpoint;
#Before
protected void setUp() {
initRequestContext();
apiEndpoint = "http://localhost:" + port;
}
protected ResponseEntity<User> requestGetUser(String userId) {
ResponseEntity<User> res = restTemplate.exchange(
apiEndpoint + "/users/" + userId,
HttpMethod.GET,
new HttpEntity<>("parameters", createDefaultHttpHeaders()),
new ParameterizedTypeReference<User>() {});
return res;
}
#Test
public void testGetUser() throws Exception {
ResponseEntity<User> apiRes = requestGetUsers(request);
assertThat(apiRes.getStatusCode(), is(HttpStatus.OK));
User user = apiRes.getBody();
assertThat(user.getName(), is(notNullValue()));
assertThat(user.getPassword(), is(notNullValue()));
}
}
#Configuration
public class MyConfig {
#Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper().configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
return objectMapper;
}
}

How do I map an nested JSON in a RestController?

I am trying to save nested JSON in a database using Spring Boot and RestController. Those JSONs look something like this:
{
"name": "Car 1",
"plate_number": "PLATE NUMBER",
"owner": {
"first_name": "First name",
"last_name": "Last name"
}
}
It was easy to map the normal fields (name and plate number) using the auto mapping provided by spring in the RestController:
public Car createProduct(Car car) {
}
But now, how can i map the object owner to it's own class, CarOwner?( I need to mention that i have multiple classes that uses this approach so a generalised way would be very useful )
EDIT:
My entities look like this:
#Entity
#Table(name = "cars")
public class Car extends BaseEntityWithName {
private String name;
private String plateNumber;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "owner_id")
private Owner owner;
}
#Entity
#Table(name = "car_owners")
public class CarOwner extends BaseEntityWithName {
private String firstName;
private String lastName;
// Constructor, setters, getters
}
And I'm trying to do something like this in the controller:
#RestController
#RequestMapping("/cars")
public class CarController {
#Autowired
private CarService carService;
#RequestMapping(value = "/create", method = RequestMethod.POST)
#ResponseBody
public ProductModel createItem(Car car) {
// How do I create the owner using the JSON parameters
// provided in the nested JSON?
car.setOwner(owner); // Owner created above
return carService.save(car);
}
}
EDIT 2
My two services look like this. The structure is the same on both of them.
#Service
public class CarServiceImpl implements CarService {
#Autowired
private ProductManufacturerRepository productManufacturerRepository;
#Autowired
private CarRepository carRepository;
#Override
public List<Car> findAll() {
return carRepository.findAll();
}
#Override
public Car findOne(Long id) {
return carRepository.findOne(id);
}
#Override
#Transactional
public Car save(Car car) {
return carRepository.save(car);
}
#Override
public void removeOne(Long id) {
carRepository.delete(id);
}
}
From your service layer I can see that you just need to save the owner class. Preferrably this would be in a separate Owner service but this is good enough for a start.
#Service
public class CarServiceImpl implements CarService {
#Autowired
private ProductManufacturerRepository productManufacturerRepository;
#Autowired
private CarRepository carRepository;
#Override
public List<Car> findAll() {
return carRepository.findAll();
}
#Override
public Car findOne(Long id) {
return carRepository.findOne(id);
}
#Override
#Transactional
public Car save(Car car) {
Owner person = car.getOwner();
ownerRepository.save(person);
return carRepository.save(car);
}
#Override
public void removeOne(Long id) {
carRepository.delete(id);
}
}

JavaFx maven, MySql, Hibernate,JPA desktop app: doesnt save yet no error or logs

I am creating a simple CRUD JavaFX desktop application but it cant save any records and doesn't throw errors or any logs.
Using Hibernate 4.3.8, Netbeans 8.0.2, Java 8. Generated POJO in Netbeans See code snippets
HibernateUtil
private static EntityManager entityManager;
public static EntityManager getEntityManager() {
if (entityManager == null) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
entityManager = emf.createEntityManager();
}
return entityManager;
}
UserService
#Service
#Configurable
public class UsersService implements IServiceInterface<Users> {
#Override
public Users save(Users entity) {
return usersDAO.save(entity);
}
UserController
#Controller
public class UserCtrl implements Initializable {
private final IServiceInterface userService = new UsersService();
public void addUser(Users user) {
userService.save(user);
}
}
ViewUsers
public class ViewUsers {
#FXML
private TextField username;
#FXML
private TextField password;
public void addUser(ActionEvent event) {
Users user = new Users();
user.setUserName(username.getText());
user.setUserPass(password.getText());
userCtrl.addUser(user);
}
}
View.fxml
<GridPane fx:controller="com.users.view.users"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10"
styleClass="root">
<TextField fx:id="username" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<PasswordField fx:id="password" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<Button text="Sign In" onAction="#addUser"/>
</GridPane>
UPDATE I am using GenericDao
final EntityManager em = HibernateUtil.getEntityManager();
#Override
public T save(T entity) {
final T savedEntity = em.merge(entity);
return savedEntity;
}