response响应

重要的API

config

  • init()和init(ServletConfig config)

getInitParameter():String

getServletConfig().getInitParameter("height")

response响应

HttpServletResponse接口属于Servlet规范,存在于servlet-api.jar中,由服务器提供接口的实现类,主要用于封装服务器的响应信息,可以将doGet或doPost的响应信息写出到【响应体】中

  • ServletResponse隐藏了向浏览器发送响应的复杂过程

响应头的相关操作

addHeader(String name, String value) / addIntHeader(String name, int value) /addDateHeader(String name, long date)

  • Content-Disposition Expires Cache-Control

setHeader(String name, String value) / setDateHeader(String name, long date) / setIntHeader(String name, int value)

其中,add表示添加,而set表示设置

响应输出流的操作

PrintWriter getWriter()获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。

response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<html>....</html>");  //可以输出html文档
out.flush();
out.close();

ServletOutputStream getOutputStream()获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。

需求:动态生成验证码—防止机器人

具体应用使用组件

public class PicServlet extends HttpServlet {
    private int width=120,height=40;

    //允许在web.xml中针对图片的高和宽进行配置
    public void init() throws ServletException {
        String ss=this.getServletConfig().getInitParameter("width");
        try{
            width=Integer.parseInt(ss);
        }catch (Exception e){
            width=120;
        }
        ss=this.getServletConfig().getInitParameter("height");
        try{
            height=Integer.parseInt(ss);
        }catch (Exception e){
            height=40;
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics paint=img.getGraphics();
        paint.setColor(new Color(200,200,100));
        paint.fillRect(0,0,width,height);
        paint.setColor(Color.black);
        paint.drawRect(2,2,width-6,height-6);
        //绘制动态验证码
        String checkcode=this.generateCode(6);
        System.out.println(checkcode);
        paint.setColor(Color.red);
        paint.setFont(new Font("宋体",Font.BOLD,28));//设置绘制字符所使用的字体
        paint.drawString(checkcode,10,height-10);
        //绘制杂点或者扰动线,避免OCR图像识别
        paint.dispose();

        //告知浏览器如何处理响应内容
        response.setContentType("image/jpeg");
        ServletOutputStream sos=response.getOutputStream();
        //输出为JPG格式
        ImageIO.write(img,"jpg",sos); //通过输出的字节流输出jpg格式的图片
        sos.flush();
        sos.close();
    }
    //生态动态验证码
    private String source="abcdefghijklmnopqrstuvwxyz1234567890";//在验证码中允许出现的字符范围
    private String generateCode(int len){
        Random r=new Random();
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<len;i++){
            int pos=r.nextInt(source.length());
            sb.append(source.charAt(pos));
        }
        return sb.toString();
    }
}

web.xml的Servlet和Servlet初始化参数的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>PicServlet</servlet-name>
        <servlet-class>com.yan.action.PicServlet</servlet-class>
        <init-param>
            <param-name>width</param-name>
            <param-value>200</param-value>
        </init-param>
        <init-param>
            <param-name>height</param-name>
            <param-value>60</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>PicServlet</servlet-name>
        <url-pattern>/pic.do</url-pattern>
    </servlet-mapping>
</web-app>

客户端缓存

思路:使每次访问URL都不一致,引入一个没有用的额外参数

<body onload="ff()">
<form action="login.do" method="post">
    <input name="checkcode"/>
    <img id="img1"/>
    <script>
        function ff(){
            document.getElementById("img1").src='pic.do?q='+Math.random();
        }
    </script>
</form>
</body>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

服务器端设置避免客户端缓存

response.setContentType("image/jpeg");
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires",0);
ServletOutputStream sos=response.getOutputStream();
... ...

其它操作

指定浏览器解析页面的编码方式setContentType(String type),这里的类型定义type采用的是MIME格式的规范

  • text/html表示是一个html格式的文本文档
  • image/jpeg表示是一个jpg格式的图片文档
response.setContentType("text/html;charset=utf-8");

设置响应行状态码setStatus(int sc)

  • 200 OK
  • 404
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setStatus(404);
}

sendError(int sc, String msg)设置报错状态码,例如404,String是自定义的报错信息

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendError(404,"张前端来了!");
}

如何自定义报错页面

  • 一般是应用完成后给客户提交之前配置的,主要作用是隐藏各种报错信息
  • 如果开发过程中不建议配置

web.xml中允许配置在当前应用中报错处理页面

<!--在当前应用中如果出现404异常时,自动跳转abc.html页面-->
<error-page>
	<error-code>404</error-code>
    <location>/abc.html</location>
</error-page>

可以在当前应用中全局配置针对指定异常的报错页面

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int k=0;
        System.out.println(10/k);
}

默认报错为【HTTP状态 500 - 内部服务器错误】

<!-- 在当前应用中如果出现Exception类型的异常则自动跳转bbb.html页面-->
<error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/bbb.html</location>
</error-page>

request请求

HttpServletRequest接口类型,属于Servlet规范,存在于servlet-api.jar中,由服务器提供接口的具体实现类

  • 主要用于封装用户的请求数据
  • Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息
  • request对象是从发起请求开始创建,生成响应完毕后销毁

请求头数据

long getDateHeader(String name) / String getHeader(String name) /int getIntHeader(String name)

Enumeration getHeaderNames() / Enumeration getHeaders(String name)

referer头的作用:执行该此访问的的来源,做防盗链

  • 图片水印
  • 盗链页面
 @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //如果地址栏中直接访问,则返回为null;如果有上一个页面,则返回该页面的地址,例如http://localhost:8080/demo3_war_exploded/login.html
        String referer=request.getHeader("referer");
        System.out.println(referer);
}

