新闻客户端后台主要是提供了一些接口供移动端调用,实现了上传apk到服务器的功能,以及推送功能等等,开发中使用的框架式ssm,数据库mysql,服务器tomcat,新闻客户端的主体是新闻,需要实时更新并推送到客户端上。本次我选择的新闻数据源是聚合数据,请求成功后返回的数据结构
新闻数据结构截图:
根据以上数据信息,整理出来4张表。
tb_newsdetail --新闻详情表
--newsdetail_id
--uniquekey
--title
--date
--category
--author_name
--url
--pic1
--pic2
--pic3
tb_category --新闻类别表
--category_id
--categoryname
--categoryspell
tb_comment --新闻跟帖表
--comment_id
--newsdetail_id
--content
--date
tb_version --app版本表
--version_id
--number
--content
--date
--status
--path
考虑到实时更新数据需要使用调度器,选择了quartz,quartz做持久化需要使用数据库存储一些信息。整个表结构是这样的,数据库sql会在源码里给出
定义接口。
添加新闻跟帖,查询新闻跟帖集合,查询执行id新闻,查询新闻集合,查询app版本
接口文档会在源码中给出
项目中使用新闻数据api,到官网申请key,把申请的key放在 WebRoot/admin/config/KEY.txt下。
如果遇到客户端请后台提交数据库中中文乱码,首先检查mysql编码格式是否为UTF-8,然后修改tomcat下conf/server.xml,在下面这段代码中加上URIEncoding=“UTF-8”
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
1、实现api接口Controller, pd = this.getPageData(); 将请求的参数封装到PageData中,PageData类是封装map对象,实际上是将请求参数封装到map中
package com.controller.api;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.controller.base.BaseController;
import com.service.api.ApiService;
import com.utils.AppUtil;
import com.utils.PageData;
@Controller
@RequestMapping(value = "/api")
public class ApiController extends BaseController {
private static final String TAG = ApiController.class.getSimpleName();
@Resource(name = "apiService")
private ApiService apiService;
/**
* 检查更新
* @return
*/
@RequestMapping(value = "/findVersion")
@ResponseBody
public Object findVersion() {
logBefore(logger, TAG, "findVersion 检查更新");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
PageData result = apiService.findVersion();
map.put("pd", result);
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
/**
* 返回10条新闻列表
*
* @return
* @throws Exception
*/
@RequestMapping(value = "/news")
@ResponseBody
public Object getNews() throws Exception {
logBefore(logger, TAG, "getNews 返回10条新闻列表");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
List<PageData> pdList = apiService.getNews(pd);
map.put("pdList", pdList);
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
/**
* 添加帖子
* @return
*/
@RequestMapping(value = "/addComment")
@ResponseBody
public Object addComment() {
logBefore(logger, TAG, "addComment 添加帖子");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
apiService.addComment(pd);
int count = apiService.findCommentById(pd);
map.put("count", count);
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
/**
* 帖子集合
* @return
*/
@RequestMapping(value = "/commentList")
@ResponseBody
public Object commentList() {
logBefore(logger, TAG, "commentList 帖子集合");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
List<PageData> pdList= apiService.commentList(pd);
map.put("pdList", pdList);
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
/**
* 清除重复的新闻信息
* @return
*/
@RequestMapping(value = "/cleanRepetition")
@ResponseBody
public Object cleanRepetition() {
logBefore(logger, TAG, "cleanRepetition 清除重复的新闻信息");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
apiService.cleanRepetition();
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
/**
* 返回指定新闻
*
* @return
* @throws Exception
*/
@RequestMapping(value = "/findNewsById")
@ResponseBody
public Object findNewsById() throws Exception {
logBefore(logger, TAG, "findNewsById 返回指定新闻");
PageData pd = new PageData();
Map<String, Object> map = new HashMap<String, Object>();
pd = this.getPageData();
try {
PageData result = apiService.findNewsById(pd);
map.put("pd", result);
map.put("status", "01");
map.put("message", "success");
} catch (Exception e) {
logger.error(e.toString(), e);
map.put("status", "02");
map.put("message", "error");
logger.error(e.toString(), e);
} finally {
logAfter(logger);
}
return AppUtil.returnObject(pd, map);
}
}
2、service实现,实现代码比较简单
package com.service.api;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.dao.DaoSupport;
import com.utils.DateUtil;
import com.utils.PageData;
import com.utils.UuidUtil;
@SuppressWarnings("unchecked")
@Service("apiService")
public class ApiService {
@Resource(name = "daoSupport")
private DaoSupport dao;
/**
* 返回最新版本信息
* @throws Exception
*/
public PageData findVersion() throws Exception {
return (PageData) dao.findForObject("ApiMapper.findVersion",null);
}
/**
* 返回指定id
* @param pd
* @throws Exception
*/
public PageData findNewsById(PageData pd) throws Exception {
return (PageData) dao.findForObject("ApiMapper.findNewsById", pd);
}
/**
* 查询新闻详情
*
* @return
* @throws Exception
*/
public List<PageData> getNews(PageData pd) throws Exception {
int flag;
if (pd.containsKey("count")) {
int count = Integer.parseInt(pd.getString("count"));
flag = count * 10;
} else {
flag = 0;
}
pd.put("flag", flag);
return (List<PageData>) dao.findForList("ApiMapper.getNews", pd);
}
/**
* 添加跟帖
*
* @param pd
* @throws Exception
*/
public void addComment(PageData pd) throws Exception {
pd.put("commentId", UuidUtil.get32UUID());
pd.put("date", DateUtil.getTime());
dao.save("ApiMapper.addComment", pd);
}
/**
* 返回跟帖数量
* @param pd
* @throws Exception
*/
public int findCommentById(PageData pd) throws Exception {
return (Integer) dao.findForObject("ApiMapper.findCommentById", pd);
}
/**
* 跟帖详情
*
* @return
* @throws Exception
*/
public List<PageData> commentList(PageData pd) throws Exception {
return (List<PageData>) dao.findForList("ApiMapper.commentList", pd);
}
/**
* 清除重复的新闻
*
* @return
* @throws Exception
*/
public void cleanRepetition() throws Exception {
dao.delete("ApiMapper.cleanRepetition", null);
}
}
3、mapper.xml文件编写sql代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ApiMapper">
<select id="findVersion" resultType="pd">
SELECT
VERSION_ID,
NUMBER,
CONTENT,
DATE,
STATUS,
PATH
FROM
TB_VERSION
WHERE
STATUS = '1'
ORDER BY DATE DESC
LIMIT 1
</select>
<select id="findNewsById" parameterType="pd" resultType="pd">
SELECT
NEWSDETAIL_ID,
UNIQUEKEY,
TITLE,
PIC1,
URL,
`DATE`,
(SELECT CATEGORYNAME FROM TB_CATEGORY WHERE N.CATEGORY = CATEGORYSPELL) CATEGORY,
(SELECT COUNT(C.NEWSDETAIL_ID) FROM TB_COMMENT C WHERE C.NEWSDETAIL_ID = N.NEWSDETAIL_ID) `COMMENT`
FROM TB_NEWSDETAIL N
WHERE 1=1
and
N.NEWSDETAIL_ID = #{newsdetailId}
</select>
<select id="getNews" resultType="pd" parameterType="pd">
SELECT
NEWSDETAIL_ID,
UNIQUEKEY,
TITLE,
PIC1,
URL,
`DATE`,
(SELECT CATEGORYNAME FROM TB_CATEGORY WHERE N.CATEGORY = CATEGORYSPELL) CATEGORY,
(SELECT COUNT(C.NEWSDETAIL_ID) FROM TB_COMMENT C WHERE C.NEWSDETAIL_ID = N.NEWSDETAIL_ID) `COMMENT`
FROM TB_NEWSDETAIL N
WHERE 1=1
<if test="type != null and type != ''">
AND
CATEGORY = #{type}
</if>
ORDER BY `DATE` DESC
LIMIT #{flag},10
</select>
<insert id="addComment" parameterType="pd">
INSERT INTO TB_COMMENT (
comment_id,
newsdetail_id,
content,
date
) VALUES(
#{commentId},
#{newsdetailId},
#{content},
#{date}
)
</insert>
<select id="findCommentById" parameterType="pd" resultType="Integer">
SELECT
COUNT(NEWSDETAIL_ID)
FROM
TB_COMMENT
WHERE
NEWSDETAIL_ID = #{newsdetailId}
GROUP BY NEWSDETAIL_ID
</select>
<select id="commentList" resultType="pd" parameterType="pd">
SELECT
COMMENT_ID,
`DATE`,
CONTENT
FROM TB_COMMENT
WHERE 1=1
AND
NEWSDETAIL_ID = #{newsdetailId}
ORDER BY `DATE` DESC
</select>
<delete id="cleanRepetition">
DELETE
FROM
tb_newsdetail
WHERE
uniquekey
IN
(
SELECT
a.uniquekey
FROM
(
SELECT
uniquekey
FROM
tb_newsdetail
GROUP BY uniquekey
HAVING COUNT(uniquekey) >1
) a
)
</delete>
</mapper>
访问项目地址 http://localhost:8080/news 可在页面中上传apk,点击推送可推送apk
http://localhost:8080/news/category/category //查看所有类别
http://localhost:8080/news/newsdetail/upload //手动更新新闻信息,需要注意每天只能请求100次数据
http://localhost:8080/news/newsdetail/newsdetail //返回新闻信息
app端源码请点击这里