英语复习系统【4】

我们将环境及数据库搭建好以后,开始写核心业务逻辑代码:获取题目,并将其转化为乱序,通过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中并没有写其他路径

至此,我们本系统的题目展示及校验已经实现。总结一下,由于是第一次写这样的业务,坎坷还是遇到了一些,还有就是数据交互那一块,也是第一次用到,所以进行了好多次尝试才将其实现。但反过来看的时候才发现,自己其实并没有写多少代码,事实证明逻辑思维还真的是特别重要。



猜你喜欢

转载自blog.csdn.net/TTTZZZTTTZZZ/article/details/80743110