项目一总结

项目一总结

day1

构建Maven 工程 

src/main/java

src/main/resources

src/test/java

src/test/resources

搭建三层项目环境

1.拷贝页面:src/main/webapp/web-inf/views

2.修改页面为jsp

3.希望访问webapp/web-inf/views/index.jsp 但是访问不了!因为web-inf 只有通过程序访问

4.写一个IndexController

后台管理页面统一存放在WEB-INF文件夹下的system文件夹中,而WEB-INF文件夹是安全目录,浏览器是不能直接访问到WEB-INF中的目录,只能通过服务器转发的方式访问到该目录,要从浏览器中访问到该目录,需要定义一个Controller用于转发

配置文件:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!-- 配置前缀 -->

<property name="prefix" value="/WEB-INF/system/"></property>

<!-- 配置后缀 -->

<property name="suffix" value=".jsp"></property>

</bean>

IndexController代码:

@Controller

@RequestMapping("/system")

public class IndexController {

@RequestMapping("/index")

public String system(){

return "index";

}

@RequestMapping("/main")

public String main(){

return "main";

}

}

全注解开发

@Controller 控制器

@Service 业务对象

@Repository 持久层对象

@Component  组件

day2

富文本编辑器

<div id="editor">

        <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p>

    </div>

    <!-- 注意, 只需要引用 JS,无需引用任何 CSS !!!-->

    <script type="text/javascript" src="/wangEditor.min.js"></script>

    <script type="text/javascript">

        var E = window.wangEditor

        var editor = new E('#editor')

        // 或者 var editor = new E( document.getElementById('editor') )

        editor.create()

    </script>

Ajax交互方式

优点:

异步请求,发送请求的同事还可以继续操作页面。页面不销毁;

返回部分数据,减少不必要的数据承传输,介绍网络资源。页面不刷新,而是更新页面部分数据;

同步和异步请求

同步:你先做完我再做,后一步的操作必须要等待前一步操作的结果

异步:各做各的相互不干扰(效率高)

1.AJAX对象本身是浏览器中的一个对象,但在低版本IE中表现为一个ActiveX。所以在使用JavaScript语言进行创建该对象时,需要区分不同的浏览器

2.有时候我们会把XMLHttpRequest对象称为AJAX对象,或异步对象

创建方式1:判断方式

function getXhr(){

var xhr = null;

if(window.XMLHttpRequest){//针对其他浏览器

xhr = new XMLHttpRequest();

}else{//针对低版本的ie浏览器

xhr = new ActiveXObject('Microsoft.XMLHTTP');

}

return xhr;

}

day3

分页

分页是我们开发中很常见的功能。试想一下,如果一张表有20万条数据,我们一次读取出来,对整个程序的性能是非常大的负担,而且也要影响到查询的速度。对用户来说,一下看到这么多数据估计也是醉了。

分页有两种:真分页与假分页。

这个只是我们对两种分页方式的取名而已,两种分页方式没有孰优孰劣。他们只是方式与特性不同,于是选择上有不同,咱们B/S结构的软件可能更多的会使用真分页来完成功能。

假分页(前端分页)

比如说现有数据库有300条数据。

它先把300要数据全部读取到我们的内存里面。

Select * from news;  -> List<Product>  300条

如果我每页30条,那么我们都从内存里面(List) 里面来读取

好处:翻页快,功能实现简单,只适合小数据量 且不会经常修改的数据

劣势:占用内存大

真分页(后端分页)

比如说现有数据库有300条数据。

如果我每页30条,那么每次到数据库里去读取当前的30条数据

select * from news LIMIT 0,3

select * from news LIMIT 3,3

select * from news LIMIT ?,3

好处:占用内存小

劣势:翻页慢

它查询数据是匀速的

2.2.代码实现

分页对象

public class PageList<T> {

//当前页

private Integer currentPage;

//总页数

private Integer totalPage;

//当前页面显示数据

private Integer pageSize;

//总数据数

private Integer totalData;

//首页

private Integer firstPage=1;

//上一页

private Integer prePage;

//下一页

private Integer nextPage;

//尾页

private Integer lastPage;

//显示的数据

private List<T> list;

……

public PageList(Integer currentPage, Integer pageSize, Integer totalData, List<T> list) {

this.currentPage = currentPage;

this.pageSize = pageSize;

this.totalData = totalData;

this.list = list;

//首页

this.firstPage=1;

//总页数

this.totalPage=this.totalData%this.pageSize==0?this.totalData/this.pageSize:this.totalData/this.pageSize+1;

//上一页

this.prePage=this.currentPage==1?1:this.currentPage-1;

//下一页

this.nextPage=this.currentPage==this.totalPage?this.totalPage:this.currentPage+1;

//尾页

this.lastPage=this.totalPage;

}

}

