我们将环境及数据库搭建好以后,开始写核心业务逻辑代码:获取题目,并将其转化为乱序,通过JSON数据返回给前端。
首先经行mapper相关类的编写。在EnglishMapper接口类里加入对应的方法
package com.kfzx.mapper;
import java.util.List;
import com.kfzx.model.Cloze;
public interface EnglishMapper {
List<Cloze> getCloze(int unit);
}
然后在EnglishMapper.xml中写相应的实现代码。此处还因注意在对应配置文件中加入相关语句,这些都属于SSM的基础知识,本文将不再经行阐述。
EnglishMapper.xml里面的实现如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper (View Source for full doctype...)>
- <!-- namespace:必须与对应的接口全类名一致 id:必须与对应接口的某个对应的方法名一致
-->
- <!-- mybsits_config中配置的alias类别名,也可以直接配置resultType为类路径
-->
- <mapper namespace="com.kfzx.mapper.EnglishMapper">
<select id="getCloze" parameterType="int" resultType="Cloze">select id,question,word from cloze where id = #{id}</select>
</mapper>
写好mapper后,我们开始写service层代码,结构还是和以前一样, 先在service包里写相应的接口,然后在对应的包经行实现。
,首先写接口类
package com.kfzx.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface EnglishService {
void getRequest(HttpServletRequest request, HttpServletResponse response);
void sendWord(HttpServletRequest request, HttpServletResponse response);
}
然后将其实现,本类一共实现了两个功能,一是取出题目,并将其打乱,二是对前台返回的用户填写的数据经行校验,并将结果以list数组的形式再返回给前端,让其进行相应显示
package com.kfzx.service.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kfzx.mapper.EnglishMapper;
import com.kfzx.model.Cloze;
import com.kfzx.model.Word;
import com.kfzx.service.EnglishService;
import com.kfzx.utils.RandomArray;
@Service
@Transactional
public class EnglishServiceImpl implements EnglishService {
@Resource
private EnglishMapper mapper;
// 设置一个字符串类型的数组,与前台传输过来的数据进行对比,确认答案、、、、、、以后可以优化(前台返回答案时候带上相应题目的id)
String[] words = new String[10];
@Override
public void getRequest(HttpServletRequest request, HttpServletResponse response) {
List<Cloze> list = null;
// 获取单元
// int unit = Integer.parseInt(request.getParameter("unit"));
int unit = 1;// 先设置一个固定值进行测试
// 生成相应单元的随机题目
int num[] = RandomArray.randomArray((unit - 1) * 10 + 1, unit * 10, 10);
// String jsonString = null;
JSONArray jsonArray = new JSONArray();
int j = 0; // 正确答案数组下标
for (int i : num) {
list = mapper.getCloze(i);// 获取出一道题的信息
// 便利list数组,并将其封装成JSON对象数组
for (Cloze cloze : list) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", cloze.getId());
jsonObject.put("question", cloze.getQuestion());
jsonObject.put("word", cloze.getWord());
jsonArray.add(jsonObject);
}
Cloze cloze = list.get(0);// 将其转化为一个对象,并获取到答案,存入答案数组中
words[j++] = cloze.getWord();
}
response.setCharacterEncoding("utf-8");
try {
response.getWriter().print(jsonArray);
System.out.println(jsonArray);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void sendWord(HttpServletRequest request, HttpServletResponse response) {
int iword = 0;// 用户填入的单词
ArrayList<Integer> list = new ArrayList<>();
String jsonStr = request.getParameter("json1");
System.out.println(jsonStr);
List<Word> parseArray = JSON.parseArray(jsonStr, Word.class);// 将前来传来的json串解析为对象数组
for (Word word : parseArray) {
// 将用户的答案与正确答案进行对比
if (word.getWord().equalsIgnoreCase(words[iword++])) {
list.add(1);
} else {
list.add(0);
}
}
String jsonString = JSON.toJSONString(list);
response.setCharacterEncoding("utf-8");
try {
response.getWriter().print(jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
}
这段代码目前是可以达到效果的,近期还将经行相关优化,使其逻辑及结构更加完整。在生成随机题号时,上面代码调用了我们自己写个一个util类
package com.kfzx.utils;
import java.util.Random;
/**
* * 随机指定范围内N个不重复的数 在初始化的无重复待选数组中随机产生一个数放入结果中, 将待选数组被随机到的数,用待选数组(len-1)下标对应的数替换
* 然后从len-2里随机产生下一个随机数,如此类推
*
* @param max
* 指定范围最大值
* @param min
* 指定范围最小值
* @param n
* 随机数个数
* @return int[] 随机数结果集
*
* @author
*
*/
public class RandomArray {
public static int[] randomArray(int min, int max, int n) {
int len = max - min + 1;
if (max < min || n > len) {
return null;
}
// 初始化给定范围的待选数组
int[] source = new int[len];
for (int i = min; i < min + len; i++) {
source[i - min] = i;
}
int[] result = new int[n];
Random rd = new Random();
int index = 0;
for (int i = 0; i < result.length; i++) {
// 待选数组0到(len-2)随机一个下标
index = Math.abs(rd.nextInt() % len--);
// 将随机到的数放入结果集
result[i] = source[index];
// 将待选数组中被随机到的数,用待选数组(len-1)下标对应的数替换
source[index] = source[len];
}
return result;
}
}
通过这段代码,可以高效地产生对应utile的乱序题目,由于我们采用的是list集合来承接数据库返回的内容,所以题目对应的id,question,answer并不会被打乱。
这时我们就可以将其用JSON封装起来,通过response返回给前端。
最后我们进行controller部分的编写,其代码如下
package com.kfzx.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.kfzx.service.EnglishService;
@Controller
@RequestMapping
public class EnglishController {
@Autowired
private EnglishService englishService;
@RequestMapping("/getRequest")
public void getRequest(HttpServletRequest request, HttpServletResponse response) {
englishService.getRequest(request, response);
}
@RequestMapping("/sendword")
public void sendWord(HttpServletRequest request, HttpServletResponse response) {
englishService.sendWord(request, response);
}
}
由于本系统功能并不多,所以在类最上面的RequestMapping中并没有写其他路径
至此,我们本系统的题目展示及校验已经实现。总结一下,由于是第一次写这样的业务,坎坷还是遇到了一些,还有就是数据交互那一块,也是第一次用到,所以进行了好多次尝试才将其实现。但反过来看的时候才发现,自己其实并没有写多少代码,事实证明逻辑思维还真的是特别重要。