如上图示把稳选择TOMCAT版本
如上图示勾选天生web.xml,当然如果不勾选也行,但后续如果有须要用到配置的地方就须要再单独添加,故这里我选择一并天生。
末了点击finish按钮即可天生WEB项目
WEB项目的构造如下图示,每个部份都有解释,该图引用自网络
如上步骤也可参考更详细的教程:http://www.runoob.com/jsp/eclipse-jsp.html
二、编写一个登录静态页面(login.html),把稳静态页面(html)、动态页面(jsp)均应在WebContent目录下创建
后面采纳默认即可,末了创建好空的login.html,然后写如下示例代码:
<!DOCTYPE html><html><head><meta charset=\"大众UTF-8\公众><title>login</title></head><body> <form action=\公众/demo2/servlet/login\"大众 method=\"大众post\"大众> <div> <label for=\公众userid\公众>UserID:</label> <input type=\"大众text\"大众 name=\"大众uid\公众 /> </div> <div> <label for=\"大众pwd\"大众>Password:</label> <input type=\"大众password\"大众 name=\"大众pwd\"大众 /> </div> <div> <button type=\公众submit\"大众>Enter</button> </div> </form></body></html>
三、编写做事端处理逻辑类(LoginServlet),该类必需继续自HttpServlet,并按需重写干系的要求方法,例如此处是:doGet(处理GET要求)、doPost(处理POST要求)
自定义的Servlet类统一放在src目录下,按照JAVA 标准以包、类层级呈现
如上图示,包名一样平常是域名的反写,大家可能看到下面还有一个创建package-info.java的勾选项,详细用法可参考:PACKAGE-INFO.JAVA 浸染及用法详解
创建好LoginServlet类后,编写如下代码:(紧张是doPost,用于处理登录要求)
package cn.zuowenjun.java; 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;import javax.servlet.http.HttpSession; / Servlet implementation class LoginServlet /@WebServlet(name=\"大众LoginServlet\"大众,urlPatterns= {\"大众/servlet/login\"大众})public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; / @see HttpServlet#HttpServlet() / public LoginServlet() { super(); // TODO Auto-generated constructor stub } / @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) / protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append(\公众Served at: \公众).append(request.getContextPath()); } / @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) / protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String uid = request.getParameter(\公众uid\"大众); String pwd = request.getParameter(\公众pwd\"大众); if (uid.isEmpty() || pwd.isEmpty()) { response.getWriter().append(\公众the UserID and Passwrod cannot be empty!\"大众); return; } if(uid.equals(\"大众admin\公众) && pwd.equals(\公众java.web\"大众)) { HttpSession session= request.getSession(); session.setAttribute(\"大众loginid\公众, uid); String indexUrl= request.getContextPath()+\"大众/jsp/index.jsp\"大众; response.sendRedirect(indexUrl); return; } else { response.getWriter().append(\公众the UserID or Passwrod is wrong!\公众); } } }
servlet支配(映射)有两种办法,一种是在web.xml中利用如下配置:
<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>cn.zuowenjun.java.LoginServlet</servlet-class></servlet><servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/servlet/login</url-pattern></servlet-mapping>
另一种办法是利用表明,在servlet类名上方利用@WebServlet表明,在里面设置参数,如下:
@WebServlet(name=\"大众LoginServlet\"大众,urlPatterns= {\"大众/servlet/login\"大众})public class LoginServlet extends HttpServlet { ... ...}
这样登录页面的前后端交互写完了,如果登录成功则跳转至index.jsp页面,否则直接输出错误信息,下面就写index.jsp(动态页面):
四、编写index.jsp(动态页面),我这里将所有jsp页面统一放在jsp目录中,以区分静态页面与动态页面,创建jsp页面的方法与创建静态页面方法基本相同,只是创建类型选择jsp File即可,在此不再重复先容。
创建好空的index.jsp页面后,编写从SQL SERVER DB中获取表数据并显示在页面上的逻辑(即:查询数据),代码如下:
<%@ page language=\"大众java\"大众 contentType=\"大众text/html; charset=utf-8\"大众 pageEncoding=\公众utf-8\公众%><%@page import=\"大众java.sql.Connection\公众%><%@page import=\"大众java.sql.DriverManager\公众%><%@page import=\"大众java.sql.ResultSet\公众%><%@page import=\公众java.sql.SQLException\"大众%><%@page import=\公众java.sql.Statement\"大众%> <%!/从SQL SERVER中获取测试数据/ private ResultSet getTestData(String sql) { try { Class.forName(\"大众com.microsoft.sqlserver.jdbc.SQLServerDriver\公众); Connection sqlConn = DriverManager.getConnection( \"大众jdbc:sqlserver://xxxxxxx;DatabaseName=testDB\公众, \公众dbuser\"大众, \"大众password\"大众); Statement statement = sqlConn.createStatement(); ResultSet set = statement.executeQuery(sql); return set; } catch (Exception ex) { ex.printStackTrace(); return null; } }%> <!DOCTYPE html><html><head><meta charset=\公众utf-8\"大众><title>Index页面</title><style type=\"大众text/css\"大众> table{border:solid 2px black;border-collapse:collapse;} table th{color:blue;background-color:orange;border:solid 1px gray;padding:3px;} table td{border:solid 1px gray;padding:3px;}</style></head><body><%ResultSet pageData=getTestData(\"大众select top 100 sys_guid,FormId,EventId,MaxElapsedTime,SlowTotalCount,LastSlowRequestTime,DisabedRequest from TS_ConfigLimitRequest\"大众);int colCount=pageData.getMetaData().getColumnCount();%><table> <tr> <%for(int i=1;i<=colCount;i++) { %> <th><%=pageData.getMetaData().getColumnName(i) %></th> <%} %> <th>操作</th> </tr> <%while (pageData.next()){ %> <tr> <%for(int i=1;i<=colCount;i++) { %> <td><%=pageData.getString(i) %></td> <%} %> <td><a href=\"大众edit.jsp?sysguid=<%=pageData.getString(\公众sys_guid\"大众)%>\"大众 target=\"大众_blank\公众>编辑</a></td> </tr> <%} %> </table> </body></html>
JSP生命周期及干系学习教程,可参考:http://www.runoob.com/jsp/jsp-life-cycle.html
如上代码,涉及第一个重点:引用第三方JAR包(如:SQL SERVER JDBC),如何引用步骤如下:
1.先下载所需的JAR包(如这里我须要SQL SERVER JDBC的JAR包,下载地址:https://docs.microsoft.com/zh-cn/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-2017)
2.下载后将JAR包复制到WebContent\WEB-INF\lib目录下,然后选中JAR包右键,选择buid path-->configure buid path,如下图示:
3.然后如下图所示在Libaraies下选择WebContent\WEB-INF\lib目录下的mssql-jdbc-7.0.0.jre8.jar包,末了点击运用即可。
可以从项目的依赖类库中看到刚添加的JAR包,如下图示:
涉及第二个重点:利用原生JDBC操作数据库,由于这块涉及的内容比较多,故我这里借别人的图来展示一下JDBC的完全构造,代码中也只是用到了最基本的查询:
五、编写edit.jsp页面,用于可修正记录或删除记录(即:增、删、改),同样参照index.jsp的创建步骤
创建好edit.jsp空页面后,编写如下代码:
<%@ page language=\"大众java\"大众 contentType=\公众text/html; charset=UTF-8\"大众 import=\"大众java.sql.\公众 pageEncoding=\"大众UTF-8\"大众%> <% Class.forName(\公众com.microsoft.sqlserver.jdbc.SQLServerDriver\"大众);%> <%! //全局定义区 /从SQL SERVER中获取测试数据/ private Connection getConnection() throws SQLException { Connection sqlConn = DriverManager.getConnection(\"大众jdbc:sqlserver://serverIP;DatabaseName=testDB\"大众, \公众user\"大众, \公众password\"大众); return sqlConn; } private ResultSet getItemData(String sql, String sysguid) { try { Connection sqlConn = getConnection(); PreparedStatement stmt = sqlConn.prepareStatement(sql); stmt.setString(1, sysguid); ResultSet set = stmt.executeQuery(); return set; } catch (Exception ex) { ex.printStackTrace(); return null; } } /实行SQL,利用事务/ private String executeSql(String sql, String[] params) { Connection sqlConn = null; try { sqlConn = getConnection(); sqlConn.setAutoCommit(false); PreparedStatement stmt = sqlConn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { stmt.setObject(i + 1, params[i]);//参数是从1开始 } stmt.execute(); sqlConn.commit(); return \"大众实行成功!
\"大众; } catch (SQLException sqlEx) { if (sqlConn != null) { try{ sqlConn.rollback(); }catch(SQLException sqlExtrn){ return \"大众实行失落败,且回滚事务失落败,缘故原由:\公众 + sqlExtrn.getMessage(); } } return \"大众实行失落败,缘故原由:\"大众 + sqlEx.getMessage(); } catch (Exception ex) { return \公众实行失落败,缘故原由:\公众 + ex.getMessage(); } } /是否FORM要求回调/ private Boolean isPostBack(HttpServletRequest request) { String postValue = request.getParameter(\"大众__formpost\"大众); if (\公众POST\公众.equals(postValue)) { return true; } else { return false; } }%> <!DOCTYPE html><html><head><meta charset=\"大众UTF-8\"大众><title>edit页面</title></head><body> <% String execResult = \公众\"大众; if (isPostBack(request)) { String sysguid = request.getParameter(\公众sysguid\公众); String doAction = request.getParameter(\公众doAction\"大众); String formId = request.getParameter(\"大众FormId\"大众); String eventId = request.getParameter(\"大众EventId\"大众); String maxElapsedTime = request.getParameter(\公众MaxElapsedTime\公众); String slowTotalCount = request.getParameter(\公众SlowTotalCount\公众); String lastSlowRequestTime = request.getParameter(\"大众LastSlowRequestTime\"大众); String disabedRequest = request.getParameter(\"大众DisabedRequest\"大众); String sql=null; if(\"大众Save\"大众.equals(doAction)){ sql = \公众update TS_ConfigLimitRequest set FormId=?,EventId=?,MaxElapsedTime=?,SlowTotalCount=?,LastSlowRequestTime=?,DisabedRequest=? where sys_guid=?\"大众; execResult = executeSql(sql, new String[] { formId, eventId, maxElapsedTime, slowTotalCount, lastSlowRequestTime, disabedRequest, sysguid }); }else if(\公众Delete\"大众.equals(doAction)) { sql=\公众delete from TS_ConfigLimitRequest where sys_guid=?\"大众; execResult = executeSql(sql, new String[] { sysguid }); } } String sysguid = request.getParameter(\"大众sysguid\公众); ResultSet itemSet = getItemData( \公众select sys_guid,FormId,EventId,MaxElapsedTime,SlowTotalCount,LastSlowRequestTime,DisabedRequest from TS_ConfigLimitRequest where sys_guid=?\"大众, sysguid); if (!itemSet.next()) { out.println(\"大众不存在该条记录!
\"大众); return; } %> <form method=\"大众post\公众> <table> <tr> <td>FormId:</td> <td><input type=\"大众text\"大众 name=\公众FormId\"大众 value=\"大众<%=itemSet.getString(\公众FormId\"大众)%>\"大众 /></td> </tr> <tr> <td>EventId:</td> <td><input type=\"大众text\"大众 name=\"大众EventId\"大众 value=\"大众<%=itemSet.getString(\公众EventId\"大众)%>\"大众 /></td> </tr> <tr> <td>MaxElapsedTime:</td> <td><input type=\"大众text\"大众 name=\"大众MaxElapsedTime\"大众 value=\"大众<%=itemSet.getString(\"大众MaxElapsedTime\"大众)%>\"大众 /></td> </tr> <tr> <td>SlowTotalCount:</td> <td><input type=\"大众text\"大众 name=\"大众SlowTotalCount\公众 value=\"大众<%=itemSet.getString(\公众SlowTotalCount\"大众)%>\"大众 /></td> </tr> <tr> <td>LastSlowRequestTime:</td> <td><input type=\公众text\公众 name=\"大众LastSlowRequestTime\"大众 value=\公众<%=itemSet.getString(\"大众LastSlowRequestTime\"大众)%>\"大众 /></td> </tr> <tr> <td>DisabedRequest:</td> <td><select name=\公众DisabedRequest\"大众> <option value=\公众\"大众 <%if (\公众\公众.equals(itemSet.getString(\"大众DisabedRequest\"大众))) {%> selected <%}%>>-空-</option> <option value=\"大众true\"大众 <%if (\"大众true\"大众.equals(itemSet.getString(\"大众DisabedRequest\公众))) {%> selected <%}%>>true</option> <option value=\"大众false\"大众 <%if (\"大众false\公众.equals(itemSet.getString(\公众DisabedRequest\"大众))) {%> selected <%}%>>false</option> </select></td> </tr> </table> <input type=\公众hidden\"大众 name=\公众sysguid\"大众 value=\"大众<%=sysguid%>\"大众> <button id=\"大众btnSave\"大众 type=\"大众submit\"大众 name=\公众doAction\"大众 value=\"大众Save\公众>Save</button> <button id=\"大众btnSave\公众 type=\公众submit\"大众 name=\"大众doAction\"大众 value=\"大众Delete\"大众>Delete</button> <input type=\"大众hidden\"大众 name=\公众__formpost\"大众 value=\公众POST\"大众> </form> <p style=\"大众color:<%if (!execResult.isEmpty() && execResult.startsWith(\"大众保存失落败\"大众)) {%>red<%} else {%>green<%}%>\"大众> <%=execResult%> </p></body></html>
如上代码紧张涉及JDBC实行SQL语句,同时还特意利用了参数占位符以避免SQL注入,利用了事务以便可以演示事务的提交与回滚操作,详细的代码事理因篇幅有限就不先容请参摄影关文档。
六、编写一个登录验证过滤器:LoginValidationFilter,以实现对某些目录下页面进行登录限定(如:本文示例的是jsp目录),过滤器必需实现Filter接口,过滤器的紧张逻辑写在doFilter中,代码如下:
(过滤器干系知识:http://www.runoob.com/jsp/jsp-writing-filters.html)
package cn.zuowenjun.java; import java.io.IOException;import java.io.PrintWriter; 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.; / Servlet Filter implementation class LoginValidationFilter /@WebFilter(filterName=\公众LoginValidationFilter\"大众,urlPatterns=\公众/jsp/\公众)public class LoginValidationFilter implements Filter { / Default constructor. / public LoginValidationFilter() { // TODO Auto-generated constructor stub } / @see Filter#destroy() / public void destroy() { // TODO Auto-generated method stub } / @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) / public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; res.setCharacterEncoding(\"大众utf-8\"大众); res.setHeader(\公众Pragma\"大众, \"大众No-cache\"大众);// 禁止缓存 res.setHeader(\"大众Cache-Control\"大众, \"大众no-cache\公众); res.setHeader(\"大众Expires\"大众, \"大众0\公众); PrintWriter out = res.getWriter(); HttpSession session = req.getSession(); if (session.getAttribute(\"大众loginid\"大众) != null) { chain.doFilter(request, response); } else { String indexUrl = req.getContextPath() + \"大众/login.html\"大众; out.println(\公众<script>alert('您没有登录登录,请先登录!
need ReLogin!');this.location.href='\公众 + indexUrl + \公众'; </script>\"大众); } } / @see Filter#init(FilterConfig) / public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
Filter支配(映射)有两种办法,同servlet支配类假,一种是在web.xml中利用如下配置:
<filter> <filter-name>LoginValidationFilter</filter-name> <filter-class>cn.zuowenjun.java.LoginValidationFilter</filter-class></filter><filter-mapping> <filter-name>LoginValidationFilter</filter-name> <url-pattern>/jsp/</url-pattern></filter-mapping>
另一种办法便是利用@WebFilter表明,配置如下:
@WebFilter(filterName=\"大众LoginValidationFilter\公众,urlPatterns=\公众/jsp/\"大众)public class LoginValidationFilter implements Filter {...}
如此一个大略的JSP WEB示例网站代码就写完了,包含:登录、验证登录、查看数据、编辑数据,下面贴出运行效果,把稳由于是DEMO,故没有严格按照编码规范及UI用户体验,只是为了演示结果:
当然还有一种类型没有先容,那便是监听器:Listener,紧张是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个工具中的属性变更信息事宜的监听器,可参考:https://www.cnblogs.com/xdp-gacl/p/3969249.html,我们可以利用ServletRequestListener的requestInitialized、requestDestroyed方法来写一个大略的记录当前demo网站的在线用户人数,实现比较大略,在此就不再展开先容了。
七、打包支配到WEB做事器(Tomcat)
1.打包WAR包:直接参考这篇文章即可:https://www.cnblogs.com/yjq520/p/7323934.html,本身也大略便是导出时选择WAR包类型即可,在此就不先容了。
2.支配到TOMCAT:只需将打包好的WAR包复制到tomcat的webapps目录下即可,在第一次运行时tomcat会自动解包并天生一个目录,本DEMO的示例发布到TOMCAT的效果:
末了就直接在浏览器中访问URL即可:localhost:8080/demo2/xxxx;
附加2个编码小技巧:
1.创建一个JSP文件,默认字符编码并不是UTF-8,故须要手动调度一下设置,如下图所示:
2.在eclipse中运行调试JSP网站,如果本地安装了TOMCAT且后台一贯运行着默认实例,那么可能调试时会报端口被占用,如果被占用了,就须要修正一下项眼前的端口,方法如下图所示:
把稳server.xml中有好几种Connector配置,一样平常我们只需改protocal=\"大众HTTP\公众的即可,由于我们是运行WEB项目,
其余大家也看到后面还有一个redirectPort配置项,这个的浸染是:当用户用http要求某个资源URL,而该资源本身又被设置了必须要https办法访问,此时Tomcat会自动重定向到这个redirectPort设置的https端口。
末了小结:
1.JSP WEB项目中页面类一样平常包含:HTML、JSP、Servlet,个中:HTML、JSP文件是可以直接编辑HTML,而Servlet一样平常只是用于做事端要求的逻辑处理,并没有供应直接的HTML,若需相应成HTML,得自己利用JAVA代码来动态拼出HTML,原则上不建议在Servlet类中拼大量的HTML,完备可以采取JSP来代替。JSP可以HTML与JAVA措辞稠浊,大家也看我上面的DEMO代码,有些地方我用HTML静态页面,而有些我又利用JSP动态页面。如果比拟ASP.NET项目,那么JSP文件类似ASP.NET中的ASPX文件,而Servlet类似于ASHX
2.Listener:用于监听捕获WEB运用、高下文、会话的改变,并根据每种事宜处理干系逻辑,Filter:用于拦截每一个要求,并在拦截中处理干系逻辑(如:身份验证、记日志等),这些类似于ASP.NET项目中的IIS管道事宜、global全局事宜;
3.大家有没有创造,JSP WEB,要么前后分离(HTML纯前端、Servlet纯后端),要么便是稠浊(JSP,包含HTML+Servlet),那有没有一种后端掌握前端,后端与前端无需对应,但又能各自变革呢?答案是可以的,这便是下一篇我要先容的SSM框架,在此只是引入为什么须要MVC模式;
4.以前利用VS+ASP.NET,创造微软的很多东西都是开箱即用,无需过多配置就能快速上手,而eclipse+JSP WEB须要各种配置,最紧张是eclipse的编码体验确实与VS相差太远。后续考虑会学习基于IDEA或VS CODE IDE来写JAVA WEB项目,到时候再来分享。