本系列文章旨在记录和总结自己在Java Web开发之路上的知识点、经验、问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人。
上篇文章介绍了JSP的核心原理,本篇文章准备介绍JSP的初步使用。
大家一定要自己动手编写代码,运行验证,只有这样才能理解的更加透彻,印象也更加深刻。不知道大家有没有这样一种体会,就是明明自己看了不少技术相关的书籍,但是每到用的时候就忘记了相关技术如何使用,还是需要不断的上网搜索。
这还是说明我们动手实践比较少。在我看来,任何一门科学、技术、学问、专业都离不开以下四个环节:
任何一门科学、技术、学问、专业都不是一日之功,需要长期的坚持这四个环节,所以必须从小就灌输,养成学、做、思、记的习惯。这四个环节是互相影响、互相交叉、互相促进、需要同时进行,不可偏废的。正所谓“纸上得来终觉浅,绝知此事要躬行”、“学而不思则罔,思而不学则殆”、“好记性不如烂笔头”等等。
虽说这四个环节不可偏废,但各门科学、技术、学问、专业还是有所侧重的,比如科学这个词感觉就偏理论学习和思考多一些,动手实践少一些;而技术这个词就相反。再比如工科偏动手实践多一些,理科偏理论研究多一些等等。
不好意思,又跑题。说那么多无非就是想说我们需要多敲敲代码。软件/编程这一行业被划分到工科,那就说明我们更要多动手实践。话说这应该是实践成本最低的工科行业了,只要一台个人电脑即可,还有各种开源的软件可用,要是建筑、土木、工业制造、各种勘探、化工、电力等等,要么需要去实地、要么需要建个实验室、要么需要买个机床。。。。。。
好了,不说废话了。我们仍然以前面开发的租房网应用(可以参考这篇文章和这篇文章)为基础,使用JSP技术来改造,至少需要达到的一个目标是让代码看起来更加清爽。
工程结构:
静态资源 - 登录页面login.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>租房网 - 登录</title> </head> <body> <form action="login.servlet" method="post"> <label for="user_name">用户名:</label><input type="text" id="user_name" name="userName" /> <label for="password">密码:</label><input type="password" id="password" name="password" /> <input type="submit" value="登录" /> </form> </body> </html>
房源实体类 - House.java:
package houserenter.entity; public class House { private String id; private String name; private String detail; public House(String id, String name, String detail) { super(); this.id=id; this.name=name; this.detail=detail; } public String getId() { return id; } public void setId(String id) { this.id=id; } public String getName() { return name; } public void setName(String name) { this.name=name; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail=detail; } @Override public String toString() { return "House [id=" + id + ", name=" + name + ", detail=" + detail + "]"; } }
处理登录请求的Servlet - LoginServlet.java:
package houserenter.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/login.servlet") public class LoginServlet extends HttpServlet { private static final long serialVersionUID=1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName=request.getParameter("userName"); String password=request.getParameter("password"); //这里需要验证用户是否已经注册,省略 System.out.println("userName: " + userName + ", password: " + password); //用户登录成功,重定向到房源列表页面 response.sendRedirect("house.html?userName=" + userName); } }
处理房源相关请求(房源查找、房源详情、房源编辑)的Servlet - HouseServlet.java:
package houserenter.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; 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 houserenter.entity.House; @WebServlet("/house.html") public class HouseServlet extends HttpServlet { private static final long serialVersionUID=1L; private List<House> mockHouses; @Override public void init() { mockHouses=new ArrayList<House>(); mockHouses.add(new House("1", "金科嘉苑3-2-1201", "详细信息")); mockHouses.add(new House("2", "万科橙9-1-501", "详细信息")); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName=request.getParameter("userName"); PrintWriter writer=response.getWriter(); writer.println("<!DOCTYPE html>"); writer.println("<html>"); writer.println("<head>"); writer.println("<meta charset=\"UTF-8\">"); writer.println("<title>租房网</title>"); writer.println("</head>"); writer.println("<body>"); writer.println("<h1>你好,"+userName+"!欢迎来到租房网! <a href=\"login.html\">退出</a></h1>"); writer.println("<br><br>"); String houseId=request.getParameter("houseId"); String editHouse=request.getParameter("editHouse"); if (houseId==null || houseId.isEmpty()) { //查找该用户感兴趣的房源,这里省略 System.out.println("userName: " + userName + " access house.html!"); writer.println("<h6>共找到你感兴趣的房源 "+mockHouses.size()+" 条</h6>"); writer.println("<ul>"); for (House house : mockHouses) { writer.println("<li><h2><a href=\"house.html?userName="+userName+"&houseId="+house.getId()+"\">"+house.getName()+"</a></h2></li>"); } writer.println("</ul>"); } else if (editHouse==null) { //根据houseId查找该房源的详细信息 System.out.println("userName: " + userName + " access house.html for house detail!"); House target=null; for (House house : mockHouses) { if (houseId.equals(house.getId())) { target=house; break; } } writer.println("<h2>"+target.getName()+"<a href=\"house.html?userName="+userName+"&houseId="+houseId+"&editHouse=true\">编辑</a></h2>"); writer.println("<h3>"+target.getDetail()+"</h3>"); writer.println("<h4><a href=\"house.html?userName="+userName+"\">回到列表</a></h4>"); } else { //存在editHouse参数,返回指定房源的编辑页面 System.out.println("userName: " + userName + " access house.html to edit house!"); House target=null; for (House house : mockHouses) { if (houseId.equals(house.getId())) { target=house; break; } } //writer.println("<form action=\"house.html?userName="+userName+"&houseId="+houseId+"\" method=\"post\">"); writer.println("<form action=\"house.html\" method=\"post\">"); writer.println("<input type=\"hidden\" name=\"userName\" value=\""+userName+"\"/>"); writer.println("<input type=\"hidden\" name=\"houseId\" value=\""+houseId+"\"/>"); writer.println("<label for=\"house_name\">房源名字:</label><input type=\"text\" id=\"house_name\" name=\"houseName\" value=\""+target.getName()+"\" />"); writer.println("<label for=\"house_detail\">房源详细信息:</label><input type=\"text\" id=\"house_detail\" name=\"houseDetail\" value=\""+target.getDetail()+"\" />"); writer.println("<input type=\"submit\" value=\"提交\" />"); writer.println("</form>"); } writer.println("</body>"); writer.println("</html>"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName=request.getParameter("userName"); String houseId=request.getParameter("houseId"); //获取提交的房源信息,并保存 System.out.println("userName: " + userName + " access house.html to save house detail!"); String houseName=request.getParameter("houseName"); String houseDetail=request.getParameter("houseDetail"); for (House house : mockHouses) { if (houseId.equals(house.getId())) { house.setName(houseName); house.setDetail(houseDetail); break; } } response.sendRedirect("house.html?userName="+userName+"&houseId="+houseId); } }
设置请求响应编码、登录验证的Filter - MyFirstFilter.java:
package houserenter.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter("/house.html") public class MyFirstFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); HttpServletRequest httpServletRequest=(HttpServletRequest) request; HttpServletResponse httpServletResponse=(HttpServletResponse) response; String userName=httpServletRequest.getParameter("userName"); if (userName==null || userName.isEmpty()) { System.out.println("invalid user!"); httpServletResponse.sendRedirect("login.html"); } else { chain.doFilter(request, response); } } }
登录页面和LoginServlet目前还算简单,暂时可以不用改造。
HouseServlet的代码量稍微有点多(也不过一百多行),且夹杂着输出HTML内容,看着比较乱。从功能上来说虽然都与房源有关,但实际上动态生成的呈现给浏览器的是三个页面(房源列表、房源详情、房源编辑),所以可以考虑用三个JSP页面代替,咱就命名为:
另外,因为涉及到一个房源编辑的表单,所以需要一个Servlet来处理表单的提交,就叫HouseFormServlet吧。
还有一个要提的是HouseServlet初始化了一些模拟数据,那这部分应该放在哪呢?因为一个JSP页面就相当于一个Servlet,所以原来的HouseServlet现在要改造成三个JSP页面,感觉模拟数据放在哪个JSP页面都不太合适,因为三个JSP页面都要访问同一份模拟数据才行。
于是问题变为:如何在多个JSP页面之间共享访问同一份数据?我先想到的是能不能在一个Filter中初始化模拟数据,然后让它拦截到这三个JSP页面的请求,然后在请求中使用setAttribute()方法将模拟数据挂上去,最后在JSP页面中使用请求的getAttribute()方法取出来。
好了,既然思路有了,那我们就大刀阔斧的干吧。
不过我们可以把之前的代码都保留着,另外编写新添加的JSP页面和Filter即可,当然也可以把之前的都删掉。
这次我们先编写我们的Filter。
在Filter中初始化模拟数据跟之前在HouseServlet中是类似的。Filter也有一个相同的生命周期方法init()(另一个相同的是destroy()方法),大家可以直接看看Filter的源码(如何查看源码可以参考这篇文章)。
不过Filter的这个init()方法是Servlet容器初始化Filter的时候就调用,与Servlet的init()方法在第一个请求到来时才调用是不同的。
Filter的doFilter()方法还是可以跟之前的Filter一样设置请求响应的编码以及进行登录验证,但最主要的是调用请求的setAttribute()方法把模拟数据挂载到该请求中。
在Eclipse中创建Filter还是可以使用New工具(可以参考这篇文章中的新建Java类部分),大家应该很容易知道该怎么填写相关信息,比如Filter的类名、初始化参数、映射(即拦截何种请求)。当然,你也可以新建空白的文件手动敲写所有代码。
package houserenter.filter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import houserenter.entity.House; @WebFilter( urlPatterns={ "/houses.jsp", "/house-details.jsp", "/house-form.jsp", "house-form.servlet" }) public class MySecondFilter implements Filter { private List<House> mockHouses; @Override public void init(FilterConfig filterConfig) { System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); mockHouses=new ArrayList<House>(); mockHouses.add(new House("1", "金科嘉苑3-2-1201", "详细信息")); mockHouses.add(new House("2", "万科橙9-1-501", "详细信息")); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("BBBBBBBBBBBBBBBBBBBBBBBBBBBB"); request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); HttpServletRequest httpServletRequest=(HttpServletRequest) request; HttpServletResponse httpServletResponse=(HttpServletResponse) response; Object obj=httpServletRequest.getAttribute("mockHouses"); if (obj==null) { httpServletRequest.setAttribute("mockHouses", mockHouses); } String userName=httpServletRequest.getParameter("userName"); if (userName==null || userName.isEmpty()) { System.out.println("invalid user!"); httpServletResponse.sendRedirect("login.html"); } else { chain.doFilter(request, response); } } }
上面的代码是我用New工具生成之后,把无用的注释、成员方法删掉之后,再加上初始化模拟数据的逻辑、doFilter的逻辑。
因为Filter接口的init()方法和destroy()方法是default的(JDK8才支持),因此可以不必实现。
注意,此Filter拦截的有哪些资源的访问请求!
doFilter的逻辑跟之前的相比,多了一个把mockHouses挂载到请求上去的部分。经过测试,不用强制转换成HttpServletRequest也是可以的。
对了,我在init()方法和doFilter()方法中都加了打印日志的部分,便于调试。
现在开始编写我们的JSP页面,第一个是房源列表。
编写房源列表页面,实际上就是编写Servlet,只不过它们的HTML和Java内容是反着来的。所以你可以参照原来的HouseServlet中是怎样输出HTML的,你就可以把它们拷贝过来,然后把writer.println("")这种去掉,把HTML标签拿出来,而需要Java代码的地方就用JSP语法中的<%和%>括起来即可。
即编写JSP页面时,你就可以想象着这是在编写Servlet的service()方法(除去JSP的声明,即<%!和%>括起来的,和page指令中的import部分以外),只不过HTML内容直接写,而Java代码需要<%(或<%=)和%>括起来。
但实际上,我们仍然可以使用New工具,从而生成通用的JSP模板页面(工具中可以选择是HTML 5、HTML 4.01、XHTML等等,我选的是HTML5)。
我们把这几个JSP页面都直接放在WebContent节点下,这样跟MySecondFilter的映射配置是一致的。
这里有一个小诀窍,就是写一部分代码验证一部分代码,不必整个页面编写完毕才验证,当然我们这几个页面都比较简单,也可以全部编写完毕再验证。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.List" %> <%@ page import="houserenter.entity.House" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>租房网</title> </head> <body> <h1>你好,${param.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1> <br><br> <% List<House> mockHouses=(List<House>) request.getAttribute("mockHouses"); System.out.println(mockHouses); %> <h6>共找到你感兴趣的房源 <%=mockHouses.size() %> 条</h6> <ul> <%for (House house : mockHouses) { System.out.println(house); %> <li><h2><a href="house-details.jsp?userName=${param.userName}&houseId=<%=house.getId() %>"><%=house.getName() %></a></h2></li> <%} %> </ul> </body> </html>
需要提一下:
我们可以一边开发JSP页面一边进行验证了,Eclispe中启动Tomcat之后也不用关闭,它会自动检测JSP页面和Java代码的变化,进行重新编译和发布,不过有时候修改代码后还是重新发布应用比较踏实。
先别忘了修改我们的LoginServlet重定向的地址:
response.sendRedirect("houses.jsp?userName=" + userName);
OK,从浏览器中访问租房网的登录页面login.html:
随便输入用户名和密码,点击登录:
耶,完全没有问题!继续编写其他两个JSP页面。
有了前面的分析,相信大家都能够理解一般的JSP代码了,那就直接上代码吧。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.List" %> <%@ page import="houserenter.entity.House" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>租房网</title> </head> <body> <h1>你好,${param.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1> <br><br> <% List<House> mockHouses=(List<House>) request.getAttribute("mockHouses"); String houseId=request.getParameter("houseId"); House target=null; for (House house : mockHouses) { if (houseId.equals(house.getId())) { target=house; break; } } %> <h2><%=target.getName() %><a href="house-form.jsp?userName=${param.userName }&houseId=<%=target.getId() %>">编辑</a></h2> <h3><%=target.getDetail() %></h3> <h4><a href="houses.jsp?userName=${param.userName }">回到列表</a></h4> </body> </html>
还是主要用了JSP脚本、JSP表达式和EL表达式三个技术。
不过,JSP脚本看着似乎有点长。
还是直接上代码。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.List" %> <%@ page import="houserenter.entity.House" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>租房网</title> </head> <body> <h1>你好,${param.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1> <br><br> <% List<House> mockHouses=(List<House>) request.getAttribute("mockHouses"); String houseId=request.getParameter("houseId"); House target=null; for (House house : mockHouses) { if (houseId.equals(house.getId())) { target=house; break; } } %> <form action="house-form.servlet" method="post"> <input type="hidden" name="userName" value="${param.userName}"/> <input type="hidden" name="houseId" value="<%=target.getId() %>"/> <label for="house_name">房源名字:</label><input type="text" id="house_name" name="houseName" value="<%=target.getName() %>" /> <label for="house_detail">房源详细信息:</label><input type="text" id="house_detail" name="houseDetail" value="<%=target.getDetail() %>" /> <input type="submit" value="提交" /> </form> </body> </html>
注意,此时表单的提交路径是:house-form.servlet
所以,后面编写HouseFormServlet时,配置其URL映射模式要与此一致。
无非就是提取表单提交的数据,然后保存到我们的模拟数据中,最后重定向回该房源的详情页面。
package houserenter.servlet; import java.io.IOException; import java.util.List; 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 houserenter.entity.House; @WebServlet("/house-form.servlet") public class HouseFormServlet extends HttpServlet { private static final long serialVersionUID=1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<House> mockHouses=(List<House>) request.getAttribute("mockHouses"); String houseId=request.getParameter("houseId"); House target=null; for (House house : mockHouses) { if (houseId.equals(house.getId())) { target=house; break; } } String houseName=request.getParameter("houseName"); target.setName(houseName); String houseDetail=request.getParameter("houseDetail"); target.setDetail(houseDetail); String userName=request.getParameter("userName"); response.sendRedirect("house-details.jsp?userName=" + userName + "&houseId=" + houseId); } }
至此,全部JSP页面和Servlet代码已经编写完毕,大家可以自行验证,应该没有问题。
虽然已经完成了全部工作,运行也没有问题,但是很明显,三个JSP页面中开头的很大一部分都是重复的,这时候JSP中的include指令就排上用场了。
我们把这部分重复的提取出来,形成一个独立的JSP文件:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.List" %> <%@ page import="houserenter.entity.House" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>租房网</title> </head> <body> <h1>你好,${param.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1> <br><br>
然后改造三个JSP页面,比如房源列表页面houses.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="include.jsp"%> <% List<House> mockHouses=(List<House>) request.getAttribute("mockHouses"); System.out.println(mockHouses); %> <h6>共找到你感兴趣的房源 <%=mockHouses.size() %> 条</h6> <ul> <%for (House house : mockHouses) { System.out.println(house); %> <li><h2><a href="house-details.jsp?userName=${param.userName}&houseId=<%=house.getId() %>"><%=house.getName() %></a></h2></li> <%} %> </ul> </body> </html>
直接使用include指令:
<%@ include file="include.jsp"%>
但是,要注意,房源列表页面houses.jsp中仍然需要下面的page指令,否则会有中文乱码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
实际上,include指令也是由Servlet容器在将JSP页面生成Servlet代码的过程中解析,并用包含的JSP页面的内容替换该指令,完全是解析阶段发生的故事。
最后,我们的租房网的工程结构变成:
虽然我们的租房网还不够完美,但总算比之前纯粹使用Servlet的时候干净清爽多了,页面结构也比较清晰合理。
当然,还有很多需要改进的地方,读者朋友们自己可以思考思考。
上系统全面的HTML+CSS课程上线了
0基础精讲,简单易学,前端开发入门首选课程
【推荐理由】
HTML+CSS是学习HTML5的基础课程,是前端开发的必备技术,无论是PHP、JSP等网站编程语言,都要用到HTML。
HTML+CSS让建站更简单,内容分离布局更灵活,便于维护和修改,尤其是大型网站的制作特别明显。
HTML+CSS支持各种浏览器,兼容性好,符合web标准规范的发展趋势,可以使用在广泛的平台上。
HTML+CSS有利于网站的优化,可以被更好的搜索和收录。
【课程简介】
郑州HTML5培训本课程从最基础的前端认知,工具和插件安装等开始教起,通俗易懂,步骤详细,上手简单,实用性强,非常适合0基础的人群学习。
【课程特色】
金牌师资:蓝鸥Html5资深讲师
丰富案例:运用实际的项目讲述知识点
深入浅出:面向零基础,而又不失去课程的严禁和拓展,保证人人可以学会,可以提升自己一个新的高度。
【讲师介绍】
蓝鸥HTML5特级讲师
IT教育行业从业经验12年,资深前端开发工程师,为人热情豪迈,热爱教育行业,担任全国多所大学的客座讲师。
【我们承诺】
1.录制最新课程内容,紧跟HTML+CSS技术发展实时更新知识点;打造全真课堂环境,模拟PPT教学场景与老师手写电子板书效果。
2.难点重点集中讲解,结合相关案例具体分析,促进对知识点的透彻理解及项目的实战操作。
课程目标
了解前端开发职位;
掌握HTML常用标签以及语义及用法,包括html模板、标签、表格、表单等等;
掌握常用CSS的基础知识及布局技巧,能熟练手写CSS进行网页布局;
掌握整站规划基础。
郑州HTML5培训http://www.lanou3g.com/
用JSP文件上传,下载的一些方法,Java实现文件分片上传、大文件秒传,大文件如何做断点续传?JAVAWEB 文件上传及下载,JAVA大文件上传,大文件下载解决方案,JAVA实现文件分片上传并且断点续传,JAVA大文件分片上传/多线程上传功能,超大文件上传和断点续传的控件,JAVA实现浏览器端大文件分片上传,JAVA实现大文件上传,JAVA WEB 实现文件上传和下载接口功能,
百度webuploader上传文件到服务器指定文件夹问题,webuploader上传文件到服务器指定文件夹问题,JSP上传文件到服务器指定文件夹问题,JAVA上传大文件实现源代码,JAVA上传大文件实现源码,JAVA上传大文件实现代码,JAVA上传大文件实现技巧,JAVA上传大文件实现技术,JAVA上传大文件实现思路,JAVA上传大文件实现解决方案,
前端上传大文件实现方案,js上传大文件实现方法,JavaScript上传大文件实现方法,vue上传大文件实现方法,前端上传大文件实现方法,html上传大文件实现方法,html5上传大文件实现方法,百度webuploader上传大文件实现方法,webuploader上传大文件实现方法,JAVA上传大文件实现方法,
网上也搜过相关的解决方案,论坛里面也有网友交流,但是都不太令人满意,与实际的需求需求也相差太远。可以说是完全不能满足公司这边的项目需求。公司项目这块实际上是需要一个成熟的商业解决方案。
大文件上传的话基本上都是分片来传,网上很多文章讲的不能说乱七八糟只能说完全没用。
JAVA的话主要是负责后端的接口,业务逻辑,功能的实现,比如文件初始化,文件分块,文件块合并,文件信息的查询等。
客户这个项目跟了很长时间了,大概有2年了。实际上客户并不在意使用哪种技术,只在乎两点。
文件比较大,有50G左右,用户希望能够在网页里面直接上传,一期的时候我们是直接用的HTML5的API,也就是chrome提供的API来做的,但是上线后用户反馈不是特别的好用,用户那边有些电脑用的是WIN7+IE9,chrome的API在ie9里面不支持。但是用户系统是支持的,这就把人整的有点不会了。二期的时候我们还是定制开发了,
前端用了JSP,VUE2,VUE3,后端用了JSP,SpringBoot,IDE用了Eclipse,MyEclipse,因为新项目和老项目都用了两种IDE。
用户要求能够在网页上面上传文件夹,文件夹里面大约有1万多个文件,有大有小,大的有1G~10G,小的有几MB,文件夹上传的时候需要保存层级结构,同时能够将层级结构信息保存到数据库中,同时还需要支持文件夹下载,下载下来的文件夹要和上传的文件夹层级结构一模一样。客户每天都会传输一些资料,功能这块使用频率非常高。
要求支持断点续传,支持进度信息离线存储,用户可能传一半没有传完,下班了,明天上班后继续上传,电脑晚上到点需要关机,支持加密传输,支持国密加密算法SM4,要求支持下载,支持非打包方式下载,浏览器要求支持包含IE在内的所有浏览器,
系统环境要求支持信创国产化,比如银河麒麟,中标麒麟,统信UOS,龙芯,数据库支持MySQL,Oracle,达梦数据库,人大金仓,需要提供前端源码,后端源码,控件源码,公司自己的项目,也有自己的产品,后续需要集成使用,
要求提供7*24小时技术支持服务,提供文档教程,视频教程,远程技术指导,1对1技术支持服务,提供手机,微信,QQ,邮箱,企业微信等联系方式。导入项目:
导入到Eclipse:http://www.ncmem.com/doc/view.aspx?id=9da9c7c2b91b40b7b09768eeb282e647
导入到IDEA:http://www.ncmem.com/doc/view.aspx?id=9fee385dfc0742448b56679420f22162
springboot统一配置:http://www.ncmem.com/doc/view.aspx?id=7768eec9284b48e3abe08f032f554ea2
下载示例:
https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/
工程
NOSQL
NOSQL示例不需要任何配置,可以直接访问测试
创建数据表
选择对应的数据表脚本,这里以SQL为例
修改数据库连接信息
访问页面进行测试
文件存储路径
up6/upload/年/月/日/guid/filename
相关问题:
1.javax.servlet.http.HttpServlet错误
2.项目无法发布到tomcat
3.md5计算完毕后卡住
4.服务器找不到config.json文件
相关参考:
文件保存位置
源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra
源码报价单:https://drive.weixin.qq.com/s?k=ACoAYgezAAwoiul8gl
OEM版报价单:https://drive.weixin.qq.com/s?k=ACoAYgezAAwuzp4W0a
控件源码下载:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc
*请认真填写需求信息,我们会在24小时内与您取得联系。