Search code examples
javaspringspring-bootservletshttpsession

Field httpSession in required a bean of type 'javax.servlet.http.HttpSession' that could not be found


I'm getting this error

***************************
APPLICATION FAILED TO START
***************************

Description:

Field httpSession in com.example.splitwise.Controllers.UserController required a bean of type 'javax.servlet.http.HttpSession' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'javax.servlet.http.HttpSession' in your configuration.


Process finished with exit code 0


###############################################################################

This is my controller class

package com.example.splitwise.Controllers;

import com.example.splitwise.DTOS.RequestDTO;
import com.example.splitwise.DTOS.ResponseDTO;
import com.example.splitwise.Modals.Users;
import com.example.splitwise.Services.UserServices;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/api")
public class UserController {

    private UserServices userServices;

    @Autowired
    private HttpSession httpSession;

    private UserController(UserServices userServices) {
        this.userServices = userServices;
    }

    @PostMapping("/signup")
    public ResponseEntity<ResponseDTO> signup(@RequestBody RequestDTO requestDTO) {
        ResponseDTO responseDTO = new ResponseDTO();

        // Check if the user already exists
//        Users existingUser = userServices.findBy(requestDTO.getUserEmail());
//        if (existingUser != null) {
//            responseDTO.setMessage("User already exists");
//            responseDTO.setStatus("Failure");
//            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseDTO);
//        }

        // Create the new user
        Users user = userServices.signup(requestDTO);
        if (user != null) {
            responseDTO.setMessage("Signup is Successful");
            responseDTO.setStatus("Success");
        } else {
            responseDTO.setMessage("Failure in Signup: ");
            responseDTO.setStatus("Failure");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseDTO);
        }

        return ResponseEntity.ok(responseDTO);
    }

    @GetMapping("/login")
    public ResponseEntity<ResponseDTO> login(@Valid @RequestBody RequestDTO requestDTO, @RequestParam HttpServletRequest request) {
        ResponseDTO responseDTO = new ResponseDTO();

        // Check if the user is already logged in
        Users currentUser = (Users) request.getSession().getAttribute("users");
        if (currentUser != null) {
            responseDTO.setMessage("User already logged in");
            responseDTO.setStatus("Failure");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseDTO);
        }

        // Login the user
        Users user = userServices.login(requestDTO.getUserEmail(), requestDTO.getUserPassword());
        if (user != null) {
            request.getSession().setAttribute("users", user);
            responseDTO.setMessage("is logged in");
            responseDTO.setStatus("Success");
        } else {
            responseDTO.setMessage("Failure in Login: ");
            responseDTO.setStatus("Failure");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(responseDTO);
        }

        return ResponseEntity.ok(responseDTO);
    }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>splitwise</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>splitwise</name>
    <description>backend for splitwise</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-security</artifactId>-->``
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
<!--            <scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

config

spring.datasource.url=jdbc:mysql://localhost:3306/xxxx
spring.datasource.username=root
spring.datasource.password=xxxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always

Solution

  • I was not aware that you can autowire HttpSession, but according to Autowiring session in Spring? it is possible (I guess Spring uses a proxy and accesses the current session somehow).

    The problem is that you imported javax.servlet.HttpSession, but you're using Spring Boot 3.1, and since Spring Boot 3, you need to use jakarta.servlet.HttpSession. So, change the import, and make sure that you remove dependencies that import the old javax.* classes. For example, remove the dependency on javax.servlet:javax.servlet-api:4.0.1 from your POM, Spring Boot 3 and higher don't use it, and other dependencies or your code that use classes from this library won't actual work under Spring Boot 3.