简体   繁体   中英

How to retrieve a Users from a database using a variable other than User Id

I have a Spring Boot application where I have a model user and I am trying to retrieve Users that have the same username when I hit the submit button on my front-end react application. It is saying that it cannot retrieve and I don't know what exactly is wrong. I am getting this error.

xhr.js:247 GET http://localhost:8080/calorie_counter/user/$%7Bemail%7D.net::ERR_FAILED 500

I am not having trouble posting things into the database using my front-end application. And I can retrieve Users using Postman with the Id. But When I try to use Email it just doesn't work.

Backend

UserModel

this is where the user is created and what the table in the database Is based on



@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private LocalDate dob;
@Transient
private Integer age;
@Transient
private Integer suggestedCalories;
private Integer lifestyle;
private String goal;
private Double weight;

public User() {
}

public User(String name, String email, LocalDate dob, String goal, Integer lifestyle, Double weight) {
this.name = name;
this.email = email;
this.dob = dob;
this.lifestyle = lifestyle;
this.goal = goal;
this.weight = weight;
}

public User(String name, String email, LocalDate dob) {
this.name = name;
this.email = email;
this.dob = dob;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public LocalDate getDob() {
return dob;
}

public void setDob(LocalDate dob) {
this.dob = dob;
}

public Integer getAge() {
return Period.between(this.dob, LocalDate.now()).getYears();
}

public void setAge(Integer age) {
this.age = age;
}

public Integer getSuggestedCalories() {
return calculateCalories();
}

public void setSuggestedCalories(Integer suggestedCalories) {
this.suggestedCalories = suggestedCalories;
}

public Integer getLifestyle() {
return lifestyle;
}

public void setLifestyle(Integer lifestyle) {
this.lifestyle = lifestyle;
}

public Double getWeight() {
return weight;
}

public void setWeight(Double weight) {
this.weight = weight;
}
public String getGoal() {
return goal;
}

public void setGoal(String goal) {
this.goal = goal;
}

public Integer calculateCalories(){
Double calories = 0.0;

    String goal = getGoal();
    Integer lifeStyleValue = getLifestyle();
    if(goal.equals("LOSE")) {
        calories = (weight\*10);
        if (lifeStyleValue \<= 1) {
            calories -= 500;
        } else if (lifeStyleValue == 2) {
            calories  -= 250;
        } else if (lifeStyleValue == 4) {
            calories += 250;
        } else if (lifeStyleValue \>= 5) {
            calories += 500;
        } else {
            calories +=0;
        }
    } else if (goal.equals("GAIN") ){
        calories = ((weight\*15)+500);
        if (lifeStyleValue \<= 1) {
            calories -= 500;
        } else if (lifeStyleValue == 2) {
            calories -= 250;
        } else if (lifeStyleValue == 4) {
            calories += 250;
        } else if (lifeStyleValue \>= 5) {
            calories += 500;
        } else {
            calories+=0;
        }
    }
    else {
        calories = (weight\*15);
        if (lifeStyleValue \<= 1) {
            calories -= 500;
        } else if (lifeStyleValue == 2) {
            calories -= 250;
        } else if (lifeStyleValue == 4) {
            calories += 250;
        } else if (lifeStyleValue \>= 5) {
            calories += 500;
        } else {
            calories +=0;
        }
    
    }
    Integer cv = calories.intValue();
    return cv;

}

}

UserRepository



@Repository
public interface UserRepository extends JpaRepository\<User, Long\> {
@Query("SELECT u FROM User u WHERE u.email = ?1")
User findUserByEmail(String email);

}

UserService



@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;

    @Override
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    @Override
    public User saveUser(User user) {
        return userRepository.save(user);
    }
    
    @Override
    public User getUserById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(()->new UserNotFoundException(id));
    }
    
    @Override
    public User getUserByEmail(String email) {
        User user = userRepository.findUserByEmail(email);
        if (email != null &&
                email.length() > 0 &&
                !Objects.equals(user.getEmail(), email)) {
            User userOptional = userRepository
                    .findUserByEmail(email);
            if (userOptional == null) {
                throw new IllegalStateException("email does not exist");
            }
            return user;
        }
        return null;
    }
    
    @Override
    public User updateUser(User newUser, Long id) {
        return userRepository.findById(id)
                .map(user -> {
                    user.setName(newUser.getName());
                    user.setEmail(newUser.getEmail());
                    user.setDob(newUser.getDob());
                    user.setWeight(newUser.getWeight());
                    user.setLifestyle(newUser.getLifestyle());
                    user.setGoal(newUser.getGoal());
                    return userRepository.save(user);
                }).orElseThrow(()->new UserNotFoundException(id));
    }
    
    @Override
    public String deleteUser(Long id) {
        if(!userRepository.existsById(id)){
            throw new UserNotFoundException(id);
        }
        userRepository.deleteById(id);
        return "User with id"+id+"has been deleted, success";
    }

}