分页条件对象

public class SqlCondition {

private Integer currentPage=1;

private Integer pageSize=10;

…….

}

DAO代码

public PageList<Images> queryAll(SqlCondition sc) {

String countSql="select count(*) from images";

Integer count = jt.queryForObject(countSql, Integer.class);

String sql="select * from images";

List<Images> list = jt.query(sql, new BeanPropertyRowMapper(Images.class));

PageList<Images> pageList = new PageList<>(sc.getCurrentPage(), sc.getPageSize(), count, list);

System.out.println(pageList);

return pageList;

}

Controller代码

@RequestMapping("/query")

public String query(SqlCondition sc,Model m){

PageList<Images> queryAll = service.queryAll(sc);

m.addAttribute("pageList",queryAll);

return "main";

}

前端页面-数据展示

<c:forEach items="${requestScope.pageList.list }" var="img">

<tr>

<th>#${img.imgid }</th>

<th>${img.storepath }</th>

<th>${img.intro }</th>

<th>

<c:choose>

<c:when test="${img.isenabled }">

<span class="glyphicon glyphicon-ok" aria-hidden="true" />

</c:when>

<c:otherwise>

<span class="glyphicon glyphicon-remove" aria-hidden="true"/>

</c:otherwise>

</c:choose>

</th>

<th>${img.inputdate }</th>

<th><a href="main_edit.html" class="btn-default tableA"><span

class="glyphicon glyphicon-pencil" aria-hidden="true">修改</span></a> <a

href="" class="btn-default tableA"><span

class="glyphicon glyphicon-trash" aria-hidden="true">删除</span></a>

</th>

</tr>

</c:forEach>

前端页面-分页

<ul class="pagination" id="paging">

<li><span>当前第${requestScope.pageList.currentPage }页</span></li>

<li><a href="${pageContext.request.contextPath }/img/query?currentPage=${requestScope.pageList.currentPage }"> <span aria-hidden="true">首页</span></a></li>

<li><a href="${pageContext.request.contextPath }/img/query?currentPage=${requestScope.pageList.prePage }" aria-label="上一页"> <span aria-hidden="true">上一页</span></a></li>

<li></li>

<li><a href="${pageContext.request.contextPath }/img/query?currentPage=${requestScope.pageList.nextPage }" aria-label="下一页"> <span aria-hidden="true">下一页</span></a></li>

<li><a href="${pageContext.request.contextPath }/img/query?currentPage=${requestScope.pageList.lastPage }" aria-label="尾页"> <span aria-hidden="true">尾页</span></a></li>

<li><span>总页数:共${requestScope.pageList.totalPage }页</span> <span>总数据:共${requestScope.pageList.totalData }条</span></li>

</ul>

3.CMS首页数据【高级查询】

一张表中有10000多个客户,我们是让用户从10000多个人中去找,还是根据一些条件(如名称,性别等)过一次过滤查询就找到。

其实完成高级查询,就是拼接Sql(根据不同的条件拼接Sql来实现不同的查询)

高级查询就是拼接Sql.

高级查询就是在查询基础上添加后面的where条件

2 根据不同的情况,where后面的条件都不同的

3 提供的过滤条件越多,我们查询的排列组合也就越多

综上可以看到,我们需要提供相应的查询字段,但是会不会用到,就看客户自己。但是由于这咱排列组合,我们不可能把所有的Sql全部准备好。

因此,咱们必需要能生成动态SQL(说白了就是根据条件来拼接字符串)

怎么拼接呢?用户选择了,这个字段就不为空,当这个字段不为空的时候,我们就在where后的查询加上这个条件过滤

day4 页面静态化

MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。 它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑, 在没有程序员来修改或重新编译代码时,也可以修改页面的样式。

而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中

完成静态化的步骤:

  1.导入jar包

* 2.创建一个配置对象 1.传递一个版本

3.设置模板加载路径

4设置一个模板编码

5.获取一个模板对象

6获取一个数据

7生成文件

day5

轮播管理

2.1.文件上传

1.前端页面设置

<form action="${pageContext.request.contextPath }/img/add" enctype="multipart/form-data" method="post">

<div class="form-group">

<label for="fileImg">轮播图上传</label> <input type="file" name="fileImg">

</div>

<div class="form-group">

<label for="isenabled">是否启用:</label> <label class="radio-inline">

<input type="radio" name="isenabled" id="isenabled" value="true"

checked="checked">是

</label> <label class="radio-inline"> <input type="radio"

name="isenabled" id="isenabled" value="false">否

</label>

</div>

<div class="form-group">

<label for="intro">轮播图简述</label>

<div id="intro"></div>

<input type="hidden" id="txtIntro" name="intro" />

</div>

<div class="btn-toolbar" data-role="editor-toolbar"

data-target="#editor">

<a class="btn btn-large" data-edit="bold"><i class="icon-bold"></i></a>

</div>

<div class="modal-footer">

<button type="submit" class="btn btn-primary">新增轮播</button>

</div>

</form>

上传文件使用的前端页面,必须按照如下标准:

post提交数据

enctype属性被修改为:multipart/form-data

使用上传文件的file标签

2.配置文件上传

<bean id="multipartResolver"

class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="maxUploadSize">

<value>100000</value>

</property>

<property name="defaultEncoding">

<value>UTF-8</value>

</property>

</bean>

3.代码实现

@RequestMapping(value="/add",method=RequestMethod.POST)

public void add(Images img,HttpServletRequest req) throws Exception{

/**

* 需求:新增上传文件数据,新增成功跳转查询

*/

//获取到上传的文件数据

MultipartFile fileImg = img.getFileImg();

ServletContext context = req.getServletContext();

//获取原始文件名

String oldName = fileImg.getOriginalFilename();

System.out.println(oldName);

System.out.println(context.getMimeType(oldName));

//判断上传文件是否为图片

if (!context.getMimeType(oldName).startsWith("image/")) {

return;

}

//获取存储路径

String realPath = context.getRealPath("/upload");

//创建新名字

String newName=UUID.randomUUID().toString()+"."+FilenameUtils.getExtension(oldName);

fileImg.transferTo(new File(realPath,newName));

//存储数据

img.setStorepath(realPath);

img.setStorename(newName);

service.addImg(img);

}

Images类

private Integer imgid;

private String storepath;

private String storename;

private String intro;

private Boolean isenabled;

private Date inputdate=new Date();

private MultipartFile fileImg;

API

MultipartFile :接收文件数据,命名必须和file标签name属性一致

getOriginalFilename:获取上传的文件名

transferTo:存储文件

2.2.文件下载

前端页面

<a href="${pageContext.request.contextPath }/download?filename=小师妹.jpg">文件下载</a>

代码实现

@RequestMapping(value = "/download", method = RequestMethod.GET)

public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename)

throws IOException {

String realPath = request.getServletContext().getRealPath("/upload");

File file = new File(realPath,filename);// 新建一个文件

//设置头信息

HttpHeaders headers = new HttpHeaders();

//设置响应的文件名

String downloadFileName = new String(filename.getBytes("UTF-8"), "iso-8859-1");

headers.setContentDispositionFormData("attachment", downloadFileName);

headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

// MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息

return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);

}

7.Ajax检查用户名是否重复

<form>

<input type="text" id="txtUserName" name="txtUserName"><span id="spanInfo">...</span></input>

<input type="button" id="btnCheck" onclick="checkUserName();" value="检查用户名是否存在"></input>

</form>

7.2.js

function checkUserName(){

var xhr;

// 1 创建ajax对象

xhr = getAjax();

// 2 open

var userName = document.getElementById("txtUserName").value;

xhr.open("GET","/ajax1/isExsit?username=" + userName);

// 监听

xhr.onreadystatechange = function(){

if(xhr.readyState == 4 && xhr.status == 200){

var info = document.getElementById("spanInfo");

if(xhr.responseText == "true")

info.innerHTML="用户名已存在";

else

info.innerHTML="可以用此用户名";

}

}

// 3 send

xhr.send();

}

7.3.Servlet

@SuppressWarnings("serial")

@WebServlet("/isExsit")

public class UserNameCheckServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// 获取参数

req.setCharacterEncoding("UTF-8");

resp.setContentType("text/html;charset=UTF-8");

String userName = req.getParameter("username");

System.out.println(userName);

// 检查用户名是否存在

if("你好".equals(userName)){

resp.getWriter().print(true);

System.out.println("true");

} else {

resp.getWriter().print(false);

System.out.println("false");

}

}

}

8.Ajax post登录

Get 请求中文乱码:配置tomcat:URIEncoding="UTF-8"就可以解决

Post请求中文乱码:req.setCharacterEncoding("utf-8");

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 一. Java基础部分.................................................
    wy_sure阅读 3,811评论 0 11
  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵胜奥阅读 4,820评论 0 1
  • JAVA面试题 1、作用域public,private,protected,以及不写时的区别答:区别如下:作用域 ...
    JA尐白阅读 1,154评论 1 0
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,592评论 1 114
  • 在开发过程中,我们经常会从数据库中查询数据,然后在客户端显示出来。当数据少时,可以在一个页面显示。当我们查询几百条...
    S等价交换S阅读 2,192评论 0 0