001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.components.http;
017
018import com.jfinal.log.Log;
019
020import java.io.*;
021import java.util.List;
022import java.util.Map;
023
024public class JbootHttpResponse implements Closeable {
025
026    private static final Log LOG = Log.getLog(JbootHttpResponse.class);
027
028    private final JbootHttpRequest request;
029    private String content;
030    private OutputStream contentStream;
031    private File file;
032    private Throwable error;
033    private Map<String, List<String>> headers;
034    private int responseCode;
035    private String contentType;
036
037    public JbootHttpResponse(JbootHttpRequest request) {
038        this.request = request;
039
040        File downloadToFile = request.getDownloadFile();
041
042        if (downloadToFile != null) {
043            if (!downloadToFile.getParentFile().exists() && !downloadToFile.getParentFile().mkdirs()) {
044                LOG.error("Can not mkdirs for: " + downloadToFile.getParentFile());
045            }
046            if (downloadToFile.exists() && !downloadToFile.delete()) {
047                LOG.error("Can not delete file: " + downloadToFile);
048            }
049            try {
050                this.file = downloadToFile;
051                this.contentStream = new FileOutputStream(file);
052            } catch (Exception e) {
053                throw new RuntimeException(e);
054            }
055        } else {
056            this.contentStream = new ByteArrayOutputStream();
057        }
058    }
059
060
061    /**
062     * 获取数据内容
063     *
064     * @return
065     */
066    public String getContent() {
067        return getContent(request.getCharset());
068    }
069
070    /**
071     * 获取数据内容
072     *
073     * @return
074     */
075    public String getContent(String charset) {
076        if (content != null) {
077            return content;
078        }
079        if (contentStream != null && contentStream instanceof ByteArrayOutputStream) {
080            try {
081                return ((ByteArrayOutputStream) contentStream).toString(charset);
082            } catch (UnsupportedEncodingException e) {
083                LOG.error(e.toString(), e);
084            }
085        }
086        return null;
087    }
088
089
090    public void setContent(String content) {
091        this.content = content;
092    }
093
094
095    /**
096     * 把 inputStream 写入response
097     *
098     * @param inputStream
099     */
100    public void copyStream(InputStream inputStream) {
101        try {
102            byte[] buffer = new byte[1024];
103            for (int len = 0; (len = inputStream.read(buffer)) > 0; ) {
104                contentStream.write(buffer, 0, len);
105            }
106        } catch (Throwable throwable) {
107            LOG.error(throwable.toString(), throwable);
108            setError(throwable);
109        }
110    }
111
112    /**
113     * 结束response和释放资源
114     */
115    @Override
116    public void close() {
117        if (contentStream != null) {
118            try {
119                contentStream.flush();
120                contentStream.close();
121            } catch (IOException e) {
122                LOG.error(e.toString(), e);
123            }
124        }
125    }
126
127
128    public boolean isNotError() {
129        return !isError();
130    }
131
132    public boolean isError() {
133        return error != null;
134    }
135
136    public Throwable getError() {
137        return error;
138    }
139
140    public void setError(Throwable error) {
141        this.error = error;
142    }
143
144    public File getFile() {
145        return file;
146    }
147
148    public void setFile(File file) {
149        this.file = file;
150    }
151
152    public Map<String, List<String>> getHeaders() {
153        return headers;
154    }
155
156    public void setHeaders(Map<String, List<String>> headers) {
157        this.headers = headers;
158    }
159
160    public int getResponseCode() {
161        return responseCode;
162    }
163
164    public void setResponseCode(int responseCode) {
165        this.responseCode = responseCode;
166    }
167
168    public String getContentType() {
169        return contentType;
170    }
171
172    public void setContentType(String contentType) {
173        this.contentType = contentType;
174    }
175
176
177    @Override
178    public String toString() {
179        return "JbootHttpResponse{" +
180                "\nfile=" + file +
181                "\nheaders=" + headers +
182                "\nresponseCode=" + responseCode +
183                "\ncontentType=" + contentType +
184                "\ncontent=" + getContent() +
185                "\n}";
186    }
187}