###请求参数

get采用的是协议头的方式传递数据,数据格式为abc.do?username=zhangsan&password=123

post采用的是协议体的方式传入数据,请求体中的内容是通过post提交的请求参数,格式是:username=zhangsan&password=123

String getParameter(String name)

String sage=request.getParameter("age");   //传递各种数据类型时只能接收到String或者String[]类型
Integer age=null;
try{
    age=Integer.parseInt(sage);
}catch(Exception e){
    age=null;
}
//if(age==null)  如果要求必须正确的age提交参数的报错处理,如果age值可有可无,则不做处理

String[] getParameterValues(String name)

Enumeration getParameterNames()

Map<String,String[]> getParameterMap()

Request乱码问题的解决方法

在service中使用的编码解码方式默认为ISO-8859-1编码,但此编码并不支持中文,因此会出现乱码问题,所以我们需要手动修改编码方式为UTF-8编码,才能解决中文乱码问题

中文乱码的3种解决方案:

  • 针对post请求
<meta charset="GBK">

<form action="test.do" method="post">
    <input name="name"/>
    <input type="submit" value="提交数据"/>
</form>

java编程接收数据的处理

//设置请求编码字符集必须在所有获取请求参数之前,否则设置无效
request.setCharacterEncoding("GBK");   //这里编码字符集必须和提交数据的页面编码字符集一致

String ss=request.getParameter("name");
System.out.println(ss);
  • 针对get请求

修改Tomcat的配置server.xml,添加一个配置参数URIEncoding=“GBK”

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="GBK" redirectPort="8443" />
  • 通用解决方案
String ss=request.getParameter("name");
ss=new String(ss.getBytes("ISO-8859-1"),"GBK");
System.out.println(ss);

###其它方法

获得客户端的请求方式:String getMethod()

参照HttpServlet类中service方法的实现—模板模式

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();  //获取请求方法,按照http1.1协议有8种不同的请求方法,例如get、post、delete、put等
        if (method.equals(METHOD_GET)) {
                doGet(req, resp);//如果请求方法是GET时,则调用doGet,在HttpServlet类中声明了方法,但是没有具体的实现,实现延迟到具体子类中进行覆盖定义
        } else if (method.equals(METHOD_HEAD)) {
            doHead(req, resp);
        } else if (method.equals(METHOD_POST)) {
           doPost(req, resp);
        } else if (method.equals(METHOD_PUT)) {
           doPut(req, resp);
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
        } else {
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }
public abstract class BaseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        if(action==null ||action.trim().length()<1)
            action="show";
        try {
            Class clz = this.getClass();
            Method method = clz.getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,req,resp);
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }
    public abstract void show(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
}

用户CRUD操作

public class UserServlet extends BaseServlet {
    @Override
    public void show(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//路径是user.do?action=show或者user.do
    }
    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//路径是user.do?action=add
    }

    public void del(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//路径是user.do?action=del
    }

    public void load(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//路径是user.do?action=load&id=1
    }

    public void modify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//路径是user.do?action=modify
    }
}

OOP编程原则:

  • 要求类内高内聚、类间弱耦合
  • 将一个用户的相关操作定义在4个不同的Servlet类中
  • 解决方案:引入一个额外的动作参数

获得请求的资源:

String getRequestURI() /demo3/test.do 不会包含get请求的参数

StringBuffer getRequestURL() http://localhost:8080/demo3/test.do

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println(request.getRequestURI());
}

String getContextPath() —web应用的名称 /demo3

String getQueryString() ---- get提交url地址后的参数字符串 //id=123&name=yanjun

Java反射基础

构建对象

 //构建一个对象,类名称是作为字符串类型的参数进行指定
Object obj=Class.forName("com.yan.action.Test2").newInstance(); //等价于new Test2();

调用方法

 //构建一个对象,类名称是作为字符串类型的参数进行指定
Object obj=Class.forName("com.yan.action.Test2").newInstance();
//获取类的引用
Class clz=obj.getClass();
//查找指定的方法,参数1:方法名称为字符串类型,后续参数就是该方法的参数类型
Method method=clz.getDeclaredMethod("pp",Integer.class);

//调用查找到的方法,参数1是方法所在的对象,如果有参数才有后续的参数,后续参数就是调用方法时的实参
Object res=method.invoke(obj,10);
System.out.println(res);  //null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 ASP.NET Web API 来创建一个 Web 服务,读取文件内容并将其作为文件下载响应返回给客户端。 以下是一个简单的示例代码: ```csharp using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Web.Http; public class FileController : ApiController { [HttpGet] public HttpResponseMessage DownloadFile(string filePath) { try { // 读取文件内容 byte[] fileBytes = File.ReadAllBytes(filePath); // 创建 HTTP 响应 var response = new HttpResponseMessage(HttpStatusCode.OK); response.Content = new ByteArrayContent(fileBytes); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(filePath); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return response; } catch (Exception e) { // 创建 HTTP 错误响应 var response = new HttpResponseMessage(HttpStatusCode.InternalServerError); response.Content = new StringContent("读取文件失败:" + e.Message); return response; } } } ``` 你需要在 Web 服务中注册该控制器,并启动 Web 服务。然后,你可以通过发送 GET 请求到 `/api/file?filePath=C:\example.txt` 来下载文件。如果文件读取成功,将返回 HTTP 200 OK 响应,并包含文件内容。如果文件读取失败,将返回 HTTP 500 Internal Server Error 响应,并包含错误消息。另外,该代码还会设置响应头,以便浏览器能够正确地将文件下载到本地。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值