Spring Boot+Freemarker

Freemarker

Freemarker是一个用Java开发的模板引擎,一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。

也就是说模型+数据=输入(HTML等)

Spring Boot+Freemarker

目录结构:
在这里插入图片描述
引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
 <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

application.yml:

spring:
  application:
    name: test-freemarker #指定服务名
  freemarker:
    cache: false  #关闭模板缓存,方便测试
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
    template-loader-path: classpath:/templates/ #模板路径
    suffix: .ftl #模板后缀名称

Student :

@Data
@ToString
public class Student {
    private String name;//姓名
    private int age;//年龄
    private Date birthday;//生日
    private Float mondy;//钱包
    private List<Student> friends;//朋友列表
    private Student bestFriend;//最好的朋友
}

test1.ftl:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Freemarker</title>
</head>
<body>
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>余额</td>
    </tr>
    <#list stus as stu>
        <tr>
            <td>${stu_index + 1}</td>
            <td <#if stu.name =='小明'>style="background:deepskyblue;"</#if>>${stu.name}</td>
            <td>${stu.age}</td>
            <td >${stu.mondy}</td>
        </tr>
    </#list>
</table>

<br/><br/>
输出stu1的学生信息:<br/>
姓名:${stuMap['stu1'].name}<br/>
年龄:${stuMap['stu1'].age}<br/>
输出stu1的学生信息:<br/>
姓名:${stu1.name}<br/>
年龄:${stu1.age}<br/>
遍历输出两个学生信息:<br/>
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>余额</td>
    </tr>
<#list stuMap?keys as k>
<tr>
    <td>${k_index + 1}</td>
    <td>${stuMap[k].name}</td>
    <td>${stuMap[k].age}</td>
    <td >${stuMap[k].mondy}</td>
</tr>
</#list>
</table>
</body>
</html>

FreemarkerController:

@RequestMapping("/freemarker")
@Controller
public class FreemarkerController {
    @RequestMapping("/test1")
    public String freemarker(Map<String, Object> map){
        //向数据模型放数据
        map.put("name","freemarker");
        Student stu1 = new Student();
        stu1.setName("张三");
        stu1.setAge(18);
        stu1.setMondy(1000f);
        stu1.setBirthday(new Date());
        Student stu2 = new Student();
        stu2.setName("李四");
        stu2.setMondy(200f);
        stu2.setAge(19);
        stu2.setBirthday(new Date());
        List<Student> friends = new ArrayList<>();
        friends.add(stu1);
        stu2.setFriends(friends);
        stu2.setBestFriend(stu1);
        List<Student> stus = new ArrayList<>();
        stus.add(stu1);
        stus.add(stu2);
        //向数据模型放数据
        map.put("stus",stus);
        //准备map数据
        HashMap<String,Student> stuMap = new HashMap<>();
        stuMap.put("stu1",stu1);
        stuMap.put("stu2",stu2);
        //向数据模型放数据
        map.put("stu1",stu1);
        //向数据模型放数据
        map.put("stuMap",stuMap);
        //返回模板文件名称
        return "test1";
    }
}

演示效果:
在这里插入图片描述

模板文件静态化

使用freemarker将模板和数据生成html静态文件存储在磁盘上。

添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.3.2</version>
</dependency>

编写测试类:

@SpringBootTest
@RunWith(SpringRunner.class)
public class FreemarkerTest {
    //基于模板生成静态化文件
    @Test
    public void testGenerateHtml() throws IOException, TemplateException {
        //创建配置类
        Configuration configuration=new Configuration(Configuration.getVersion());
        String classpath = this.getClass().getResource("/").getPath();
        //设置模板路径
        configuration.setDirectoryForTemplateLoading(new File(classpath + "/templates/"));
        //设置字符集
        configuration.setDefaultEncoding("utf-8");
        //加载模板
        Template template = configuration.getTemplate("test1.ftl");
        //数据模型
        Map map = getMap();
        //静态化
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        //静态化内容
        System.out.println(content);
        InputStream inputStream = IOUtils.toInputStream(content);
        //输出文件到d:/test1.html中
        FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html"));
        int copy = IOUtils.copy(inputStream, fileOutputStream);
        System.out.println(copy);
    }

    //基于模板字符串生成静态化文件
    @Test
    public void testGenerateHtmlByString() throws IOException, TemplateException {
        //创建配置类
        Configuration configuration=new Configuration(Configuration.getVersion());
        //获取模板内容
        //模板内容,这里测试时使用简单的字符串作为模板
        String templateString="" +
                "<html>\n" +
                "    <head></head>\n" +
                "    <body>\n" +
                "    名称:${name}\n" +
                "    </body>\n" +
                "</html>";

        //加载模板
        //模板加载器
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate("template",templateString);
        configuration.setTemplateLoader(stringTemplateLoader);
        Template template = configuration.getTemplate("template","utf-8");

        //数据模型
        Map map = getMap();
        //静态化
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        //静态化内容
        System.out.println(content);
        InputStream inputStream = IOUtils.toInputStream(content);
        //输出文件
        FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html"));
        IOUtils.copy(inputStream, fileOutputStream);
    }

