一、实验要求
1. 综合应用HTML、CSS完成页面布局
2. 结合jQuery AJAX实现数据请求与提交
3. 熟悉Web程序的发布
二、实验内容
1. 搭建前端应用程序
2. 综合应用HTML、CSS、JavaScript技术
3. 以jQuery AJAX实现数据请求与提交
三、实验内容和步骤
1、设计新闻列表布局
创建网页,创建网页文件index.html,按布局设计图“网页设计图_新闻列表页”进行精确布局,布局方法参考实验1。
设计思路:头部和底部将position设置为fixed,分别居上和居下放置,中间的列表内容只要高度大于屏幕高度,自然就能上下滑动。
2、创建数据库
在MySQL中创建一个数据库,数据库名自取,在数据库中创建一个表News,字段设计见表1.
表1 数据库设计
表名:News
字段名 | 类型 | 约束 | 说明 |
id | int | 主键,自增 | 新闻ID |
title | varchar(200) | 新闻标题 | |
pic | varchar(50) | 新闻图片 | |
source | varchar(50) | 新闻来源 | |
type | varchar(10) | 新闻栏目 | |
ishead | bool | 是否头条(号外) | |
time | datetime | 发表时间 |
执行“新闻列表.xlsx”中的SQL语句写入新闻数据。
3、设计newslist接口
创建newslist.java文件,将其设计成为一个servlet,基本逻辑就是接收请求,再返回对应的新闻列表,请求数据见表2.
表2 newslist请求参数
数据名 | 请求方式 | 取值范围 |
type | GET/POST | game、finance、tour、tech、sports、edu、sichuan、head |
当取值为head时,搜索数据库中news表ishead字段为1的所有新闻,否则,搜索news表中type字段为对应值的新闻,将搜索结果封装为JSON后返回,JSON格式见表3.
表3 newslist请求参数
{ state: "SUC", msg: "成功返回新闻列表", content: [ {id: 1, title: "新闻标题", pic: "新闻图片", source: "新闻来源", type: "新闻类型", time: "新闻时间"}, {id: 2, title: "新闻标题", pic: "新闻图片", source: "新闻来源", type: "新闻类型", time: "新闻时间"}, {id: 2, title: "新闻标题", pic: "新闻图片", source: "新闻来源", type: "新闻类型", time: "新闻时间"} ], time: "服务器时间" } |
提示:构造这个JSON需要一个Message消息类,和一个News视图类,将试图类实例化后装入List序列,再装入content属性即可。
表4 新闻列表结果构造代码提示
Message msgObj = new Message(); //创建消息对象 msgObj.setState("SUC"); List<News> newsList = new ListArray<News>(); //创建新闻列表对象 //遍历数据库表查询结果 While(rs.next()){ News newsItem = new News(); //创建新闻对象(视图类对象) newsItem.setId(rs.getInt("id")); //写入新闻ID newsItem.setTitle(rs.getString("title"));//写入新闻标题 newsItem.setPic(rs.getString("pic")); //写入新闻图片 …… //写入其他字段 newsList.add(newsItem); //将新闻对象装入新闻列表 } //循环完毕后,所有新闻对象均被装入新闻列表,再将新闻列表写入content msgObj.setContent(newsList); |
4、index.html页面逻辑
(1)点击每个新闻栏目,向newslist发起对应栏目的请求,具体请求的键和值见表2。
type: game、finance、tour、tech、sports、edu、sichuan、head
(2)收到服务器的响应后,将收到的JSON数据渲染至 中,渲染时可覆盖上一次请求的新闻列表,JSON格式见表3。
(3)新闻列表支持上下滑动。
(4)index.html设计图
四、代码实现
1、News新闻类:
public class News {
int id;
String title;
String pic;
String source;
String type;
String time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
@Override
public String toString() {
return "News{" +
"id=" + id +
", title='" + title + '\'' +
", pic='" + pic + '\'' +
", source='" + source + '\'' +
", type='" + type + '\'' +
", time='" + time + '\'' +
'}';
}
}
2、Message消息类:
public class Message {
private String state;
private String msg;
private Object data;
private String time;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
3、getNewsServlet后端接口
import net.sf.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
@WebServlet(urlPatterns = "/getNewsServlet")
public class getNewsServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("UTF-8");
resp.setContentType("application/json;charset=UTF-8");
Message msg = new Message();
msg.setState("SUC");
msg.setTime("");
Connection connection = null;
List<News> newslist = new ArrayList<News>();
try {
String type = req.getParameter("typeSource");
System.out.println(type);
String dbhost = "localhost:3306";
String dbname = "newsdatabase";
String dbuser = "root";
String dbpassword = "123456";
String url = "jdbc:mysql://" + dbhost + "/" + dbname+ "?useSSL=false&useUnicode=true&characterEncoding=UTF-8";
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(url, dbuser, dbpassword);
Statement statement = connection.createStatement();
if(type !=null) {
if(type.equals("head")){
//在数据库中 ishead是 bool型 所以单独设置 在这里 1表示true
String sql = "select * from news where ishead = '" + 1 + "'";
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
News news = new News();
news.setId(rs.getInt("ID"));
news.setTitle(rs.getString("title"));
news.setTime(rs.getString("time"));
news.setPic(rs.getString("pic"));
news.setSource(rs.getString("source"));
news.setType(rs.getString("type"));
newslist.add(news);
}
msg.setMsg("号外");
}else{
String sql = "select * from news where type = '" + type + "'";
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
News news = new News();
news.setId(rs.getInt("ID"));
news.setTitle(rs.getString("title"));
news.setTime(rs.getString("time"));
news.setPic(rs.getString("pic"));
news.setSource(rs.getString("source"));
news.setType(rs.getString("type"));
newslist.add(news);
}
msg.setMsg(type);
}
msg.setData(newslist);
/* for(News newsItem : newslist){ //看有没有数据
System.out.println("数据库的新闻数据----->"+newsItem.toString());
}*/
}
else {
throw new Exception("Error");
}
}
catch (Exception e) {
msg.setState("ERR");
msg.setData(null);
msg.setMsg(e.getMessage());
}
finally {
//序列化JavaBean对象
JSONObject jsonObject = JSONObject.fromObject(msg);
String jstr = jsonObject.toString();
System.out.println("Json数据: ----->"+jstr);
PrintWriter out = resp.getWriter();
out.print(jstr);
try{
if(connection != null){
connection.close();
}
}catch (Exception e){
}
}
}
}
4、news.jsp新闻界面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>小吕的新闻</title>
</head>
<body>
<div class="zhuti">
<div class="icon">
<div class="img_icon">
<img src="images/icon.png" class="img_left">
</div>
<div class="search">
<input type="text">
</div>
<div class="img_icon1">
<label><img src="images/message.png" class="img_right">
</label>
</div>
<div class="img_icon2">
<label><img src="images/sub_more.png" class="img_right">
</label>
</div>
</div>
<div class="content_news">
<div class="navigator">
<input type="radio" id="nav_name1" name="nav_name" value= "head"
checked="checked"><label for="nav_name1">号外</label>
<input type="radio" id="nav_name2" name="nav_name" value="finance">
<label for="nav_name2">财经</label>
<input type="radio" id="nav_name3" name="nav_name" value="tech">
<label for="nav_name3">科技</label>
<input type="radio" id="nav_name4" name="nav_name" value="sports">
<label for="nav_name4">体育</label>
<input type="radio" id="nav_name5" name="nav_name" value="edu">
<label for="nav_name5">教育</label>
<input type="radio" id="nav_name6" name="nav_name" value="tour">
<label for="nav_name6">旅游</label>
<input type="radio" id="nav_name7" name="nav_name" value="game">
<label for="nav_name7">游戏</label>
<input type="radio" id="nav_name8" name="nav_name" value="Sichuan">
<label for="nav_name8">四川</label>
</div>
<div class="news" id="news">
</div>
</div>
<div class="icon">
<div class="img_icon">
<img src="images/main_config1.png" class="img_left">
</div>
<div class="img_icon3">
<label><img src="images/main_home1.png" class="img_btom">
</label>
</div>
</div>
</div>
</body>
<style>
body{
height: 100vh;
display: flex;
justify-content: center;
background-size: cover;
flex: 1;
}
.content_news{
height: 86%;
width: 100%;
}
.navigator{
width: 100%;
height: 5%;
/* background-color: pink; */
line-height: 30px;
border-bottom: 1px solid rgb(204, 208, 210);
border-left: 1px solid rgb(204, 208, 210);
border-right: 1px solid rgb(204, 208, 210);
}
.navigator input{
margin-left: 5%;
opacity: 0;
}
.news{
width: 100%;
height: 100%;
overflow-y: scroll;
}
/* 为选中的radio添加样式 */
input[type="radio"]:checked + label {
color: black;
font-weight: bold;
border-bottom: 2px solid black;
}
/* 为取消选中的radio添加样式 */
input[type="radio"]:not(:checked) + label {
color: black;
font-weight: normal;
}
.newsItem{
position: relative;
width: 98%;
height: 120px;
background-color: white;
margin-top: 5px;
margin-left: 1%;
border-radius: 10px;
border: 2px solid rgb(204, 208, 210);
box-shadow: 5px 2px 35px -7px #cdcdcd;
}
.newsItem_left{
position: absolute;
width: 70%;
height: 100%;
margin-left: 1%;
}
.news_title{
height: 60%;
width: 100%;
line-height: 40px;
font-size: 18px;
}
.publish{
position: relative;
width: 100%;
height: 40%;
font-size: 14px;
}
.reporter{
position: absolute;
height: 100%;
width: 70%;
line-height: 30px;
}
.reporter_time{
position: absolute;
height: 100%;
width: 30%;
margin-left: 70%;
line-height: 30px;
}
.newsItem_right{
position: absolute;
width: 25%;
height: 100%;
margin-left: 74%;
text-align: center;
}
.newsItem_right img{
margin-top: 1.5%;
width: 95%;
height: 95%;
}
.zhuti{
margin: 0 auto;
width: 900px;
height: 100%;
}
.icon{
position: fixed;
position: relative;
width: 100%;
height: 50px;
background-color: #e66c05;
text-align: center;
border: 1px solid #e66c05;
}
.img_icon{
position: absolute;
margin-left: 4%;
margin-top: 10px;
width: 4%;
height: 70%;
}
.img_icon1{
position: absolute;
margin-left: 88%;
width: 4%;
height: 70%;
}
.img_icon2{
position: absolute;
margin-left: 92%;
width: 4%;
height: 70%;
}
.img_icon3{
position: absolute;
margin-left: 92%;
margin-top: 10px;
width: 6%;
height: 70%;
}
.img_left{
width: 100%;
height: 100%;
}
.img_right{
width: 60%;
height: 60%;
margin-top: 13px;
}
.img_btom{
width: 80%;
height: 100%;
}
.search{
position: absolute;
margin-left: 11%;
margin-top: 10px;
width: 75%;
height: 30px;
border-radius: 5px;
background-color: aliceblue;
}
.search input{
height: 30px;
width: 100%;
border-color: white;
background-position: 2%;
background: url(images/search.png)no-repeat;
background-size: 20px;
border-radius: 5px;
}
</style>
</html>
<script src="jquery-3.1.1.min.js"></script>
<script>
$().ready(function (){
var type1 = $("input[name='nav_name']:checked").val();
news(type1);
$("input[name='nav_name']").click(function (){
var type = $("input[name='nav_name']:checked").val();
news(type);
});
});
function news(typeText){
$.ajax({
url:"getNewsServlet",
data:{typeSource:typeText},
type:"POST",
dataType: "JSON",
success:function (jData){
if(jData.state =="SUC"){
var newshtml = ""
for(var i in jData.data){
console.log(jData.data[i].title);
newshtml +=
"<div class=newsItem>"
+"<div class=newsItem_left>"
+"<div class=news_title>"+
jData.data[i].title
+"</div>"
+"<div class=publish>"
+"<div class=reporter>"+
jData.data[i].source
+"</div>"
+"<div class=reporter_time>"
+jData.data[i].time
+"</div>"
+"</div>"
+"</div>"
+"<div class=newsItem_right>"
+"<img src="+"news_images/"+jData.data[i].pic+">"
+"</div>"
+"</div>"
}
$("#news").html(newshtml);
}else{
alert(jData.msg);
}
}
});
}
</script>
五、运行结果: