Skip to content
Back to skills

586 Migration Guide 6ad9289a

ASecurity

This guide provides detailed instructions for migrating Spring MVC applications to Spring Boot, covering all aspects from build configuration to testing.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
devopsjavabashsqlspringtestinggitapidatabasesecuritydocumentation

Works with

  • api

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 586-migration_guide_6ad9289a --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 586 Migration Guide 6ad9289a?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 586 Migration Guide 6ad9289a
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-586-migration-guide-6ad9289a/badge)](https://www.skillsdirectory.com/skills/tools-only-586-migration-guide-6ad9289a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Spring MVC to Spring Boot Migration Guide

## Overview

This guide provides detailed instructions for migrating Spring MVC applications to Spring Boot, covering all aspects from build configuration to testing.

## Pre-Migration Checklist

Before starting migration:

- [ ] Backup your code (create git branch)
- [ ] Document current application structure
- [ ] List all external dependencies
- [ ] Note custom configurations
- [ ] Identify integration points
- [ ] Review current Spring version
- [ ] Check Java version compatibility

## Migration Process

### Phase 1: Build Configuration

#### Maven Migration

**Step 1: Add Spring Boot Parent**

```xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath/>
</parent>
```

**Step 2: Replace Dependencies**

Remove individual Spring dependencies:
```xml
<!-- Remove these -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>
```

Add Spring Boot starters:
```xml
<!-- Add these -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
```

**Step 3: Add Spring Boot Maven Plugin**

```xml
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
```

#### Gradle Migration

**Step 1: Add Spring Boot Plugin**

```gradle
plugins {
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'java'
}
```

**Step 2: Replace Dependencies**

```gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

### Phase 2: Application Structure

#### Create Main Application Class

Create `Application.java` in your base package:

```java
package com.example.myapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
```

#### Update Package Structure

Recommended structure:
```
src/main/java/com/example/myapp/
├── Application.java
├── controller/
│   └── UserController.java
├── service/
│   └── UserService.java
├── repository/
│   └── UserRepository.java
├── model/
│   └── User.java
└── config/
    └── WebConfig.java
```

### Phase 3: Configuration Migration

#### XML to Java Configuration

**Before (XML):**
```xml
<beans>
    <context:component-scan base-package="com.example"/>
    <mvc:annotation-driven/>

    <bean id="dataSource" class="...">
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    </bean>
</beans>
```

**After (Java + Properties):**

```java
@Configuration
public class DatabaseConfig {
    // Most configuration is auto-configured
    // Only add custom beans if needed
}
```

```properties
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
```

#### web.xml Migration

Spring Boot doesn't use `web.xml`. Configuration is done through:

1. **Application properties**
2. **Java configuration classes**
3. **Annotations**

**Before (web.xml):**
```xml
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-config.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
```

**After:** Not needed - Spring Boot auto-configures DispatcherServlet

### Phase 4: Controller Migration

#### Update Annotations

**Before:**
```java
@Controller
@RequestMapping("/users")
public class UserController {

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public List<User> getUsers() {
        return userService.findAll();
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.POST)
    @ResponseBody
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}
```

**After:**
```java
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping
    public List<User> getUsers() {
        return userService.findAll();
    }

    @PostMapping("/{id}")
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
}
```

**Key Changes:**
- `@Controller` + `@ResponseBody` → `@RestController`
- `@RequestMapping(method = RequestMethod.GET)` → `@GetMapping`
- `@RequestMapping(method = RequestMethod.POST)` → `@PostMapping`
- Similar for `@PutMapping`, `@DeleteMapping`, `@PatchMapping`

### Phase 5: Service Layer

Service layer typically requires minimal changes:

```java
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> findAll() {
        return userRepository.findAll();
    }

    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("User not found"));
    }
}
```

### Phase 6: Data Access Layer

#### JPA/Hibernate Configuration

**Before (XML):**
```xml
<bean id="entityManagerFactory" class="...">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.example.model"/>
</bean>
```

**After (Properties):**
```properties
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
```

#### Repository Layer

Spring Data JPA works the same:

```java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByLastName(String lastName);
}
```

### Phase 7: Test Migration

#### Update Test Annotations

**Before:**
```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = WebConfig.class)
@WebAppConfiguration
public class UserControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .build();
    }
}
```

**After:**
```java
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGetUsers() throws Exception {
        mockMvc.perform(get("/users"))
            .andExpect(status().isOk());
    }
}
```

**Key Changes:**
- `@RunWith(SpringJUnit4ClassRunner.class)` → Not needed (JUnit 5)
- `@ContextConfiguration` → `@SpringBootTest`
- Manual MockMvc setup → `@AutoConfigureMockMvc`
- `@Before` → `@BeforeEach`
- `@Test` from `org.junit.Test` → `org.junit.jupiter.api.Test`

### Phase 8: Properties Configuration

Create `src/main/resources/application.properties`:

```properties
# Server Configuration
server.port=8080
server.servlet.context-path=/myapp

# Logging
logging.level.root=INFO
logging.level.com.example=DEBUG

# Database
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

# JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# View Resolver (if using JSP)
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
```

## Common Migration Patterns

### Pattern 1: Exception Handling

**Before:**
```java
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("message", ex.getMessage());
        return mav;
    }
}
```

**After (REST API):**
```java
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(
            HttpStatus.NOT_FOUND.value(),
            ex.getMessage()
        );
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
}
```

### Pattern 2: Interceptors

**Before:**
```java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggingInterceptor());
    }
}
```

**After:** Same pattern works in Spring Boot

### Pattern 3: CORS Configuration

**Before:**
```java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000");
    }
}
```

**After:** Same pattern or use properties:
```properties
spring.web.cors.allowed-origins=http://localhost:3000
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE
```

## Post-Migration Steps

1. **Build the application**
   ```bash
   mvn clean package
   ```

2. **Run the application**
   ```bash
   java -jar target/myapp.jar
   # or
   mvn spring-boot:run
   ```

3. **Test endpoints**
   ```bash
   curl http://localhost:8080/users
   ```

4. **Run tests**
   ```bash
   mvn test
   ```

5. **Check actuator endpoints** (if enabled)
   ```bash
   curl http://localhost:8080/actuator/health
   ```

## Troubleshooting

### Issue: Application won't start

**Solution:** Check for:
- Missing `@SpringBootApplication` annotation
- Incorrect package structure
- Conflicting dependencies

### Issue: Controllers not found

**Solution:** Ensure:
- Controllers are in same package or sub-package as Application class
- `@ComponentScan` is not restricting scan

### Issue: Database connection fails

**Solution:** Verify:
- Database URL in application.properties
- Database driver dependency
- Database is running

### Issue: Tests fail

**Solution:** Update:
- JUnit 4 to JUnit 5
- Test annotations
- MockMvc setup

## Best Practices

1. **Migrate incrementally** - One module at a time
2. **Keep tests passing** - Run tests after each change
3. **Use Spring Boot starters** - Don't mix with individual dependencies
4. **Leverage auto-configuration** - Minimize custom configuration
5. **Use application.properties** - Externalize configuration
6. **Enable Actuator** - For production monitoring
7. **Follow conventions** - Use standard package structure

## Next Steps

After successful migration:

1. Enable Spring Boot Actuator for monitoring
2. Add Spring Boot DevTools for development
3. Configure profiles for different environments
4. Set up logging configuration
5. Add API documentation (Swagger/OpenAPI)
6. Configure security (Spring Security)
7. Optimize for production deployment

Files in this skill

  • README.md1001 B
  • skill.md11.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.