Error 404 when post request Spring boot and Flutter app

I try to create a mobile login page using Springboot and Flutter technologies. I am new in development. Tomcat started normally and connected to db. I use emulator pixel 4 api 31 to test my app.

Is url http://192.168.2.6:8090/users/login' in dart file correct? When login button pressed I/flutter ( 7730): Error: 404 appeared.

I aslo try to change in login_page.dart file the url to 'http://localhost:8090/users/login', 'http://127.0.0.1:8090/users/login' and http://'127.0.0.2':8090/users/login' but I get a connection refused error. Here is the code:

App.java

@SpringBootApplication
@EnableJpaRepositories("org.example.repository.*")
@ComponentScan(basePackages = { "org.example.controller.*" })
@EntityScan("org.example.model.*")
public class App
{
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

UserController.java

@RestController
@RequestMapping("/users")

public class UserController {

    private final UserService userService;
    private UserMapper userMapper; // Inject UserMapper here

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/register") // in mobile app doesn't need all users should be registered by corresponding gym
    public ResponseEntity<UserDTO> registerUser(@RequestBody UserDTO userDTO) {
        // Receive and validate userDTO from the client

        // Map userDTO to a User entity
        User userEntity = userService.registerUser(userDTO);

        // Map the resulting User entity to a UserDTO for the response
        UserDTO registeredUserDTO = UserMapper.mapToDTO(userEntity);

        return ResponseEntity.ok(registeredUserDTO);
    }

    @PostMapping("/login")
    public ResponseEntity<UserDTO> loginUser(@RequestBody UserDTO userDTO) throws AuthenticationException {
        // Validate the loginRequest, e.g., check for null values

        // Map userDTO to a User entity
        UserDTO loginUserDTO = userService.loginUser(userDTO);

        return ResponseEntity.ok(loginUserDTO);
    }

application.properties

server.port=8090
server.tomcat.threads.max=200
server.connection-timeout=5s
server.max-http-header-size=8KB
server.tomcat.max-swallow-size=2MB
server.tomcat.max-http-post-size=2MB
spring.datasource.url=jdbc:mysql://localhost:3306/testdbgymapp?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update

login_page.dart (Flutter app)

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

import 'home_page.dart';

class LoginDemo extends StatefulWidget {
  @override
  _LoginDemoState createState() => _LoginDemoState();
}

class _LoginDemoState extends State<LoginDemo> {
  final TextEditingController usernameController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  Future<void> loginUser() async {
    final response = await http.post(
      Uri.parse('http://192.168.2.6:8090/users/login'),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
      body: jsonEncode(<String, String>{
        'username': usernameController.text,
        'password': passwordController.text,
      }),
    );

    if (response.statusCode == 200) {
      // Successful login
      Navigator.push(
          context, MaterialPageRoute(builder: (_) => HomePage()));
    } else if (response.statusCode == 400) {
      // Invalid username or password
      print('Invalid username or password');
    } else {
      // Handle other error cases
      print('Error: ${response.statusCode}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Login Page"),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 60.0),
              child: Center(
                child: Container(
                    width: 200,
                    height: 150,
                    decoration: BoxDecoration(
                        color: Colors.red,
                        borderRadius: BorderRadius.circular(50.0)),
                    child: Image.asset('asset/images/gymApp-logo.png')),
              ),
            ),
            Padding(
              //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
              padding: EdgeInsets.symmetric(horizontal: 15),
              child: TextField(
                decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Email',
                    hintText: 'Enter valid email id as [email protected]'),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(
                  left: 15.0, right: 15.0, top: 15, bottom: 0),
              //padding: EdgeInsets.symmetric(horizontal: 15),
              child: TextField(

                obscureText: true,
                decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Password',
                    hintText: 'Enter secure password'),
              ),
            ),
            TextButton(
              onPressed: (){
                //TODO FORGOT PASSWORD SCREEN GOES HERE
              },
              child: Text(
                'Forgot Password',
                style: TextStyle(color: Colors.blue, fontSize: 15),
              ),
            ),
            Container(
              height: 50,
              width: 250,
              decoration: BoxDecoration(
                  color: Colors.blue, borderRadius: BorderRadius.circular(20)),
                        child: TextButton(
                onPressed: () {
                  loginUser();
                },
                child: Text(
                  'Login',
                  style: TextStyle(color: Colors.white, fontSize: 25),
                ),
              ),
            ),
            SizedBox(
              height: 130,
            ),
            Text('New User? Create Account')
          ],
        ),
      ),
    );
  }
}

Tomcat logs

2023-09-14T10:38:53.779+03:00 INFO 288 --- [ restartedMain] org.example.App : Starting App using Java 17.0.8 with PID 288 (C:\Users\giorg\IdeaProjects\gymApp\target\classes started by Λιτσα in C:\Users\giorg\IdeaProjects\gymApp) 2023-09-14T10:38:53.782+03:00 INFO 288 --- [ restartedMain] org.example.App : No active profile set, falling back to 1 default profile: "default" 2023-09-14T10:38:53.864+03:00 INFO 288 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable 2023-09-14T10:38:53.864+03:00 INFO 288 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG' 2023-09-14T10:38:55.143+03:00 INFO 288 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2023-09-14T10:38:55.159+03:00 INFO 288 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 JPA repository interfaces. 2023-09-14T10:38:56.647+03:00 INFO 288 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8090 (http) 2023-09-14T10:38:56.669+03:00 INFO 288 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2023-09-14T10:38:56.669+03:00 INFO 288 --- [ restartedMain] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.5] 2023-09-14T10:38:56.787+03:00 INFO 288 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2023-09-14T10:38:56.788+03:00 INFO 288 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2923 ms 2023-09-14T10:38:56.818+03:00 INFO 288 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2023-09-14T10:38:57.185+03:00 INFO 288 --- [ restartedMain] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@2cf75a85 2023-09-14T10:38:57.186+03:00 INFO 288 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2023-09-14T10:38:57.196+03:00 INFO 288 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:mysql://localhost:3306/testdbgymapp?serverTimezone=UTC' 2023-09-14T10:38:57.461+03:00 INFO 288 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2023-09-14T10:38:57.676+03:00 INFO 288 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.1.7.Final 2023-09-14T10:38:57.963+03:00 INFO 288 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2023-09-14T10:38:58.141+03:00 INFO 288 --- [ restartedMain] SQL dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect 2023-09-14T10:38:58.537+03:00 INFO 288 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2023-09-14T10:38:58.548+03:00 INFO 288 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2023-09-14T10:38:58.761+03:00 WARN 288 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2023-09-14T10:38:59.336+03:00 INFO 288 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2023-09-14T10:38:59.366+03:00 INFO 288 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8090 (http) with context path '' 2023-09-14T10:38:59.375+03:00 INFO 288 --- [ restartedMain] org.example.App : Started App in 6.016 seconds (process running for 6.52) 2023-09-14T10:51:26.685+03:00 WARN 288 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1m59s220ms870µs300ns). 2023-09-14T10:53:55.076+03:00 INFO 288 --- [nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2023-09-14T10:53:55.077+03:00 INFO 288 --- [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2023-09-14T10:53:55.079+03:00 INFO 288 --- [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms

Upvotes: 0

Views: 415

Answers (1)

7.oz
7.oz

Reputation: 119

To test the API, you can use the following curl command in your terminal:

curl -X POST http://localhost:8080/users/login

If both the server and your machine are running locally, the IP address is typically localhost and not an address like 192.168.x.x.

For those using an Android Emulator, please refer to the networking documentation for more details on network addresses: Android Emulator Networking Documentation

Upvotes: 0

Related Questions