You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求Spring/GWT项目中无SpringBoot的Spring Data JPA Maven示例项目

Got it, let's build a straightforward non-Spring Boot Maven project that combines Spring Data JPA (for Postgres access) and GWT. I'll walk you through every key part so you can avoid Spring Boot's "magic" and have full control over servlet registration.

1. Project Structure

Here's the clean, standard layout we'll use—following Maven web app conventions:

spring-data-gwt-non-boot/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   ├── com/
│   │   │   │   ├── example/
│   │   │   │   │   ├── config/       # Spring configuration classes
│   │   │   │   │   ├── entity/       # JPA entities
│   │   │   │   │   ├── repository/   # Spring Data JPA repositories
│   │   │   │   │   └── gwt/          # GWT service classes
│   │   │   │   │       ├── client/   # GWT client-side code
│   │   │   │   │       └── server/   # GWT server-side servlet
│   │   ├── resources/
│   │   │   └── db.properties         # Postgres connection details
│   │   └── webapp/
│   │       ├── WEB-INF/
│   │       │   ├── web.xml           # Servlet and Spring config
│   │       │   └── gwt/
│   │       │       └── Example.gwt.xml # GWT module config
│   │       └── index.html            # GWT entry point
└── pom.xml
2. Maven pom.xml Configuration

We'll include only the necessary dependencies—no Spring Boot starters. Here's the core setup:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>spring-data-gwt-non-boot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <spring.version>5.3.24</spring.version>
        <spring.data.jpa.version>2.7.5</spring.version>
        <hibernate.version>5.6.14.Final</hibernate.version>
        <postgres.version>42.5.1</postgres.version>
        <gwt.version>2.10.0</gwt.version>
        <servlet.api.version>4.0.1</servlet.api.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Spring Core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring.data.jpa.version}</version>
        </dependency>

        <!-- Hibernate (JPA Provider) -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- Postgres JDBC Driver -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>${postgres.version}</version>
        </dependency>

        <!-- GWT -->
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-servlet</artifactId>
            <version>${gwt.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-user</artifactId>
            <version>${gwt.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.api.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- GWT Compiler Plugin -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin</artifactId>
                <version>${gwt.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <module>com.example.gwt.Example</module>
                    <runTarget>index.html</runTarget>
                </configuration>
            </plugin>

            <!-- Maven War Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
                <configuration>
                    <failOnMissingWebXml>true</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
3. Spring Configuration (Java Config)

Create SpringConfig.java in com.example.config to set up the database, JPA, and Spring Data:

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@ComponentScan(basePackages = "com.example")
@PropertySource("classpath:db.properties")
@EnableJpaRepositories(basePackages = "com.example.repository")
public class SpringConfig {

    private final Environment env;

    public SpringConfig(Environment env) {
        this.env = env;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("db.driver"));
        dataSource.setUrl(env.getProperty("db.url"));
        dataSource.setUsername(env.getProperty("db.username"));
        dataSource.setPassword(env.getProperty("db.password"));
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("com.example.entity");

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);

        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        jpaProperties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
        em.setJpaProperties(jpaProperties);

        return em;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }
}

Add db.properties in src/main/resources with your Postgres details:

db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/your_db_name
db.username=your_db_user
db.password=your_db_password

hibernate.hbm2ddl.auto=update
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
4. Spring Data JPA Setup

First, a simple JPA entity User.java in com.example.entity:

package com.example.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // Getters, setters, and default constructor
    public User() {}

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

    // ... add getters and setters for all fields
}

Then the Spring Data repository UserRepository.java in com.example.repository:

package com.example.repository;

import com.example.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    // Add custom queries here if needed
}
5. GWT Remote Service Setup

First, the client-side service interface UserService.java in com.example.gwt.client:

package com.example.gwt.client;

import com.example.entity.User;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

import java.util.List;

@RemoteServiceRelativePath("userService")
public interface UserService extends RemoteService {
    List<User> getAllUsers();
    User saveUser(User user);
}

The required async interface UserServiceAsync.java:

package com.example.gwt.client;

import com.example.entity.User;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.List;

public interface UserServiceAsync {
    void getAllUsers(AsyncCallback<List<User>> callback);
    void saveUser(User user, AsyncCallback<User> callback);
}

Now the server-side servlet implementation UserServiceImpl.java in com.example.gwt.server. Critical: Extend SpringBeanAutowiringSupport to enable Spring dependency injection in the GWT servlet:

package com.example.gwt.server;

import com.example.entity.User;
import com.example.gwt.client.UserService;
import com.example.repository.UserRepository;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import java.util.List;

public class UserServiceImpl extends RemoteServiceServlet implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    }

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

    @Override
    public User saveUser(User user) {
        return userRepository.save(user);
    }
}

Add the GWT module config Example.gwt.xml in src/main/webapp/WEB-INF/gwt:

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='example'>
    <inherits name='com.google.gwt.user.User'/>
    <inherits name='com.google.gwt.user.theme.clean.Clean'/>

    <source path='client'/>
    <source path='shared'/> <!-- Use this if you have shared client/server classes -->

    <entry-point class='com.example.gwt.client.EntryPoint'/>
</module>

And a basic GWT entry point EntryPoint.java in com.example.gwt.client to test the service:

package com.example.gwt.client;

import com.example.entity.User;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.List;

public class EntryPoint implements EntryPoint {
    private final UserServiceAsync userService = UserService.App.getInstance();

    @Override
    public void onModuleLoad() {
        // Test fetching users
        userService.getAllUsers(new AsyncCallback<List<User>>() {
            @Override
            public void onSuccess(List<User> users) {
                Window.alert("Fetched " + users.size() + " users!");
            }

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Error fetching users: " + caught.getMessage());
            }
        });
    }
}
6. web.xml Configuration

This is where we register the GWT servlet and set up Spring's context loader. Create web.xml in src/main/webapp/WEB-INF:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- Spring Context Loader -->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.example.config.SpringConfig</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- GWT Remote Service Servlet -->
    <servlet>
        <servlet-name>UserService</servlet-name>
        <servlet-class>com.example.gwt.server.UserServiceImpl</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserService</servlet-name>
        <url-pattern>/example/userService</url-pattern>
    </servlet-mapping>

    <!-- Welcome File -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file-list>
    </welcome-file-list>
</web-app>

Add a simple index.html in src/main/webapp:

<!DOCTYPE html>
<html>
<head>
    <title>Spring Data + GWT Non-Boot Example</title>
    <script type="text/javascript" language="javascript" src="example/example.nocache.js"></script>
</head>
<body>
    <h1>Spring Data + GWT Non-Boot App</h1>
</body>
</html>
7. Running the Project
  1. Set up Postgres: Create a database matching the db.url in db.properties.
  2. Compile GWT: Run mvn gwt:compile to build the client-side code.
  3. Build the WAR: Run mvn package to generate the WAR file.
  4. Deploy: Deploy the WAR to a servlet container like Tomcat or Jetty.
  5. Test: Access http://localhost:8080/spring-data-gwt-non-boot—you'll see an alert showing the number of users (initially 0, but you can extend the entry point to save a user first).

This setup gives you full control over servlet registration and Spring configuration, no Spring Boot magic involved. You can extend it with more services, entities, or GWT UI components as needed.

内容的提问来源于stack exchange,提问作者Alex Worden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:47:50