У меня есть приложение Spring Boot, в котором у меня есть модельный пользователь, и я пытаюсь получить пользователей с тем же именем пользователя, когда я нажимаю кнопку отправки в своем внешнем приложении реагирования. Он говорит, что он не может восстановить, и я не знаю, что именно не так. Я получаю эту ошибку.
xhr.js:247 ПОЛУЧИТЬ http://localhost:8080/calorie_counter/user/$%7Bemail%7D net::ERR_FAILED 500
У меня нет проблем с публикацией вещей в базу данных с помощью моего внешнего приложения. И я могу получить пользователей, используя Postman с идентификатором. Но когда я пытаюсь использовать электронную почту, она просто не работает.
здесь создается пользователь и на чем основана таблица в базе данных
@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;
}
}
@Repository
public interface UserRepository extends JpaRepository\<User, Long\> {
@Query("SELECT u FROM User u WHERE u.email = ?1")
User findUserByEmail(String email);
}
@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";
}
}
@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);
}
}
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>
)
}
Я хочу иметь возможность ввести электронное письмо, нажать кнопку отправки и получить информацию о пользователе (несколько пользователей позже) из базы данных. Я возился с некоторыми вещами, но я не могу понять, что не так с кодом. Я думаю, что что-то не так с кодом в UserRepository или с кнопкой отправки в ViewUser.
Вы можете увидеть весь код в моем репозитории
https://github.com/EmmanuelOlofintuyi/FullStackCalorieCounter
@PrerakSola Я попробовал это, и теперь я получаю эту ошибку GET localhost: 8080/calorie_counter/user/$%7Bemail%7D 400 и это AxiosError {сообщение: «Запрос не выполнен с кодом состояния 400», имя: «AxiosError» , код: 'ERR_BAD_REQUEST', конфигурация: {…}, запрос: XMLHttpRequest, …}
Попробуй это.
Кажется, у меня работает...
Это нормально, как бы ни было лучше всего использовать @Data
из Lombok для геттеров и сеттеров (эта аннотация уровня класса автоматически создаст для вас геттеры и сеттеры).
Опять же, это просто предложение :)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findUserByEmail(String email);
}
Встроенные запросы уязвимы для атак SQL_Injection и не рекомендуются!
в то время как Jpa и Hibernate не являются исключением для талантливого злоумышленника, все же лучше использовать их, поскольку они обеспечивают хороший уровень безопасности за счет использования регулярных выражений и т. д.
...
@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();
}
...
На самом деле UserController
в порядке, не меняйте его, и он должен работать нормально!
Спасибо, бэкэнд теперь работает, но теперь у меня проблемы с интерфейсом. Тем не менее, я намного ближе к желаемому результату, чем в прошлый раз, спасибо.
Ваш внутренний контроллер не может различать идентификатор и адрес электронной почты. Таким образом,
GET /user/{anything}
всегда будет вызыватьgetUserById
, поскольку этот маршрут объявляется первым. Вам нужно обновить маршрут, поэтому что-то вроде@GetMapping("/user/email.{email}")
должно помочь. Вы можете вызвать/user/email/${email}
из внешнего интерфейса.