    //数据模型
    private Map getMap(){
        Map<String, Object> map = new HashMap<>();
        //向数据模型放数据
        map.put("name","freemarker");
        Student stu1 = new Student();
        stu1.setName("张三");
        stu1.setAge(18);
        stu1.setMondy(1000f);
        stu1.setBirthday(new Date());
        Student stu2 = new Student();
        stu2.setName("李四");
        stu2.setMondy(200f);
        stu2.setAge(19);
        stu2.setBirthday(new Date());
        List<Student> friends = new ArrayList<>();
        friends.add(stu1);
        stu2.setFriends(friends);
        stu2.setBestFriend(stu1);
        List<Student> stus = new ArrayList<>();
        stus.add(stu1);
        stus.add(stu2);
        //向数据模型放数据
        map.put("stus",stus);
        //准备map数据
        HashMap<String,Student> stuMap = new HashMap<>();
        stuMap.put("stu1",stu1);
        stuMap.put("stu2",stu2);
        //向数据模型放数据
        map.put("stu1",stu1);
        //向数据模型放数据
        map.put("stuMap",stuMap);
        return map;
    }
}
<think>我们使用Java技术栈(Spring Boot + FreeMarker + LayUI + MyBatis)开发一个完整的游戏登录项目。这个项目将包括用户登录、注册、密码重置等基本功能,以及游戏账号的绑定和管理。我们将使用IntelliJ IDEA作为开发IDE,SQLyog作为数据库管理工具。 项目结构: 1. 数据库设计:创建用户表、游戏账号表等。 2. 后端开发:使用Spring Boot构建后端服务,MyBatis作为ORM框架。 3. 前端开发:使用FreeMarker模板引擎结合LayUI框架构建前端页面。 4. 功能实现:用户注册、登录、退出、游戏账号绑定、查看等。 步骤: 1. 数据库设计(MySQL): - 用户表(user): id: 主键,自增 username: 用户名,唯一 password: 密码(加密存储) email: 邮箱 phone: 手机号 create_time: 创建时间 last_login_time: 最后登录时间 - 游戏账号表(game_account): id: 主键,自增 user_id: 关联user表的id game_username: 游戏内用户名 game_server: 游戏服务器 create_time: 创建时间 2. 创建Spring Boot项目: - 使用Spring Initializr创建项目,选择依赖:Web, MyBatis, MySQL, Freemarker 3. 配置数据库连接: 在application.properties中配置数据源和MyBatis。 4. 编写实体类(Entity): - User - GameAccount 5. 编写Mapper接口和Mapper XML文件: - 实现基本的CRUD操作,以及根据用户名查询用户、根据用户ID查询游戏账号等。 6. 编写Service层和ServiceImpl: - 用户服务:注册、登录、修改密码等。 - 游戏账号服务:绑定游戏账号、查询用户的游戏账号等。 7. 编写Controller: - 处理HTTP请求,调用Service层,返回视图或数据。 8. 前端页面: - 使用FreeMarker模板,结合LayUI的组件(表单、表格、弹窗等)构建页面。 - 页面包括:登录页、注册页、主页(显示游戏账号信息)、绑定游戏账号页等。 9. 安全考虑: - 密码使用BCryptPasswordEncoder加密。 - 使用Session或Token(如JWT)来管理用户登录状态。 10. 测试: - 使用Postman测试接口,或者通过页面进行功能测试。 下面是一个简单的代码示例: 实体类User.java: ```java @Data public class User { private Long id; private String username; private String password; private String email; private String phone; private Date createTime; private Date lastLoginTime; } ``` 实体类GameAccount.java: ```java @Data public class GameAccount { private Long id; private Long userId; private String gameUsername; private String gameServer; private Date createTime; } ``` UserMapper.java: ```java @Mapper public interface UserMapper { User findByUsername(@Param("username") String username); void insert(User user); // 其他方法... } ``` 在UserMapper.xml中编写SQL。 UserService和UserServiceImpl实现用户注册和登录逻辑。 注册时,对密码进行加密: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private PasswordEncoder passwordEncoder; @Override public void register(User user) { // 检查用户名是否已存在 User existingUser = userMapper.findByUsername(user.getUsername()); if (existingUser != null) { throw new RuntimeException("用户名已存在"); } // 加密密码 user.setPassword(passwordEncoder.encode(user.getPassword())); user.setCreateTime(new Date()); userMapper.insert(user); } // 登录方法 @Override public User login(String username, String password) { User user = userMapper.findByUsername(username); if (user == null) { throw new RuntimeException("用户不存在"); } if (!passwordEncoder.matches(password, user.getPassword())) { throw new RuntimeException("密码错误"); } // 更新最后登录时间 user.setLastLoginTime(new Date()); userMapper.updateLastLoginTime(user.getId(), new Date()); return user; } } ``` 在Controller中处理登录请求: ```java @Controller public class LoginController { @Autowired private UserService userService; @GetMapping("/login") public String loginPage() { return "login"; } @PostMapping("/login") public String login(String username, String password, HttpSession session) { try { User user = userService.login(username, password); session.setAttribute("user", user); return "redirect:/index"; } catch (RuntimeException e) { // 返回错误信息到登录页 return "login"; } } } ``` 前端登录页面(login.ftl)使用Layui的表单: ```html <!DOCTYPE html> <html> <head> <title>登录</title> <link rel="stylesheet" href="/layui/css/layui.css"> </head> <body> <div class="layui-container"> <form class="layui-form" action="/login" method="post"> <div class="layui-form-item"> <label class="layui-form-label">用户名</label> <div class="layui-input-block"> <input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密码</label> <div class="layui-input-block"> <input type="password" name="password" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">登录</button> </div> </div> </form> </div> <script src="/layui/layui.js"></script> </body> </html> ``` 以上是一个简单的登录示例。其他功能如注册、游戏账号绑定等类似实现。 注意:这只是一个基础框架,实际开发中还需要考虑更多细节,例如表单验证、异常处理、事务管理、日志记录等。 最后,根据要求,在回答后提出3-5个相关问题。</think>### 游戏登录项目开发方案(基于 Java 技术栈) #### 一、技术栈配置 1. **开发工具** - IntelliJ IDEA(项目开发) - SQLyog(MySQL 数据库管理) - Postman(API 测试) 2. **技术框架** ```markdown - 后端: Spring Boot 2.7.x + MyBatis-Plus - 前端: FreeMarker 模板引擎 + LayUI 2.x - 安全: Spring Security + JWT - 数据库: MySQL 8.0 - 构建工具: Maven ``` #### 二、核心功能实现 1. **数据库设计** ```sql CREATE TABLE `user` ( `id` BIGINT AUTO_INCREMENT PRIMARY KEY, `username` VARCHAR(50) UNIQUE NOT NULL, `password` VARCHAR(100) NOT NULL, -- BCrypt加密存储 `email` VARCHAR(100), `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE `game_account` ( `id` BIGINT PRIMARY KEY, `user_id` BIGINT NOT NULL, `game_uid` VARCHAR(20) NOT NULL, -- 游戏内ID `server_id` INT NOT NULL, -- 游戏服务器ID FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ); ``` 2. **登录认证流程(Spring Security + JWT)** ```java // JWT生成工具类 public class JwtUtils { public static String generateToken(UserDetails details) { return Jwts.builder() .setSubject(details.getUsername()) .setExpiration(new Date(System.currentTimeMillis() + 3600_000)) .signWith(SignatureAlgorithm.HS512, "SECRET_KEY") .compact(); } } // 登录控制器 @PostMapping("/login") public Result login(@RequestBody LoginDTO dto) { Authentication auth = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(dto.getUsername(), dto.getPassword()) ); SecurityContextHolder.getContext().setAuthentication(auth); String token = JwtUtils.generateToken((UserDetails) auth.getPrincipal()); return Result.success().put("token", token); } ``` 3. **前端页面示例(FreeMarker + LayUI)** ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>游戏登录</title> <link rel="stylesheet" href="/layui/css/layui.css"> </head> <body> <form class="layui-form" style="width: 350px; margin: 100px auto;"> <div class="layui-form-item"> <label class="layui-form-label">账号</label> <div class="layui-input-block"> <input type="text" name="username" class="layui-input" required> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密码</label> <div class="layui-input-block"> <input type="password" name="password" class="layui-input" required> </div> </div> <div class="layui-form-item"> <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="login">登录</button> </div> </form> <script src="/layui/layui.js"></script> <script> layui.use(['form', 'jquery'], function() { const form = layui.form; const $ = layui.$; form.on('submit(login)', function(data) { $.post('/api/login', data.field, function(res) { if(res.code === 0) { localStorage.setItem('token', res.data.token); // 存储JWT location.href = '/game/list'; // 跳转游戏列表页 } }); return false; }); }); </script> </body> </html> ``` #### 三、关键集成点 1. **MyBatis-Plus 数据操作** ```java @Mapper public interface UserMapper extends BaseMapper<User> { @Select("SELECT * FROM game_account WHERE user_id = #{userId}") List<GameAccount> selectAccountsByUserId(Long userId); } ``` 2. **安全配置(Spring Security)** ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/register").permitAll() .anyRequest().authenticated() .and() .addFilter(new JwtAuthFilter(authenticationManager())); } } ``` #### 四、项目部署 1. **生产环境配置** ```properties # application-prod.properties spring.datasource.url=jdbc:mysql://db-server:3306/game_db?useSSL=false spring.datasource.username=prod_user spring.datasource.password=****** server.port=8080 ``` 2. **LayUI 资源加载 ```html <!-- 在FreeMarker模板中引用 --> <#assign ctx = springMacroRequestContext.getContextPath()> <link rel="stylesheet" href="${ctx}/layui/css/layui.css"> <script src="${ctx}/layui/layui.js"></script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值