UserContorller


@RestController
@CrossOrigin("http://localhost:3000")

@RequestMapping("/calorie_counter")
public class UserController {
@Autowired
private UserService userService;

    @PostMapping("/addUser")
    public String add(@RequestBody User user){
        userService.saveUser(user);
        return "New user added to the database";
    }
    
    @GetMapping("/users")
    public List<User> getAllUsers(){
        return userService.getAllUsers();
    }
    
    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable Long id){
        return userService.getUserById(id);
    }
    
    @GetMapping("/user/{email}")
    public User getUserByEmail(@PathVariable String email){return userService.getUserByEmail(email);}
    
    @PutMapping("/user/{id}")
    public User updatUser(@RequestBody User newUser, @PathVariable Long id){
        return userService.updateUser(newUser, id);
    }
    
    @DeleteMapping("/user/{id}")
    public String deleteUser(@PathVariable Long id){
        return userService.deleteUser(id);
    }

}

Frontend

ViewUser

import axios from 'axios';
import React, { useState, useEffect } from 'react'

import {useParams, useNavigate} from 'react-router-dom'

export default function ViewUser() {

    const [user, setUser] = useState({
        name:"",
        email: "",
        dob: "",
        age: "",
        suggestedCalories: "",
        goal:"",
        lifestyle:"",
        weight:""
    });
    
    const onInputChange = (e) => {
        setUser({ ...user, [e.target.name]: e.target.value });
      };
    
    const {email}=useParams();
    
    useEffect(()=>{
        fetch("http://localhost:8080/calorie_counter/user/${email}")
        .then(res=>res.json)
        .then((result)=>{
            setUser(result)
        })
    }, [])
    
    const onSubmit= async (e)=>{
        e.preventDefault()
        const result = await axios.get("http://localhost:8080/calorie_counter/user/${email}",user)
        setUser(result.data)
      }
    return (
    <div className='col-md-6 offset-md-3 border rounded p-4 mt-2 shadow'>
        <form onSubmit={(e) => onSubmit(e)}>
        <div className='mb-3'>
            <label htmlFor='Email' className='form-label'>
            E-mail
            </label>
            <input
            type={'text'}
            className='form-control'
            placeholder='Enter E-mail'
            onChange={(e)=>onInputChange(e)}
            value={email}
            name='email'
            />
            <button type="submit" className='btn btn-outline-success'>Submit</button>
            <button type="submit" className='btn btn-outline-danger mx-2'>Cancel</button>
        </div>
        </form>
    <div className='card'>
        <div className='card-header'>
            Details of user id : 
            <ul className='list-group list-group-flush'>
                <li className='list-group-item'>
                    <b>Name: </b>
                    {user.name}
                </li>
                <li className='list-group-item'>
                    <b>Email: </b>
                    {user.email}
                </li>
                <li className='list-group-item'>
                    <b>Date of Brith: </b>
                    {user.dob}
                </li>
                <li className='list-group-item'>
                    <b>Age: </b>
                    {user.age}
    
                </li>
                <li className='list-group-item'>
                    <b>Suggested Calories: </b>
                    {user.suggestedCalories}
    
                </li>
                <li className='list-group-item'>
                    <b>Goal: </b>
                    {user.goal}
    
                </li>
                <li className='list-group-item'>
                    <b>LifeStyle: </b>
                    {user.lifestyle}
    
                </li>
            </ul>
        </div>
    
    </div>

)
}

I want to be able to type in an email, click the submit button and retrieve a User(Multiple Users later on) information from the database. I messed around with some things but I cannot figure out what is wrong with the code. I think it maybe something wrong with the code in UserRepository, or the submit button in ViewUser.

You can see all the code on my repository

https://github.com/EmmanuelOlofintuyi/FullStackCalorieCounter

Try this one.
Seems to be working for me...

UserModel

It's fine, how ever best practice would be using @Data from Lombok for getters and setters ( This class level annotation will generate getters and setters automatically for you ).
Again, it's just a suggestion:)

UserRepository

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findUserByEmail(String email);

}

Inline queries are vulnerable to SQL_Injection attacks and there for is not suggested!
while Jpa and Hibernate are no exception for a talented attacker, it is still better to use them as they provide a good layer of security by the use of regular expressions and etc.

UserService

...


@Override
public User getUserByEmail(String email) {

    if(email == null || email.length() == 0) return null;

    Optional<User> dbUser = this.userRepository.findUserByEmail(email);
    if (!dbUser.isPresent()) throw new IllegalStateException("email does not exist");
    return dbUser.get();
}


...

UserContorller

Actually UserController is fine, don't change it and it must work just fine!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM