马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1. Servlet简介
1.1 动态资源和静态资源
静态资源
- 无需再步伐运行时通过代码天生的资源,再步伐运行之前就写好的资源,比方html css js img ,音频文件和视频文件
动态资源
- 必要在步伐运行时通过代码运行天生的资源,在步伐运行之前无法确定的数据,运行时动态天生,比方Servlet,Thymeleaf......
- 动态资源指的不是视图上的动画结果大概是简朴的人机交互结果
生存举例
- 去蛋糕店买蛋糕
- 直接买柜台上已经做好的:静态资源
- 和柜员说要求后现场制作:动态资源
1.2 Servlet简介
Servlet(server applet) 是运行在服务端(tomcat)的java小步伐,是sun公司提供的一套界说动态资源规范;从代码上来讲Servlet就是一个接口
- 用来吸取从、处理惩罚客户端哀求、相应给欣赏器的动态资源。 在整个Web应用中,Servlet紧张负责吸取处理惩罚哀求、协同调治功能以及相应数据。我们可以把Servlet称为Web应用中的控制器
- 不是全部的JAVA项目都能用于处理惩罚客户端哀求,能处理惩罚客户端哀求并做出相应的一套技能标准就是Servlet
- Servlet是运行在服务端的,以是Servlet必须在WEB应用中开辟且在Tomcat如许的服务器容器中举行
哀求相应与HttpServletRequest和HttpServletResponce之间的对应关系
- package com.mdklea.servlet;
-
- import jakarta.servlet.*;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- /**
- * 1 创建javaWEB 项目,同时将tomcat添加为当前项目的依赖
- * 2 重写service方法 service(HeepServletRequest req, HttpServletResponce resp)
- * 3 在service方法中,定义业务处理代码
- * 4 在web.xml中,配置Servlet 对应的请求映射路径
- *
- * 1 servlet-api.jar 导入问题
- * servlet-api 编码的时候需要,运行的时候,在服务器的环境中,由服务软件(Tomcat)提供
- * 因此,我们的JAVAWEB项目中,在打包/构建的时候,是无需携带servlet-api的jar包的
- * 2 Content-Type 响应头的问题
- * MIME类型响应头,媒体类型,文件类型,相应的数据类型
- * MIME类型用于告诉客户端相应的数据是什么类型的数据,客户端以此类型决定用什么方式解析响应体
- */
- public class UserServlet extends HttpServlet {
- @Override
- protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1. 从request 对象中获取请求中的任何信息(username参数)
- String username = request.getParameter("username");//根据参数名获取参数值,无论url是在url?后还是在请求体中
- String inFo = "yes";
- //2. 处理业务的代码
- if ("md2".equals(username)) {
- inFo = "no";
- }
- //3. 将要相应的数据放入responce
- //应该设置Content-Type响应头
- //response.setHeader("Content-Type","text/html");
- response.setContentType("text/html");
- PrintWriter writer = response.getWriter(); //该方法是返回一个向响应体中返回字符串的打印流
- writer.write(inFo);
- }
- }
复制代码- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
- version="6.0">
-
- <!-- 模糊匹配-->
- <!-- / 匹配全部,不包含jsp文件-->
- <!-- /* 匹配全部,包含jsp文件-->
- <!-- /a/* 匹配前缀,后缀模糊-->
- <!-- *.action 匹配后缀,前缀模糊-->
- <servlet>
- <servlet-name>userServlet</servlet-name>
- <servlet-class>com.mdklea.servlet.UserServlet</servlet-class>
- </servlet>
-
- <servlet>
- <servlet-name>servlet1</servlet-name>
- <servlet-class>com.mdklea.servlet.Servlet1</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>userServlet</servlet-name>
- <url-pattern>/userServlet</url-pattern>
- </servlet-mapping>
-
- <servlet-mapping>
- <servlet-name>servlet1</servlet-name>
- <url-pattern>/s1</url-pattern>
- </servlet-mapping>
- </web-app>
复制代码 2. Servlet注解方式设置
@webServlet注解源码
value 与 urlPatterns互为别名- //
- // Source code recreated from a .class file by IntelliJ IDEA
- // (powered by FernFlower decompiler)
- //
-
- package jakarta.servlet.annotation;
-
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface WebServlet {
- String name() default "";
-
- String[] value() default {};
-
- String[] urlPatterns() default {};
-
- int loadOnStartup() default -1;
-
- WebInitParam[] initParams() default {};
-
- boolean asyncSupported() default false;
-
- String smallIcon() default "";
-
- String largeIcon() default "";
-
- String description() default "";
-
- String displayName() default "";
- }
复制代码 3. Servlet生命周期
3.1 声明周期简介
什么是Servlet的生命周期
- 应用步伐中的对象不但在空间上有条理布局的关系,在时间上也会由于处于步伐运行过程中的差别阶段而表现出差别状态和不偕活动-----这就是对象的生命周期。
- 简朴的叙述生命周期,就是对象在容器中从开始创建到烧毁的过程。
servlet容器
- Servlet对象是Servlet容器创建的,生命周期方法都是由容器(现在我们利用的是Tomcat)调用的。这一点和我们之前所编写的代码有很大差别。在以后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开辟职员要尽大概多的将精力放在业务逻辑的实现上。
servlet紧张声明周期实行特点
3.2 线性安全标题
3.3 defaultServlet
- package com.mdklea.servlet;
-
- import jakarta.servlet.ServletException;
- import jakarta.servlet.annotation.WebServlet;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import jakarta.servlet.http.PushBuilder;
-
- import java.io.IOException;
-
- /**
- * 1 实例化 构造器 第一次请求
- * 2 初始化 init 构造完毕
- * 3 接收请求 服务 service 每次请求
- * 4 销毁 destory 关闭服务
- *
- * Servlet在Tomcat中是单例的
- * Servlet的成员变量在多个线程之中是共享的
- * 不建议在Service方法中修改成员变量,在并发请求时,会引发线程安全问题
- */
- public class ServletLifeCicle extends HttpServlet {
- public ServletLifeCicle() {
- }
-
- @Override
- public void init() throws ServletException {
- super.init();
- }
-
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- }
-
- @Override
- public void destroy() {
- super.destroy();
- }
- }
复制代码- <servlet>
- <servlet-name>ServletLifeCycle</servlet-name>
- <servlet-class>com.mdklea.servlet.ServletLifeCicle</servlet-class>
- <!--
- 默认值是-1,含义是 tomcat 启动时不会实例化该servlet
- 其他正整数 15 含义是 tomcat 在启动时,实例化该servlet的顺序,如果序号冲突了,tomcat会自动协调启动顺序
- -->
- <load-on-startup>-1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>ServletLifeCycle</servlet-name>
- <url-pattern>/ServletLifeCycle</url-pattern>
- </servlet-mapping>
复制代码 4. Servlet继续布局
4.1 Servlet接口
- /*
- 1. 顶级的Servlet接口
- public interface Servlet {
- // 初始化方法,构造完毕后,由tomcat自动调用完成初始化功能的方法
- void init(ServletConfig var1) throws ServletException;
-
- // 获取ServletConfig 对象的方法
- ServletConfig getServletConfig();
-
- // 接收用户请求,向用户响应信息的方法
- void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
-
- // 返回Servlet字符串形式描述信息的方法
- String getServletInfo();
-
- // Servlet在回收前,由tomcat调用的销毁方法,往往用于做资源的释放工作
- void destroy();
- }
- */
复制代码 4.2 GenericServlet抽象类
- /*
- 2. 抽象的类 GenericServlet 侧重于除了service方法以外的其他方法的基础处理
- public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
- private transient ServletConfig config;
-
- public void destroy() {
- // 将抽象方法重写为普通方法,在方法内部没有任何的代码实现
- // 平庸实现
- }
- //tomcat在调用init 方法时,会读取配置信息进入一个ServletConfig 对象并将该对象传入init方法
- public void init(ServletConfig config) throws ServletException {
- // 将config 对象存储为当前的属性
- this.config = config;
- // 调用了重载的无参init
- this.init();
- }
- public void init() throws ServletException {
- // 重载的初始化方法,我们重写初始化方法时对应的方法
- }
- // 返回ServletConfig的方法
- public ServletConfig getServletConfig() {
- return this.config;
- }
- // 再次抽象声明service方法
- public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
-
- }
- */
复制代码 4.3 HttpServlet 抽象类
- /*
- // 抽象的类 HttpServlet
- public abstract class HttpServlet extends GenericServlet {
- //
- public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
-
- // 参数的父转子
- HttpServletRequest request;
- HttpServletResponse response;
- try {
- request = (HttpServletRequest)req;
- response = (HttpServletResponse)res;
- } catch (ClassCastException var6) {
- throw new ServletException(lStrings.getString("http.non_http"));
- }
- // 调用重载的service 方法
- this.service(request, response);
- }
-
- //
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // 获取请求的方式 GET POST PUT DELETE OPTIONS
- String method = req.getMethod();
- long lastModified;
-
- // 根据请求方式调用对应的do。。。方法 故意响应405
- if (method.equals("GET")) {
- lastModified = this.getLastModified(req);
- if (lastModified == -1L) {
- this.doGet(req, resp);
- } else {
- long ifModifiedSince;
- try {
- ifModifiedSince = req.getDateHeader("If-Modified-Since");
- } catch (IllegalArgumentException var9) {
- ifModifiedSince = -1L;
- }
-
- if (ifModifiedSince < lastModified / 1000L * 1000L) {
- this.maybeSetLastModified(resp, lastModified);
- this.doGet(req, resp);
- } else {
- resp.setStatus(304);
- }
- }
- } else if (method.equals("HEAD")) {
- lastModified = this.getLastModified(req);
- this.maybeSetLastModified(resp, lastModified);
- this.doHead(req, resp);
- } else if (method.equals("POST")) {
- this.doPost(req, resp);
- } else if (method.equals("PUT")) {
- this.doPut(req, resp);
- } else if (method.equals("DELETE")) {
- this.doDelete(req, resp);
- } else if (method.equals("OPTIONS")) {
- this.doOptions(req, resp);
- } else if (method.equals("TRACE")) {
- this.doTrace(req, resp);
- } else {
- String errMsg = lStrings.getString("http.method_not_implemented");
- Object[] errArgs = new Object[]{method};
- errMsg = MessageFormat.format(errMsg, errArgs);
- resp.sendError(501, errMsg);
- }
-
- }
-
- //doGet方法
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String msg = lStrings.getString("http.method_get_not_supported");
- this.sendMethodNotAllowed(req, resp, msg);
- }
- //sendMethodNotAllowed
- private void sendMethodNotAllowed(HttpServletRequest req, HttpServletResponse resp, String msg) throws IOException {
- String protocol = req.getProtocol();
- // 故意响应405
- if (protocol.length() != 0 && !protocol.endsWith("0.9") && !protocol.endsWith("1.0")) {
- resp.sendError(405, msg);
- } else {
- resp.sendError(400, msg);
- }
- }
-
- // 自定义Servlet
- Class Servlet1 extends HttpServlet {
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // 接收用户请求信息
-
- // 做出响应
- }
- }
- }
- 1 部分程序员推荐在servlet中重写do*** 方法处理请求,理由:service方法中可能做了一些处理,如果我们直接重写service的话,父类中service
- 方法中的一些处理可能会失效
- 2 目前直接重写service 也没有什么问题
- 3 后续使用SpringMVC框架后,我们则无需继承HttpServlet,处理请求的方法也无需是 do*** service
- 4 如果doGet 和doPost 方法中,我们定义的代码都一样,可以让一个方法直接调用另一个方法
-
- 掌握的技能 继承HttpServlet后,要么重写service 方法,要么重写 doGet/doPost
- */
复制代码 5. ServletConfig 的利用
ServletConfig 是什么
- 为Servlet提供初始设置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象
- 容器会为每个Servlet实例化一个ServletConfig对象,并通过Servlet生命周期的init方法传入给Servlet作为属性
6. ServletContext 的利用
ServletContext 是什么
- ServletContext 对象有称呼为上下文对象,大概叫应用域对象(背面同意解说域对象)
- 容器会为每个app创建一个独立的唯一的ServletContext对象
- ServletContext对象为全部的Servlet所共享
- ServletContext可以为全部的Servlet提供初始设置参数
ServletContext怎么用- package com.mdklea.servlet;
-
-
- import jakarta.servlet.ServletContext;
- import jakarta.servlet.ServletException;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.Enumeration;
-
-
- public class Servlet01 extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // ServletConfig servletConfig = getServletConfig();
- // String key1 = servletConfig.getInitParameter("key1");
- // System.out.println("key1: " + key1);
- // Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
- // while (initParameterNames.hasMoreElements()) {
- // String s = initParameterNames.nextElement();
- // System.out.println("pname: " + s);
- // }
- System.out.println("--------------------------------------");
- ServletContext servletContext = this.getServletContext();
- Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
- while (initParameterNames.hasMoreElements()) {
- String pname = initParameterNames.nextElement();
- System.out.println("pname: " + pname +"\n" + "context" + servletContext.getInitParameter(pname));
- }
- }
- }
复制代码 ServletContext APIs
获取资源的真实路径- String realPath = servletContext.getReadPath("资源在web目录中的路径");
复制代码
- 比方我们的目标是必要获取项目中某个静态资源的路径,不是工程目次中的路径,而是摆设目次中的路径,我们假如直接拷贝其在我们电脑中的完备路径的话着实是有标题的,由于假如该项目以后摆设到公司服务器上的话,路径肯定是会发生变革的,以是我们必要利用代码动态获取资源的真实路径,只要利用了servletContext 动态获取资源的真实路径,那么无论项目标摆设路径发生什么变革,都会动态获取项目运行时间的实际路径,以是就不会发生由于写死真实路径而导致项目摆设位置改变引发的路径错误标题。
获取项目标上下文路径- String contextPath = servletContext.getContextPath();
复制代码
- 项目摆设名称,也叫项目标上下文路径,在摆设进入tomcat时利用的路径,该路径是大概发生变革的,通过API动态获取项目真实的上下文路径,可以资助我们办理一些后端页面渲染技能大概哀求转发和相应重定向中的路径标题。
域对象干系的API
- 域对象:一些用于存储数据和通报数据的对象,通报数据差别的范围,我们称之为差别的域差别的域对象代表差别的域,共享数据的范围也差别
- ServletContext代表应用,以是ServletContext域也叫应用域,是webapp中最大的域,可以在本应用内实现数据的共享和通报
- webapp中三大域对象,分别是应用域,会话域,哀求域
- 背面我们会为三大域通一举行解说和演示
- package com.mdklea.servlet;
-
-
- import jakarta.servlet.ServletContext;
- import jakarta.servlet.ServletException;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.Enumeration;
-
-
- public class Servlet01 extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // ServletConfig servletConfig = getServletConfig();
- // String key1 = servletConfig.getInitParameter("key1");
- // System.out.println("key1: " + key1);
- // Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
- // while (initParameterNames.hasMoreElements()) {
- // String s = initParameterNames.nextElement();
- // System.out.println("pname: " + s);
- // }
- System.out.println("--------------------------------------");
- ServletContext application = this.getServletContext();
- Enumeration<String> initParameterNames = application.getInitParameterNames();
- while (initParameterNames.hasMoreElements()) {
- String pname = initParameterNames.nextElement();
- System.out.println("pname: " + pname +"\n" + "context" + servletContext.getInitParameter(pname));
- }
- //作为域对象一定会有的API
- // void setAttribute(String key,Object value) 向狱中存储/修改数据
- application.setAttribute("keya","valueA");
- application.setAttribute("keyb","valueb");
- // Object getAttribute(String key) 获取域中的数据
- String keya = (String) application.getAttribute("keya");
- System.out.println(keya);
- // void removeAttribute(String key); 删除域中的数据
- application.removeAttribute("keyb");
-
- }
- }
-
复制代码 7. HttpServletRequest
- 获取哀求行信息干系(方式,哀求的url,协议及版本)
- package com.mdklea.servlet;
-
- import jakarta.servlet.ServletException;
- import jakarta.servlet.annotation.WebServlet;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.Enumeration;
-
- @WebServlet("/Servlet4")
- public class Servlet04 extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // 行相关 GET POST uri Http/1.1
- System.out.println(req.getMethod()); //获取请求方式
- System.out.println(req.getScheme()); // 获取请求协议
- System.out.println(req.getProtocol()); // 获取请求协议及版本
- System.out.println(req.getRequestURI()); // 获取请求的uri 项目内的资源路径
- System.out.println(req.getRequestURL()); // 获取请求的url 项目内资源的完成的路径
- /*
- URI :统一资源标识符 /demo/a.html interface URI() 资源定位要求和规范 动物类
- URL :统一资源定位符 http://ip:port/demo/a.html class URL implements UTI{} 一个具体的资源路径 哺乳动物类
- */
- System.out.println(req.getLocalPort()); // 本应用容器的端口号 8080
- System.out.println(req.getServerPort()); // 客户端发请求时使用的端口号
- System.out.println(req.getRemotePort()); // 客户端软件的端口号
- // 头相关 key-value,key-value
- // 根据名字单独获取某个请求头
- String accept = req.getHeader("Accept");
- System.out.println("Accept" + accept);
-
- // 获取本次请求中所有的请求头的名字
- Enumeration<String> headerNames = req.getHeaderNames();
- while (headerNames.hasMoreElements()) {
- String hname = headerNames.nextElement();
- System.out.println(hname + req.getHeader(hname));
- }
- }
- }
复制代码
- package com.mdklea.servlet;
-
- import jakarta.servlet.ServletException;
- import jakarta.servlet.annotation.WebServlet;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.*;
-
- @WebServlet("/servlet5")
- public class Servlet05 extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println(req.getParameter("username"));
- System.out.println(req.getParameter("userPwd"));
- // System.out.println(req.getParameter("hobby"));
- // 根据参数名获取多个参数值
- String[] hobbies = req.getParameterValues("hobby");
- for (String hobby : hobbies) {
- System.out.println(hobby);
- }
- // 获取所有的参数名
- Enumeration<String> parameterNames = req.getParameterNames();
- while (parameterNames.hasMoreElements()) {
- String pname = parameterNames.nextElement();
- String[] parameterValues = req.getParameterValues(pname);
- if (parameterValues.length > 1) {
- System.out.println(pname + " = " + Arrays.toString(parameterValues));
- }else {
- System.out.println(pname + "=" + parameterValues[0]);
- }
- }
- // 获取map形式的参数名
- Map<String, String[]> parameterMap = req.getParameterMap();
- Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
- for (Map.Entry<String, String[]> entry : entries) {
- String key = entry.getKey();
- String[] value = entry.getValue();
- if (value.length > 1) {
- System.out.println(key + " = " + Arrays.toString(value));
- }else {
- System.out.println(key + " = " + value[0]);
- }
- }
- /*
- 以上API专门用于获取key=value形式的参数,无论这些参数是在url后还是在请求体中
- 请求
- 请求行 方式 uri http/1.1
- 请求头
- 请求体
-
- form 表单标签提交GET请求时,参数以键值对形式放在url后,不放在请求体里,GET方式的请求也是可以有请求体的
-
- post
-
- 获得请求体中的非键值对数据?
- // 获得一个从请求体中读取字符的字符输入流
- BufferedReader reader = req.getReader(); JSON串
- // 获得一个从请求中读取二进制数据字节的输入流
- ServletInputStream inputStream = req.getInputStream(); 文件
- */
- String servletPath = req.getServletPath();
- }
- }
复制代码 8. HttpServletResponce
HttpServletResponce是什么
- HttpServletResponce 是一个接口,其父接口是ServletResponse
- HttpServletResponce 是Tomcat预先创建的,在Tomcat调用service方法时传入
- HttpServletResponce代表对客户端的相应,该对象会被转换成相应的报文发送给客户端,通过该对象我们可以设置相应信息
HttpServletResponce常用API
- package com.mdklea.servlet;
-
- import jakarta.servlet.ServletException;
- import jakarta.servlet.annotation.WebServlet;
- import jakarta.servlet.http.HttpServlet;
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- @WebServlet("/servlet6")
- public class Servlet06 extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // 设置相应行相关的API HTTP/1.1 200/404/405/500/...
- resp.setStatus(200);
- String info = "<h1>Hello</h1>";
- // 设置响应头相关的API
- resp.setHeader("aaa","valuea");
- resp.setHeader("Content-Type","text/html");
- resp.setHeader("Content-Length","1234");
- resp.setContentType("text/html");
- resp.setContentLength(info.getBytes().length);
-
- // 设置响应体内容API
- // 获得一个向响应体中输入文本字符输出流
- PrintWriter writer = resp.getWriter();
- writer.write(info);
- // 获得一个向响应体中输入二进制信息的字节输入流
- // ServletOutputStream outputStream = resp.getOutputStream();
- }
- }
复制代码 |