Files
redkale/src/main/java/org/redkale/net/http/HttpRequest.java
2023-11-20 18:56:40 +08:00

2858 lines
92 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* To change this license headers, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.io.*;
import java.lang.annotation.Annotation;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import java.util.*;
import java.util.function.Supplier;
import java.util.logging.Level;
import org.redkale.annotation.Comment;
import org.redkale.asm.AsmDepends;
import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.Request;
import org.redkale.util.*;
import static org.redkale.util.Utility.isEmpty;
/**
* Http请求包 与javax.servlet.http.HttpServletRequest 基本类似。 <br>
* 同时提供json的解析接口: public Object getJsonParameter(Type type, String name) <br>
* Redkale提倡带简单的参数的GET请求采用类似REST风格, 因此提供了 getRequstURIPath 系列接口。 <br>
* 例如简单的翻页查询 <br>
* /pipes/user/query/offset:0/limit:20 <br>
* 获取页号: int offset = request.getRequstURIPath("offset:", 0); <br>
* 获取行数: int limit = request.getRequstURIPath("limit:", 10); <br>
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*/
public class HttpRequest extends Request<HttpContext> {
private static final boolean PIPELINE_SAME_HEADERS = Boolean.getBoolean("redkale.http.request.pipeline.sameheaders");
protected static final Serializable CURRUSERID_NIL = new Serializable() {
};
protected static final int READ_STATE_ROUTE = 1;
protected static final int READ_STATE_HEADER = 2;
protected static final int READ_STATE_BODY = 3;
protected static final int READ_STATE_END = 4;
protected static final byte[] EMPTY_BYTES = new byte[0];
protected static final String METHOD_GET = "GET";
protected static final String METHOD_PUT = "PUT";
protected static final String METHOD_POST = "POST";
protected static final String METHOD_HEAD = "HEAD";
protected static final String METHOD_OPTIONS = "OPTIONS";
protected static final String HTTP_1_1 = "HTTP/1.1";
protected static final String HTTP_2_0 = "HTTP/2.0";
protected static final String HEAD_COOKIE = "Cookie";
protected static final String HEAD_CONNECTION = "Connection";
protected static final String HEAD_CONTENT_TYPE = "Content-Type";
protected static final String HEAD_CONTENT_LENGTH = "Content-Length";
protected static final String HEAD_ACCEPT = "Accept";
protected static final String HEAD_HOST = "Host";
protected static final String HEAD_UPGRADE = "Upgrade";
protected static final String HEAD_USER_AGENT = "User-Agent";
protected static final String HEAD_EXPECT = "Expect";
public static final String SESSIONID_NAME = "JSESSIONID";
//---------- header 相关参数 开始 ----------
protected int headerLength;
protected int headerHalfLen;
protected String contentType;
protected long contentLength = -1;
protected String host;
@Comment("原始的cookie字符串解析后值赋给HttpCookie[] cookies")
protected String cookie;
protected HttpCookie[] cookies;
private boolean maybews = false; //是否可能是WebSocket
private boolean expect = false; //是否Expect:100-continue
protected boolean rpc;
protected int readState = READ_STATE_ROUTE;
// @since 2.1.0
protected Serializable currentUserid = CURRUSERID_NIL;
protected Supplier<Serializable> currentUserSupplier;
protected ConvertType reqConvertType;
protected Convert reqConvert;
protected ConvertType respConvertType;
protected Convert respConvert;
protected final HttpHeaders headers = HttpHeaders.create();
//---------- header 相关参数 结束 ----------
@Comment("Method GET/POST/...")
protected String method;
protected boolean getmethod;
protected String protocol;
protected String requestURI;
protected byte[] queryBytes;
protected String newSessionid;
protected final HttpParameters params = HttpParameters.create();
protected boolean boundary = false;
protected int moduleid;
protected int actionid;
protected Annotation[] annotations;
protected String remoteAddr;
protected String locale;
private String lastRequestURIString;
private byte[] lastRequestURIBytes;
private final ByteArray array;
private byte[] headerBytes;
private boolean headerParsed = false;
private boolean bodyParsed = false;
private final String remoteAddrHeader;
private final String localHeader;
private final String localParameter;
final HttpRpcAuthenticator rpcAuthenticator;
HttpServlet.ActionEntry actionEntry; //仅供HttpServlet传递Entry使用
public HttpRequest(HttpContext context) {
this(context, new ByteArray());
}
protected HttpRequest(HttpContext context, ByteArray array) {
super(context);
this.array = array;
this.remoteAddrHeader = context.remoteAddrHeader;
this.localHeader = context.localHeader;
this.localParameter = context.localParameter;
this.rpcAuthenticator = context.rpcAuthenticator;
}
@SuppressWarnings("OverridableMethodCallInConstructor")
protected HttpRequest(HttpContext context, HttpSimpleRequest req) {
super(context);
this.array = new ByteArray();
this.remoteAddrHeader = null;
this.localHeader = null;
this.localParameter = null;
this.rpcAuthenticator = null;
if (req != null) {
initSimpleRequest(req, true);
}
}
protected HttpRequest initSimpleRequest(HttpSimpleRequest req, boolean needPath) {
if (req != null) {
this.rpc = req.rpc;
this.traceid = req.traceid;
if (req.getBody() != null) {
this.array.put(req.getBody());
}
if (req.getHeaders() != null) {
this.headers.setAll(req.getHeaders());
}
this.reqConvertType = req.getReqConvertType();
this.reqConvert = req.getReqConvertType() == null ? null : ConvertFactory.findConvert(req.getReqConvertType());
this.respConvertType = req.getRespConvertType();
this.respConvert = req.getRespConvertType() == null ? null : ConvertFactory.findConvert(req.getRespConvertType());
if (req.getParams() != null) {
this.params.putAll(req.getParams());
}
if (req.getCurrentUserid() != null) {
this.currentUserid = req.getCurrentUserid();
}
this.contentType = req.getContentType();
this.remoteAddr = req.getRemoteAddr();
this.locale = req.getLocale();
if (needPath) {
this.requestURI = (req.getPath() == null || req.getPath().isEmpty()) ? req.getRequestURI() : (req.getPath() + req.getRequestURI());
} else {
this.requestURI = req.getRequestURI();
}
this.method = req.getMethod();
if (req.getSessionid() != null && !req.getSessionid().isEmpty()) {
this.cookies = new HttpCookie[]{new HttpCookie(SESSIONID_NAME, req.getSessionid())};
}
}
return this;
}
public HttpSimpleRequest createSimpleRequest(String prefix) {
HttpSimpleRequest req = new HttpSimpleRequest();
req.setBody(array.length() == 0 ? null : array.getBytes());
if (!getHeaders().isEmpty()) {
req.setHeaders(headers);
if (headers.contains(Rest.REST_HEADER_RPC)) { //外部request不能包含RPC的header信息
req.removeHeader(Rest.REST_HEADER_RPC);
}
if (headers.contains(Rest.REST_HEADER_CURRUSERID)) { //外部request不能包含RPC的header信息
req.removeHeader(Rest.REST_HEADER_CURRUSERID);
}
}
parseBody();
req.setParams(params.isEmpty() ? null : params);
req.setRemoteAddr(getRemoteAddr());
req.setLocale(getLocale());
req.setContentType(getContentType());
req.setPath(prefix);
req.setMethod(this.method);
String uri = this.requestURI;
if (prefix != null && !prefix.isEmpty() && uri.startsWith(prefix)) {
uri = uri.substring(prefix.length());
}
req.setRequestURI(uri);
req.setSessionid(getSessionid(false));
req.setRpc(this.rpc);
req.setTraceid(this.traceid);
return req;
}
protected boolean isWebSocket() {
return maybews && getmethod && "Upgrade".equalsIgnoreCase(getHeader("Connection"));
}
protected boolean isExpect() {
return expect;
}
protected void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}
protected ConvertType getRespConvertType() {
return this.respConvertType;
}
protected Convert getRespConvert() {
return this.respConvert == null ? this.jsonConvert : this.respConvert;
}
@Override
protected int readHeader(final ByteBuffer buf, final Request last) {
final ByteBuffer buffer = buf;
ByteArray bytes = array;
if (this.readState == READ_STATE_ROUTE) {
int rs = readMethodUriLine(buffer);
if (rs != 0) {
return rs;
}
this.readState = READ_STATE_HEADER;
}
if (this.readState == READ_STATE_HEADER) {
if (last != null && ((HttpRequest) last).headerLength > 0) {
final HttpRequest httplast = (HttpRequest) last;
int bufremain = buffer.remaining();
int remainHalf = httplast.headerLength - this.headerHalfLen;
if (remainHalf > bufremain) {
bytes.put(buffer);
this.headerHalfLen += bufremain;
buffer.clear();
return 1;
}
buffer.position(buffer.position() + remainHalf);
this.contentType = httplast.contentType;
this.contentLength = httplast.contentLength;
this.host = httplast.host;
this.cookie = httplast.cookie;
this.cookies = httplast.cookies;
this.keepAlive = httplast.keepAlive;
this.maybews = httplast.maybews;
this.expect = httplast.expect;
this.rpc = httplast.rpc;
this.traceid = httplast.traceid;
this.currentUserid = httplast.currentUserid;
this.reqConvertType = httplast.reqConvertType;
this.reqConvert = httplast.reqConvert;
this.respConvertType = httplast.respConvertType;
this.respConvert = httplast.respConvert;
this.headerLength = httplast.headerLength;
this.headerHalfLen = httplast.headerHalfLen;
this.headerBytes = httplast.headerBytes;
this.headerParsed = httplast.headerParsed;
this.headers.setAll(httplast.headers);
} else if (context.lazyHeaders && getmethod) { //非GET必须要读header会有Content-Length
int rs = loadHeaderBytes(buffer);
if (rs != 0) {
buffer.clear();
return rs;
}
this.headerParsed = false;
} else {
int startpos = buffer.position();
int rs = readHeaderLines(buffer, bytes);
if (rs != 0) {
this.headerHalfLen = bytes.length();
buffer.clear();
return rs;
}
this.headerParsed = true;
this.headerLength = buffer.position() - startpos + this.headerHalfLen;
this.headerHalfLen = this.headerLength;
}
bytes.clear();
if (this.contentType != null && this.contentType.contains("boundary=")) {
this.boundary = true;
}
if (this.boundary) {
this.keepAlive = false; //文件上传必须设置keepAlive为false因为文件过大时用户不一定会skip掉多余的数据
}
this.readState = READ_STATE_BODY;
}
if (this.readState == READ_STATE_BODY) {
if (this.contentLength > 0 && (this.contentType == null || !this.boundary)) {
if (this.contentLength > context.getMaxBody()) {
return -1;
}
bytes.put(buffer, Math.min((int) this.contentLength, buffer.remaining()));
int lr = (int) this.contentLength - bytes.length();
if (lr == 0) {
this.readState = READ_STATE_END;
if (bytes.isEmpty()) {
this.bodyParsed = true; //no body data
}
} else {
buffer.clear();
}
return lr > 0 ? lr : 0;
}
if (buffer.hasRemaining() && (this.boundary || !this.keepAlive)) {
bytes.put(buffer, buffer.remaining()); //文件上传、HTTP1.0或Connection:close
}
this.readState = READ_STATE_END;
if (bytes.isEmpty()) {
this.bodyParsed = true; //no body data
}
}
//暂不考虑是keep-alive且存在body却没有指定Content-Length的情况
return 0;
}
private int loadHeaderBytes(final ByteBuffer buf) {
final ByteBuffer buffer = buf;
ByteArray bytes = array;
int remain = buffer.remaining();
byte b1, b2, b3, b4;
for (;;) {
if (remain-- < 4) { //bytes不存放\r\n\r\n这4个字节
bytes.put(buffer);
buffer.clear();
if (bytes.length() > 0) {
byte rn1 = 0, rn2 = 0, rn3 = 0;
byte b = bytes.getLastByte();
if (b == '\r' || b == '\n') {
rn3 = b;
bytes.backCount();
if (bytes.length() > 0) {
b = bytes.getLastByte();
if (b == '\r' || b == '\n') {
rn2 = b;
bytes.backCount();
if (bytes.length() > 0) {
b = bytes.getLastByte();
if (b == '\r' || b == '\n') {
rn1 = b;
bytes.backCount();
}
}
}
}
}
if (rn1 != 0) {
buffer.put(rn1);
}
if (rn2 != 0) {
buffer.put(rn2);
}
if (rn3 != 0) {
buffer.put(rn3);
}
}
return 1;
}
b1 = buffer.get();
bytes.put(b1);
if (b1 == '\r') {
remain--;
b2 = buffer.get();
bytes.put(b2);
if (b2 == '\n') {
remain--;
b3 = buffer.get();
bytes.put(b3);
if (b3 == '\r') {
remain--;
b4 = buffer.get();
bytes.put(b4);
if (b4 == '\n') {
this.headerBytes = Utility.append(this.headerBytes, bytes.content(), 0, bytes.length());
this.headerLength = this.headerBytes.length;
this.headerHalfLen = this.headerLength;
bytes.clear();
return 0;
}
}
}
}
}
}
//解析 GET /xxx HTTP/1.1
private int readMethodUriLine(final ByteBuffer buf) {
final ByteBuffer buffer = buf;
Charset charset = this.context.getCharset();
int remain = buffer.remaining();
int size;
ByteArray bytes = array;
//读method
if (this.method == null) {
boolean flag = false;
if (remain >= 5) {
byte b1 = buffer.get();
byte b2 = buffer.get();
if (b2 == ' ') {
remain -= 2;
this.method = Character.toString(b1);
this.getmethod = false;
} else {
byte b3 = buffer.get();
if (b3 == ' ') {
remain -= 3;
this.method = new String(new byte[]{b1, b2});
this.getmethod = false;
} else {
byte b4 = buffer.get();
if (b4 == ' ') {
remain -= 4;
if (b1 == 'G' && b2 == 'E' && b3 == 'T') {
this.method = METHOD_GET;
this.getmethod = true;
} else if (b1 == 'P' && b2 == 'U' && b3 == 'T') {
this.method = METHOD_PUT;
this.getmethod = false;
} else {
this.method = new String(new byte[]{b1, b2, b3});
this.getmethod = false;
}
} else {
byte b5 = buffer.get();
remain -= 5;
if (b5 == ' ') {
if (b1 == 'P' && b2 == 'O' && b3 == 'S' && b3 == 'T') {
this.method = METHOD_POST;
this.getmethod = false;
} else if (b1 == 'H' && b2 == 'E' && b3 == 'A' && b3 == 'D') {
this.method = METHOD_HEAD;
this.getmethod = false;
} else {
this.method = new String(new byte[]{b1, b2, b3, b4});
this.getmethod = false;
}
} else {
flag = true;
bytes.put(b1, b2, b3, b4, b5);
}
}
}
}
}
if (flag) {
for (;;) {
if (remain-- < 1) {
buffer.clear();
return 1;
}
byte b = buffer.get();
if (b == ' ') {
break;
}
bytes.put(b);
}
size = bytes.length();
byte[] content = bytes.content();
if (size == 3) {
if (content[0] == 'G' && content[1] == 'E' && content[2] == 'T') {
this.method = METHOD_GET;
this.getmethod = true;
} else if (content[0] == 'P' && content[1] == 'U' && content[2] == 'T') {
this.method = METHOD_PUT;
this.getmethod = false;
} else {
this.method = bytes.toString(true, charset);
this.getmethod = false;
}
} else if (size == 4) {
this.getmethod = false;
if (content[0] == 'P' && content[1] == 'O' && content[2] == 'S' && content[3] == 'T') {
this.method = METHOD_POST;
} else if (content[0] == 'H' && content[1] == 'E' && content[2] == 'A' && content[3] == 'D') {
this.method = METHOD_HEAD;
} else {
this.method = bytes.toString(true, charset);
}
} else if (size == 7) {
this.getmethod = false;
if (content[0] == 'O' && content[1] == 'P' && content[2] == 'T'
&& content[3] == 'I' && content[4] == 'O' && content[5] == 'N' && content[6] == 'S') {
this.method = METHOD_OPTIONS;
} else {
this.method = bytes.toString(true, charset);
}
} else {
this.method = bytes.toString(true, charset);
this.getmethod = false;
}
bytes.clear();
}
}
//读uri
if (this.requestURI == null) {
int qst = -1;//?的位置
boolean decodeable = false;
boolean latin1 = true;
for (;;) {
if (remain-- < 1) {
buffer.clear();
return 1;
}
byte b = buffer.get();
if (b == ' ') {
break;
}
if (b == '?' && qst < 0) {
qst = bytes.length();
} else if (!decodeable && (b == '+' || b == '%')) {
decodeable = true;
} else if (latin1 && (b < 0x20 || b >= 0x80)) {
latin1 = false;
}
bytes.put(b);
}
size = bytes.length();
if (qst > 0) { //带?参数
this.requestURI = decodeable ? toDecodeString(bytes, 0, qst, charset) : context.loadUriPath(bytes, qst, latin1, charset);// bytes.toString(latin1, 0, qst, charset);
int qlen = size - qst - 1;
this.queryBytes = bytes.getBytes(qst + 1, qlen);
this.lastRequestURIString = null;
this.lastRequestURIBytes = null;
try {
addParameter(bytes, false, qst + 1, qlen);
} catch (Exception e) {
this.context.getLogger().log(Level.WARNING, "HttpRequest.addParameter error: " + bytes.toString(), e);
}
} else {
if (decodeable) { //需要转义
this.requestURI = toDecodeString(bytes, 0, bytes.length(), charset);
this.lastRequestURIString = null;
this.lastRequestURIBytes = null;
} else if (context.lazyHeaders) {
byte[] lastURIBytes = lastRequestURIBytes;
if (lastURIBytes != null && lastURIBytes.length == size && bytes.deepEquals(lastURIBytes)) {
this.requestURI = this.lastRequestURIString;
} else {
this.requestURI = context.loadUriPath(bytes, latin1, charset);// bytes.toString(latin1, charset);
this.lastRequestURIString = this.requestURI;
this.lastRequestURIBytes = bytes.getBytes();
}
} else {
this.requestURI = context.loadUriPath(bytes, latin1, charset); //bytes.toString(latin1, charset);
this.lastRequestURIString = null;
this.lastRequestURIBytes = null;
}
this.queryBytes = EMPTY_BYTES;
}
bytes.clear();
}
//读protocol
for (;;) {
if (remain-- < 1) {
this.params.clear();
buffer.clear();
return 1;
}
byte b = buffer.get();
if (b == '\r') {
if (remain-- < 1) {
this.params.clear();
buffer.clear();
buffer.put(b);
return 1;
}
if (buffer.get() != '\n') {
return -1;
}
break;
}
bytes.put(b);
}
size = bytes.length();
byte[] content = bytes.content();
if (size == 8 && content[0] == 'H' && content[5] == '1' && content[7] == '1') {
this.protocol = HTTP_1_1;
} else if (size == 8 && content[0] == 'H' && content[5] == '2' && content[7] == '0') {
this.protocol = HTTP_2_0;
} else {
this.protocol = bytes.toString(true, charset);
}
bytes.clear();
return 0;
}
//解析Header Connection: keep-alive
private int readHeaderLines(final ByteBuffer buf, ByteArray bytes) {
final ByteBuffer buffer = buf;
Charset charset = this.context.getCharset();
int remain = buffer.remaining();
for (;;) {
bytes.clear();
if (remain-- < 2) {
if (remain == 1) {
byte one = buffer.get();
buffer.clear();
buffer.put(one);
return 1;
}
buffer.clear();
return 1;
}
remain--;
byte b1 = buffer.get();
byte b2 = buffer.get();
if (b1 == '\r' && b2 == '\n') {
return 0;
}
boolean latin1 = true;
if (latin1 && (b1 < 0x20 || b1 >= 0x80)) {
latin1 = false;
}
if (latin1 && (b2 < 0x20 || b2 >= 0x80)) {
latin1 = false;
}
bytes.put(b1, b2);
for (;;) { // name
if (remain-- < 1) {
buffer.clear();
buffer.put(bytes.content(), 0, bytes.length());
return 1;
}
byte b = buffer.get();
if (b == ':') {
break;
} else if (latin1 && (b < 0x20 || b >= 0x80)) {
latin1 = false;
}
bytes.put(b);
}
String name = parseHeaderName(latin1, bytes, charset);
bytes.clear();
boolean first = true;
int space = 0;
for (;;) { // value
if (remain-- < 1) {
buffer.clear();
buffer.put(name.getBytes());
buffer.put((byte) ':');
if (space == 1) {
buffer.put((byte) ' ');
} else if (space > 0) {
for (int i = 0; i < space; i++) buffer.put((byte) ' ');
}
buffer.put(bytes.content(), 0, bytes.length());
return 1;
}
byte b = buffer.get();
if (b == '\r') {
if (remain-- < 1) {
buffer.clear();
buffer.put(name.getBytes());
buffer.put((byte) ':');
if (space == 1) {
buffer.put((byte) ' ');
} else if (space > 0) {
for (int i = 0; i < space; i++) buffer.put((byte) ' ');
}
buffer.put(bytes.content(), 0, bytes.length());
buffer.put((byte) '\r');
return 1;
}
if (buffer.get() != '\n') {
return -1;
}
break;
}
if (first) {
if (b <= ' ') {
space++;
continue;
}
first = false;
}
bytes.put(b);
}
String value;
int vlen = bytes.length();
byte[] content = bytes.content();
switch (name) {
case HEAD_CONTENT_TYPE: //Content-Type
this.contentType = bytes.toString(true, charset);
break;
case HEAD_CONTENT_LENGTH: //Content-Length
this.contentLength = Long.decode(bytes.toString(true, charset));
break;
case HEAD_HOST: //Host
this.host = bytes.toString(charset);
break;
case HEAD_COOKIE: //Cookie
if (this.cookie == null || this.cookie.isEmpty()) {
this.cookie = bytes.toString(charset);
} else {
this.cookie += ";" + bytes.toString(charset);
}
break;
case HEAD_CONNECTION: //Connection
if (vlen > 0) {
if (vlen == 5 && content[0] == 'c'
&& content[1] == 'l' && content[2] == 'o'
&& content[3] == 's' && content[4] == 'e') {
value = "close";
this.setKeepAlive(false);
} else if (vlen == 10 && content[0] == 'k'
&& content[1] == 'e' && content[2] == 'e'
&& content[3] == 'p' && content[4] == '-'
&& content[5] == 'a' && content[6] == 'l'
&& content[7] == 'i' && content[8] == 'v'
&& content[9] == 'e') {
value = "keep-alive";
this.setKeepAlive(true);
} else {
value = bytes.toString(charset);
this.setKeepAlive(true);
}
} else {
value = "";
}
headers.setValid(HEAD_CONNECTION, value);
break;
case HEAD_UPGRADE: //Upgrade
this.maybews = vlen == 9 && content[0] == 'w' && content[1] == 'e' && content[2] == 'b' && content[3] == 's'
&& content[4] == 'o' && content[5] == 'c' && content[6] == 'k' && content[7] == 'e' && content[8] == 't';
headers.setValid(HEAD_UPGRADE, this.maybews ? "websocket" : bytes.toString(true, charset));
break;
case HEAD_EXPECT: //Expect
this.expect = vlen == 12 && content[0] == '1' && content[1] == '0' && content[2] == '0' && content[3] == '-'
&& content[4] == 'c' && content[5] == 'o' && content[6] == 'n' && content[7] == 't' && content[8] == 'i'
&& content[9] == 'n' && content[10] == 'u' && content[11] == 'e';
headers.setValid(HEAD_EXPECT, this.expect ? "100-continue" : bytes.toString(true, charset));
break;
case Rest.REST_HEADER_RPC: //rest-rpc
this.rpc = vlen == 4 && content[0] == 't' && content[1] == 'r' && content[2] == 'u' && content[3] == 'e';
headers.setValid(name, this.rpc ? "true"
: (vlen == 5 && content[0] == 'f' && content[1] == 'a' && content[2] == 'l' && content[3] == 's' && content[4] == 'e'
? "false" : bytes.toString(true, charset)));
break;
case Rest.REST_HEADER_TRACEID: //rest-traceid
value = bytes.toString(true, charset);
this.traceid = value;
headers.setValid(name, value);
break;
case Rest.REST_HEADER_CURRUSERID: //rest-curruserid
value = bytes.toString(true, charset);
this.currentUserid = value;
headers.setValid(name, value);
break;
case Rest.REST_HEADER_REQ_CONVERT: //rest-req-convert-type
value = bytes.toString(true, charset);
reqConvertType = ConvertType.valueOf(value);
reqConvert = ConvertFactory.findConvert(reqConvertType);
headers.setValid(name, value);
break;
case Rest.REST_HEADER_RESP_CONVERT: //rest-resp-convert-type
value = bytes.toString(true, charset);
respConvertType = ConvertType.valueOf(value);
respConvert = ConvertFactory.findConvert(respConvertType);
headers.setValid(name, value);
break;
default:
headers.addValid(name, bytes.toString(charset));
}
}
}
private void parseHeader() {
if (headerParsed) {
return;
}
headerParsed = true;
if (headerBytes == null) {
return;
}
if (array.isEmpty()) {
readHeaderLines(ByteBuffer.wrap(headerBytes), array);
array.clear();
} else { //array存有body数据
readHeaderLines(ByteBuffer.wrap(headerBytes), new ByteArray());
}
}
static String parseHeaderName(boolean latin1, ByteArray bytes, Charset charset) {
final int size = bytes.length();
final byte[] bs = bytes.content();
final byte first = bs[0];
if ((first == 'H' || first == 'h') && size == 4) { //Host
if (bs[1] == 'o' && bs[2] == 's' && bs[3] == 't') {
return HEAD_HOST;
}
} else if ((first == 'A' || first == 'a') && size == 6) { //Accept
if (bs[1] == 'c' && bs[2] == 'c' && bs[3] == 'e'
&& bs[4] == 'p' && bs[5] == 't') {
return HEAD_ACCEPT;
}
} else if (first == 'C' || first == 'c') {
if (size == 10) { //Connection
if (bs[1] == 'o' && bs[2] == 'n' && bs[3] == 'n'
&& bs[4] == 'e' && bs[5] == 'c' && bs[6] == 't'
&& bs[7] == 'i' && bs[8] == 'o' && bs[9] == 'n') {
return HEAD_CONNECTION;
}
} else if (size == 12) { //Content-Type
if (bs[1] == 'o' && bs[2] == 'n' && bs[3] == 't'
&& bs[4] == 'e' && bs[5] == 'n' && bs[6] == 't'
&& bs[7] == '-' && (bs[8] == 'T' || bs[8] == 't')
&& bs[9] == 'y' && bs[10] == 'p' && bs[11] == 'e') {
return HEAD_CONTENT_TYPE;
}
} else if (size == 14) { //Content-Length
if (bs[1] == 'o' && bs[2] == 'n' && bs[3] == 't'
&& bs[4] == 'e' && bs[5] == 'n' && bs[6] == 't'
&& bs[7] == '-' && (bs[8] == 'L' || bs[8] == 'l')
&& bs[9] == 'e' && bs[10] == 'n' && bs[11] == 'g'
&& bs[12] == 't'
&& bs[13] == 'h') {
return HEAD_CONTENT_LENGTH;
}
} else if (size == 6) { //Cookie
if (bs[1] == 'o' && bs[2] == 'o' && bs[3] == 'k'
&& bs[4] == 'i' && bs[5] == 'e') {
return HEAD_COOKIE;
}
}
} else if (first == 'U' || first == 'u') {
if (size == 7) { //Upgrade
if (bs[1] == 'p' && bs[2] == 'g' && bs[3] == 'r'
&& bs[4] == 'a' && bs[5] == 'd' && bs[6] == 'e') {
return HEAD_UPGRADE;
}
} else if (size == 10) { //User-Agent
if (bs[1] == 's' && bs[2] == 'e' && bs[3] == 'r'
&& bs[4] == '-' && (bs[5] == 'A' || bs[5] == 'a') && bs[6] == 'g'
&& bs[7] == 'e' && bs[8] == 'n' && bs[9] == 't') {
return HEAD_USER_AGENT;
}
}
} else if ((first == 'E' || first == 'e') && size == 6) { //Expect
if (bs[1] == 'x' && bs[2] == 'p' && bs[3] == 'e'
&& bs[4] == 'c' && bs[5] == 't') {
return HEAD_EXPECT;
}
}
return bytes.toString(latin1, charset);
}
@Override
protected HttpRequest copyHeader() {
if (!PIPELINE_SAME_HEADERS || !context.lazyHeaders) {
return null;
}
HttpRequest req = new HttpRequest(context, this.array);
req.headerLength = this.headerLength;
req.headerBytes = this.headerBytes;
req.headerParsed = this.headerParsed;
req.contentType = this.contentType;
req.contentLength = this.contentLength;
req.host = this.host;
req.cookie = this.cookie;
req.cookies = this.cookies;
req.keepAlive = this.keepAlive;
req.maybews = this.maybews;
req.expect = this.expect;
req.rpc = this.rpc;
req.traceid = this.traceid;
req.currentUserid = this.currentUserid;
req.currentUserSupplier = this.currentUserSupplier;
req.reqConvertType = this.reqConvertType;
req.reqConvert = this.reqConvert;
req.respConvert = this.respConvert;
req.respConvertType = this.respConvertType;
req.headers.setAll(this.headers);
return req;
}
@Override
protected Serializable getRequestid() {
return null;
}
@Override
protected void prepare() {
this.keepAlive = true; //默认HTTP/1.1
}
@Override
protected void recycle() {
//header
this.headerLength = 0;
this.headerHalfLen = 0;
this.headerBytes = null;
this.headerParsed = false;
this.contentType = null;
this.contentLength = -1;
this.host = null;
this.cookie = null;
this.cookies = null;
this.maybews = false;
this.expect = false;
this.rpc = false;
this.readState = READ_STATE_ROUTE;
this.currentUserid = CURRUSERID_NIL;
this.currentUserSupplier = null;
this.reqConvertType = null;
this.reqConvert = null;
this.respConvert = jsonConvert;
this.respConvertType = null;
this.headers.clear();
//其他
this.newSessionid = null;
this.method = null;
this.getmethod = false;
this.protocol = null;
this.requestURI = null;
this.queryBytes = null;
this.boundary = false;
this.bodyParsed = false;
this.moduleid = 0;
this.actionid = 0;
this.annotations = null;
this.remoteAddr = null;
this.params.clear();
this.array.clear();
//内部
this.actionEntry = null;
super.recycle();
}
protected void skipBodyParse() {
this.bodyParsed = true;
}
private void parseBody() {
if (this.boundary || bodyParsed) {
return;
}
bodyParsed = true;
if (this.getContentType() != null && this.contentType.toLowerCase().contains("x-www-form-urlencoded")) {
addParameter(array, true, 0, array.length());
}
}
private void addParameter(final ByteArray array, final boolean body, final int offset, final int len) {
if (len < 1) {
return;
}
Charset charset = this.context.getCharset();
int limit = offset + len;
int keypos = array.indexOf(offset, limit, '=');
int valpos = array.indexOf(offset, limit, '&');
if (keypos <= 0 || (valpos >= 0 && valpos < keypos)) {
if (valpos > 0) {
addParameter(array, body, valpos + 1, limit - valpos - 1);
}
return;
}
String name = toDecodeString(array, offset, keypos - offset, charset);
if (body && !name.isEmpty() && name.charAt(0) == '<') {
return; //内容可能是xml格式; 如: <?xml version="1.0"
}
++keypos;
String value = toDecodeString(array, keypos, (valpos < 0) ? (limit - keypos) : (valpos - keypos), charset);
this.params.put(name, value);
if (valpos >= 0) {
addParameter(array, body, valpos + 1, limit - valpos - 1);
}
}
protected HttpRequest setMethod(String method) {
this.method = method;
this.getmethod = METHOD_GET.equalsIgnoreCase(method);
return this;
}
protected HttpRequest setRequestURI(String requestURI) {
this.requestURI = requestURI;
return this;
}
protected HttpRequest setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
return this;
}
protected HttpRequest setLocale(String locale) {
this.locale = locale;
return this;
}
protected HttpRequest setParameter(String name, String value) {
this.params.put(name, value);
return this;
}
protected HttpRequest setHeader(String name, String value) {
this.headers.setValid(name, value);
return this;
}
protected HttpRequest addHeader(String name, String value) {
this.headers.add(name, value);
return this;
}
protected HttpRequest removeParameter(String name) {
this.params.remove(name);
return this;
}
protected HttpRequest removeHeader(String name) {
this.headers.remove(name);
return this;
}
protected static String toDecodeString(ByteArray array, int offset, int len, final Charset charset) {
byte[] content = array.content();
if (len == 1) {
return Character.toString(content[offset]);
} else if (len == 2 && content[offset] >= 0x20 && content[offset] < 0x80) {
return new String(content, 0, offset, len);
} else if (len == 3 && content[offset + 1] >= 0x20 && content[offset + 1] < 0x80) {
return new String(content, 0, offset, len);
}
int start = offset;
final int end = offset + len;
boolean flag = false; //是否需要转义
byte[] bs = content;
for (int i = offset; i < end; i++) {
if (content[i] == '+' || content[i] == '%') {
flag = true;
break;
}
}
if (flag) {
int index = 0;
bs = new byte[len];
for (int i = offset; i < end; i++) {
switch (content[i]) {
case '+':
bs[index] = ' ';
break;
case '%':
bs[index] = (byte) ((hexBit(content[++i]) * 16 + hexBit(content[++i])));
break;
default:
bs[index] = content[i];
break;
}
index++;
}
start = 0;
len = index;
}
return new String(bs, start, len, charset == null ? StandardCharsets.UTF_8 : charset);
}
private static int hexBit(byte b) {
if ('0' <= b && '9' >= b) {
return b - '0';
}
if ('a' <= b && 'z' >= b) {
return b - 'a' + 10;
}
if ('A' <= b && 'Z' >= b) {
return b - 'A' + 10;
}
return b;
}
@Override
protected <T> T setProperty(String name, T value) {
return super.setProperty(name, value);
}
@Override
@SuppressWarnings("unchecked")
protected <T> T getProperty(String name) {
return super.getProperty(name);
}
@Override
protected <T> T removeProperty(String name) {
return super.removeProperty(name);
}
/**
* 设置当前用户ID, 通常在HttpServlet.preExecute方法里设置currentUserid <br>
* 数据类型只能是int、long、String、JavaBean
*
* @param <T> 泛型
* @param userid 用户ID
*
* @return HttpRequest
*
* @since 2.1.0
*/
public <T extends Serializable> HttpRequest setCurrentUserid(T userid) {
this.currentUserid = userid;
return this;
}
/**
* 获取当前用户ID的int值<br>
*
* @return 用户ID
*
* @since 2.4.0
*/
@AsmDepends
@SuppressWarnings("unchecked")
public int currentIntUserid() {
if (currentUserid == CURRUSERID_NIL || currentUserid == null) {
return 0;
}
if (this.currentUserid instanceof Number) {
return ((Number) this.currentUserid).intValue();
}
String uid = this.currentUserid.toString();
return uid.isEmpty() ? 0 : Integer.parseInt(uid);
}
/**
* 获取当前用户ID的long值<br>
*
* @return 用户ID
*
* @since 2.7.0
*/
@AsmDepends
@SuppressWarnings("unchecked")
public long currentLongUserid() {
if (currentUserid == CURRUSERID_NIL || currentUserid == null) {
return 0L;
}
if (this.currentUserid instanceof Number) {
return ((Number) this.currentUserid).longValue();
}
String uid = this.currentUserid.toString();
return uid.isEmpty() ? 0L : Long.parseLong(uid);
}
/**
* 获取当前用户ID的String值<br>
*
* @return 用户ID
*
* @since 2.8.0
*/
@AsmDepends
@SuppressWarnings("unchecked")
public String currentStringUserid() {
if (currentUserid == CURRUSERID_NIL || currentUserid == null) {
return null;
}
return this.currentUserid.toString();
}
/**
* 获取当前用户ID<br>
*
* @param <T> 数据类型只能是int、long、String、JavaBean
* @param type 类型
*
* @return 用户ID
*
* @since 2.1.0
*/
@AsmDepends
@SuppressWarnings("unchecked")
public <T extends Serializable> T currentUserid(Class<T> type) {
if (currentUserid == CURRUSERID_NIL || currentUserid == null) {
if (type == int.class || type == Integer.class) {
return (T) (Integer) (int) 0;
}
if (type == long.class || type == Long.class) {
return (T) (Long) (long) 0;
}
return null;
}
if (type == int.class || type == Integer.class) {
if (this.currentUserid instanceof Number) {
return (T) (Integer) ((Number) this.currentUserid).intValue();
}
String uid = this.currentUserid.toString();
return (T) (Integer) (uid.isEmpty() ? 0 : Integer.parseInt(uid));
}
if (type == long.class || type == Long.class) {
if (this.currentUserid instanceof Number) {
return (T) (Long) ((Number) this.currentUserid).longValue();
}
String uid = this.currentUserid.toString();
return (T) (Long) (uid.isEmpty() ? 0L : Long.parseLong(uid));
}
if (type == String.class) {
return (T) this.currentUserid.toString();
}
if (this.currentUserid instanceof CharSequence) {
return JsonConvert.root().convertFrom(type, this.currentUserid.toString());
}
return (T) this.currentUserid;
}
/**
* 建议使用 setCurrentUserid, 通过userid从Service或缓存中获取用户信息<br>
* 设置当前用户信息, 通常在HttpServlet.preExecute方法里设置currentUser <br>
* 数据类型由&#64;HttpUserType指定
*
* @param supplier currentUser对象方法
*
* @since 2.4.0
*
* @return HttpRequest
*/
public HttpRequest setCurrentUserSupplier(Supplier supplier) {
this.currentUserSupplier = supplier;
return this;
}
/**
* 建议使用 currentUserid, 通过userid从Service或缓存中获取用户信息<br>
* 获取当前用户信息<br>
* 数据类型由&#64;HttpUserType指定
*
* @param <T> &#64;HttpUserType指定的用户信息类型
*
* @return 用户信息
*/
@SuppressWarnings("unchecked")
public <T> T currentUser() {
Supplier<Serializable> supplier = this.currentUserSupplier;
return (T) (supplier == null ? null : supplier.get());
}
/**
* 获取模块ID来自&#64;HttpServlet.moduleid()
*
* @return 模块ID
*/
@ConvertDisabled
public int getModuleid() {
return this.moduleid;
}
/**
* 获取操作ID来自&#64;HttpMapping.actionid()
*
* @return 模块ID
*/
@ConvertDisabled
public int getActionid() {
return this.actionid;
}
/**
* 获取当前操作Method上的注解集合
*
* @return Annotation[]
*/
@ConvertDisabled
public Annotation[] getAnnotations() {
if (this.annotations == null) {
return new Annotation[0];
}
Annotation[] newanns = new Annotation[this.annotations.length];
System.arraycopy(this.annotations, 0, newanns, 0, newanns.length);
return newanns;
}
/**
* 获取当前操作Method上的注解
*
* @param <T> 注解泛型
* @param annotationClass 注解类型
*
* @return Annotation
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (this.annotations == null) {
return null;
}
for (Annotation ann : this.annotations) {
if (ann.getClass() == annotationClass) {
return (T) ann;
}
}
return null;
}
/**
* 获取当前操作Method上的注解集合
*
* @param <T> 注解泛型
* @param annotationClass 注解类型
*
* @return Annotation[]
*/
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
if (this.annotations == null) {
return Creator.newArray(annotationClass, 0);
}
T[] news = Creator.newArray(annotationClass, this.annotations.length);
int index = 0;
for (Annotation ann : this.annotations) {
if (ann.getClass() == annotationClass) {
news[index++] = (T) ann;
}
}
if (index < 1) {
return Creator.newArray(annotationClass, 0);
}
return Arrays.copyOf(news, index);
}
/**
* 获取客户端地址IP
*
* @return 地址
*/
@ConvertDisabled
public SocketAddress getRemoteAddress() {
return this.channel == null || !this.channel.isOpen() ? null : this.channel.getRemoteAddress();
}
/**
* 获取客户端地址IP, 与getRemoteAddress() 的区别在于本方法优先取header中指定为RemoteAddress名的值没有则返回getRemoteAddress()的getHostAddress()。<br>
* 本方法适用于服务前端有如nginx的代理服务器进行中转通过 getRemoteAddress()是获取不到客户端的真实IP。
*
* @return 地址
*/
public String getRemoteAddr() {
if (this.remoteAddr != null) {
return this.remoteAddr;
}
parseHeader();
if (remoteAddrHeader != null) {
String val = getHeader(remoteAddrHeader);
if (val != null) {
this.remoteAddr = val;
return val;
}
}
SocketAddress addr = getRemoteAddress();
if (addr == null) {
return "";
}
if (addr instanceof InetSocketAddress) {
this.remoteAddr = ((InetSocketAddress) addr).getAddress().getHostAddress();
return this.remoteAddr;
}
this.remoteAddr = String.valueOf(addr);
return this.remoteAddr;
}
/**
* 获取国际化Locale值可以取之于header或parameter
*
* @return 国际化Locale
*/
public String getLocale() {
if (this.locale != null) {
return this.locale;
}
if (localHeader != null) {
String val = getHeader(localHeader);
if (val != null) {
this.locale = val;
return val;
}
}
if (localParameter != null) {
String val = getParameter(localParameter);
if (val != null) {
this.locale = val;
return val;
}
}
return this.locale;
}
/**
* 获取请求内容指定的编码字符串
*
* @param charset 编码
*
* @return 内容
*/
public String getBody(final Charset charset) {
return charset == null ? array.toString() : array.toString(charset);
}
/**
* 获取请求内容的UTF-8编码字符串
*
* @return 内容
*/
@ConvertDisabled
public String getBodyUTF8() {
return array.toString(StandardCharsets.UTF_8);
}
/**
* 获取请求内容的JavaBean对象
*
* @param <T> 泛型
* @param type 类型
*
* @return 内容
*/
public <T> T getBodyJson(java.lang.reflect.Type type) {
if (array == null || array.isEmpty()) {
return null;
}
Convert convert = this.reqConvert;
if (convert == null) {
convert = context.getJsonConvert();
}
if (type == byte[].class) {
return (T) array.getBytes();
}
return (T) convert.convertFrom(type, array.content());
}
/**
* 获取请求内容的JavaBean对象
*
* @param <T> 泛型
* @param convert Convert
* @param type 类型
*
* @return 内容
*/
public <T> T getBodyJson(Convert convert, java.lang.reflect.Type type) {
if (array.isEmpty()) {
return null;
}
if (type == byte[].class) {
return (T) array.getBytes();
}
return (T) convert.convertFrom(type, array.content());
}
/**
* 获取请求内容的byte[]
*
* @return 内容
*/
public byte[] getBody() {
return array.length() == 0 ? null : array.getBytes();
}
/**
* 直接获取body对象
*
* @return body对象
*/
@ConvertDisabled
protected ByteArray getDirectBody() {
return array;
}
@Override
public String toString() {
parseBody();
return this.getClass().getSimpleName() + "{\r\n method: " + this.method + ", \r\n requestURI: " + this.requestURI
+ (this.reqConvertType != null ? (", \r\n reqConvertType: " + this.reqConvertType) : "")
+ (this.respConvertType != null ? (", \r\n respConvertType: " + this.respConvertType) : "")
+ (this.currentUserid != CURRUSERID_NIL ? (", \r\n currentUserid: " + (this.currentUserid == CURRUSERID_NIL ? null : this.currentUserid)) : "")
+ (this.getRemoteAddr() != null ? (", \r\n remoteAddr: " + this.getRemoteAddr()) : "")
+ (this.cookie != null ? (", \r\n cookies: " + this.cookie) : "")
+ (this.getContentType() != null ? (", \r\n contentType: " + this.contentType) : "")
+ (this.protocol != null ? (", \r\n protocol: " + this.protocol) : "")
+ (this.getHost() != null ? (", \r\n host: " + this.host) : "")
+ (this.getContentLength() >= 0 ? (", \r\n contentLength: " + this.contentLength) : "")
+ (this.array.length() > 0 ? (", \r\n bodyLength: " + this.array.length()) : "")
+ (this.boundary || this.array.isEmpty() ? "" : (", \r\n bodyContent: " + (this.respConvertType == null || this.respConvertType == ConvertType.JSON ? this.getBodyUTF8() : Arrays.toString(getBody()))))
+ ", \r\n params: " + toMapString(this.params.map, 4)
+ ", \r\n header: " + toMapString(this.headers.map, 4)
+ "\r\n}"; //this.headers.toString(4)
}
private static CharSequence toMapString(Map<String, ?> map, int indent) {
final String space = " ".repeat(indent);
StringBuilder sb = new StringBuilder();
sb.append("{\r\n");
if (map != null) {
for (Map.Entry en : map.entrySet()) {
Object val = en.getValue();
if (val instanceof Collection) {
for (Object item : (Collection) val) {
sb.append(space).append(" '").append(en.getKey()).append("': '").append(item).append("',\r\n");
}
} else {
sb.append(space).append(" '").append(en.getKey()).append("': '").append(val).append("',\r\n");
}
}
}
sb.append(space).append('}');
return sb;
}
/**
* 获取文件上传对象
*
* @return 文件上传对象
*/
@ConvertDisabled
public final MultiContext getMultiContext() {
final InputStream in = newInputStream();
return new MultiContext(context.getCharset(), this.getContentType(), this.params.map(),
new BufferedInputStream(in, Math.max(array.length(), 8192)) {
{
array.copyTo(this.buf);
this.count = array.length();
}
}, null);
}
/**
* 是否上传文件请求
*
* @return boolean
*/
public final boolean isMultipart() {
return boundary;
}
/**
* 获取文件上传信息列表
*
* @return 文件上传对象集合
*
* @throws IOException IO异常
*/
@ConvertDisabled
public final Iterable<MultiPart> multiParts() throws IOException {
return getMultiContext().parts();
}
/**
* 获取sessionid
*
* @param autoCreate 无sessionid是否自动创建
*
* @return sessionid
*/
@ConvertDisabled
public String getSessionid(boolean autoCreate) {
String sessionid = getCookie(SESSIONID_NAME, null);
if (autoCreate && (sessionid == null || sessionid.isEmpty())) {
sessionid = context.createSessionid();
this.newSessionid = sessionid;
}
return sessionid;
}
/**
* 更新sessionid
*
* @return 新的sessionid值
*/
public String changeSessionid() {
this.newSessionid = context.createSessionid();
return newSessionid;
}
/**
* 指定值更新sessionid
*
* @param newSessionid 新sessionid值
*
* @return 新的sessionid值
*/
public String changeSessionid(String newSessionid) {
this.newSessionid = newSessionid == null ? context.createSessionid() : newSessionid.trim();
return newSessionid;
}
/**
* 使sessionid失效
*/
public void invalidateSession() {
this.newSessionid = ""; //为空表示删除sessionid
}
/**
* 获取所有Cookie对象
*
* @return cookie对象数组
*/
public HttpCookie[] getCookies() {
parseHeader();
if (this.cookies == null) {
this.cookies = parseCookies(this.cookie);
}
return this.cookies.length == 0 ? null : this.cookies;
}
/**
* 获取Cookie值
*
* @param name cookie名
*
* @return cookie值
*/
public String getCookie(String name) {
return getCookie(name, null);
}
/**
* 获取Cookie值 没有返回默认值
*
* @param name cookie名
* @param dfvalue 默认cookie值
*
* @return cookie值
*/
public String getCookie(String name, String dfvalue) {
HttpCookie[] cs = getCookies();
if (cs == null) {
return dfvalue;
}
for (HttpCookie c : cs) {
if (name.equals(c.getName())) {
return c.getValue();
}
}
return dfvalue;
}
private static HttpCookie[] parseCookies(String cookiestr) {
if (cookiestr == null || cookiestr.isEmpty()) {
return new HttpCookie[0];
}
String str = cookiestr.replaceAll("(^;)|(;$)", "").replaceAll(";+", ";");
if (str.isEmpty()) {
return new HttpCookie[0];
}
String[] strs = str.split(";");
HttpCookie[] cookies = new HttpCookie[strs.length];
for (int i = 0; i < strs.length; i++) {
String s = strs[i];
int pos = s.indexOf('=');
String v = (pos < 0 ? "" : s.substring(pos + 1));
if (v.indexOf('"') == 0 && v.lastIndexOf('"') == v.length() - 1) {
v = v.substring(1, v.length() - 1);
}
cookies[i] = new HttpCookie((pos < 0 ? s : s.substring(0, pos)), v);
}
return cookies;
}
/**
* 获取协议名 http、https、ws、wss等
*
* @return protocol
*/
public String getProtocol() {
return protocol;
}
/**
* 获取请求方法 GET、POST等
*
* @return method
*/
public String getMethod() {
return method;
}
/**
* 获取Content-Type的header值
*
* @return contentType
*/
public String getContentType() {
if (contentType == null) {
parseHeader();
}
return contentType;
}
/**
* 获取请求内容的长度, 为-1表示内容长度不确定
*
* @return 内容长度
*/
public long getContentLength() {
if (contentLength < 1) {
parseHeader();
}
return contentLength;
}
/**
* 获取Host的Header值
*
* @return Host
*/
public String getHost() {
if (host == null) {
parseHeader();
}
return host;
}
/**
* 获取请求的URL
*
* @return 请求的URL
*/
public String getRequestURI() {
return requestURI;
}
/**
* 获取请求参数的byte[]
*
* @return byte[]
*/
public byte[] getQueryBytes() {
return queryBytes;
}
/**
* 截取getRequestURI最后的一个/后面的部分
*
* @return String
*/
@ConvertDisabled
public String getRequstURILastPath() {
if (requestURI == null) {
return "";
}
return requestURI.substring(requestURI.lastIndexOf('/') + 1);
}
/**
* 获取请求URL最后的一个/后面的部分的short值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: short type = request.getRequstURILastPath((short)0); //type = 2
*
* @param defvalue 默认short值
*
* @return short值
*/
public short getRequstURILastPath(short defvalue) {
String val = getRequstURILastPath();
if (val.isEmpty()) {
return defvalue;
}
try {
return Short.parseShort(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的short值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: short type = request.getRequstURILastPath(16, (short)0); //type = 2
*
* @param radix 进制数
* @param defvalue 默认short值
*
* @return short值
*/
public short getRequstURILastPath(int radix, short defvalue) {
String val = getRequstURILastPath();
if (val.isEmpty()) {
return defvalue;
}
try {
return Short.parseShort(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的int值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: int type = request.getRequstURILastPath(0); //type = 2
*
* @param defvalue 默认int值
*
* @return int值
*/
public int getRequstURILastPath(int defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Integer.parseInt(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的int值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: int type = request.getRequstURILastPath(16, 0); //type = 2
*
* @param radix 进制数
* @param defvalue 默认int值
*
* @return int值
*/
public int getRequstURILastPath(int radix, int defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Integer.parseInt(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的float值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: float type = request.getRequstURILastPath(0.0f); //type = 2.0f
*
* @param defvalue 默认float值
*
* @return float值
*/
public float getRequstURILastPath(float defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Float.parseFloat(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的int值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: long type = request.getRequstURILastPath(0L); //type = 2
*
* @param defvalue 默认long值
*
* @return long值
*/
public long getRequstURILastPath(long defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Long.parseLong(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的int值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: long type = request.getRequstURILastPath(16, 0L); //type = 2
*
* @param radix 进制数
* @param defvalue 默认long值
*
* @return long值
*/
public long getRequstURILastPath(int radix, long defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Long.parseLong(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL最后的一个/后面的部分的double值 <br>
* 例如请求URL /pipes/user/query/2 <br>
* 获取type参数: double type = request.getRequstURILastPath(0.0); //type = 2.0
*
* @param defvalue 默认double值
*
* @return double值
*/
public double getRequstURILastPath(double defvalue) {
String val = getRequstURILastPath();
try {
return val.isEmpty() ? defvalue : Double.parseDouble(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
*
* 从prefix之后截取getRequestURI再对"/"进行分隔
* <p>
* @param prefix 前缀
*
* @return String[]
*/
public String[] getRequstURIPaths(String prefix) {
if (requestURI == null || prefix == null) {
return new String[0];
}
return requestURI.substring(requestURI.indexOf(prefix) + prefix.length() + (prefix.endsWith("/") ? 0 : 1)).split("/");
}
/**
* 获取请求URL分段中含prefix段的值 <br>
* 例如请求URL /pipes/user/query/name:hello <br>
* 获取name参数: String name = request.getRequstURIPath("name:", "none");
*
* @param prefix prefix段前缀
* @param defvalue 默认值
*
* @return prefix截断后的值
*/
public String getRequstURIPath(String prefix, String defvalue) {
if (requestURI == null || prefix == null || prefix.isEmpty()) {
return defvalue;
}
int pos = requestURI.indexOf(prefix);
if (pos < 0) {
return defvalue;
}
String sub = requestURI.substring(pos + prefix.length());
pos = sub.indexOf('/');
return pos < 0 ? sub : sub.substring(0, pos);
}
/**
* 获取请求URL分段中含prefix段的short值 <br>
* 例如请求URL /pipes/user/query/type:10 <br>
* 获取type参数: short type = request.getRequstURIPath("type:", (short)0);
*
* @param prefix prefix段前缀
* @param defvalue 默认short值
*
* @return short值
*/
public short getRequstURIPath(String prefix, short defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Short.parseShort(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的short值 <br>
* 例如请求URL /pipes/user/query/type:a <br>
* 获取type参数: short type = request.getRequstURIPath(16, "type:", (short)0); //type = 10
*
* @param radix 进制数
* @param prefix prefix段前缀
* @param defvalue 默认short值
*
* @return short值
*/
public short getRequstURIPath(int radix, String prefix, short defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Short.parseShort(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的int值 <br>
* 例如请求URL /pipes/user/query/offset:0/limit:50 <br>
* 获取offset参数: int offset = request.getRequstURIPath("offset:", 0); <br>
* 获取limit参数: int limit = request.getRequstURIPath("limit:", 20); <br>
*
* @param prefix prefix段前缀
* @param defvalue 默认int值
*
* @return int值
*/
public int getRequstURIPath(String prefix, int defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Integer.parseInt(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的int值 <br>
* 例如请求URL /pipes/user/query/offset:0/limit:50 <br>
* 获取offset参数: int offset = request.getRequstURIPath("offset:", 0); <br>
* 获取limit参数: int limit = request.getRequstURIPath(16, "limit:", 20); // limit = 16 <br>
*
* @param radix 进制数
* @param prefix prefix段前缀
* @param defvalue 默认int值
*
* @return int值
*/
public int getRequstURIPath(int radix, String prefix, int defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Integer.parseInt(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的float值 <br>
* 例如请求URL /pipes/user/query/point:40.0 <br>
* 获取time参数: float point = request.getRequstURIPath("point:", 0.0f);
*
* @param prefix prefix段前缀
* @param defvalue 默认float值
*
* @return float值
*/
public float getRequstURIPath(String prefix, float defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Float.parseFloat(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的long值 <br>
* 例如请求URL /pipes/user/query/time:1453104341363/id:40 <br>
* 获取time参数: long time = request.getRequstURIPath("time:", 0L);
*
* @param prefix prefix段前缀
* @param defvalue 默认long值
*
* @return long值
*/
public long getRequstURIPath(String prefix, long defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Long.parseLong(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的long值 <br>
* 例如请求URL /pipes/user/query/time:1453104341363/id:40 <br>
* 获取time参数: long time = request.getRequstURIPath(16, "time:", 0L);
*
* @param radix 进制数
* @param prefix prefix段前缀
* @param defvalue 默认long值
*
* @return long值
*/
public long getRequstURIPath(int radix, String prefix, long defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Long.parseLong(val, radix);
} catch (NumberFormatException e) {
return defvalue;
}
}
/**
* 获取请求URL分段中含prefix段的double值 <br>
* 例如请求URL /pipes/user/query/point:40.0 <br>
* 获取time参数: double point = request.getRequstURIPath("point:", 0.0);
*
* @param prefix prefix段前缀
* @param defvalue 默认double值
*
* @return double值
*/
public double getRequstURIPath(String prefix, double defvalue) {
String val = getRequstURIPath(prefix, null);
try {
return val == null ? defvalue : Double.parseDouble(val);
} catch (NumberFormatException e) {
return defvalue;
}
}
//------------------------------------------------------------------------------
/**
* 获取请求Header总对象
*
* @return AnyValue
*/
@AsmDepends
public HttpHeaders getHeaders() {
parseHeader();
return headers;
}
/**
* 获取所有的header名
*
* @return header名数组
*/
@ConvertDisabled
public String[] getHeaderNames() {
parseHeader();
return headers.names();
}
/**
* 获取指定的header值
*
* @param name header名
*
* @return header值
*/
public String getHeader(String name) {
return getHeader(name, null);
}
/**
* 获取指定的header值, 没有返回默认值
*
* @param name header名
* @param defaultValue 默认值
*
* @return header值
*/
@AsmDepends
public String getHeader(String name, String defaultValue) {
parseHeader();
return headers.firstValue(name, defaultValue);
}
/**
* 获取指定的header的json值
*
* @param <T> 泛型
* @param type 反序列化的类名
* @param name header名
*
* @return header值
*/
@AsmDepends
public <T> T getJsonHeader(java.lang.reflect.Type type, String name) {
String v = getHeader(name);
return isEmpty(v) ? null : jsonConvert.convertFrom(type, v);
}
/**
* 获取指定的header的json值
*
* @param <T> 泛型
* @param convert JsonConvert对象
* @param type 反序列化的类名
* @param name header名
*
* @return header值
*/
@AsmDepends
public <T> T getJsonHeader(JsonConvert convert, java.lang.reflect.Type type, String name) {
String v = getHeader(name);
return isEmpty(v) ? null : convert.convertFrom(type, v);
}
/**
* 获取指定的header的boolean值, 没有返回默认boolean值
*
* @param name header名
* @param defaultValue 默认boolean值
*
* @return header值
*/
@AsmDepends
public boolean getBooleanHeader(String name, boolean defaultValue) {
String value = getHeader(name);
return isEmpty(value) ? defaultValue : Boolean.parseBoolean(value);
}
/**
* 获取指定的header的short值, 没有返回默认short值
*
* @param name header名
* @param defaultValue 默认short值
*
* @return header值
*/
@AsmDepends
public short getShortHeader(String name, short defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return Short.decode(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的short值, 没有返回默认short值
*
* @param radix 进制数
* @param name header名
* @param defaultValue 默认short值
*
* @return header值
*/
@AsmDepends
public short getShortHeader(int radix, String name, short defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return (radix == 10 ? Short.decode(value) : Short.parseShort(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的short值, 没有返回默认short值
*
* @param name header名
* @param defaultValue 默认short值
*
* @return header值
*/
@AsmDepends
public short getShortHeader(String name, int defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return (short) defaultValue;
}
try {
return Short.decode(value);
} catch (NumberFormatException e) {
return (short) defaultValue;
}
}
/**
* 获取指定的header的short值, 没有返回默认short值
*
* @param radix 进制数
* @param name header名
* @param defaultValue 默认short值
*
* @return header值
*/
@AsmDepends
public short getShortHeader(int radix, String name, int defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return (short) defaultValue;
}
try {
return (radix == 10 ? Short.decode(value) : Short.parseShort(value, radix));
} catch (NumberFormatException e) {
return (short) defaultValue;
}
}
/**
* 获取指定的header的int值, 没有返回默认int值
*
* @param name header名
* @param defaultValue 默认int值
*
* @return header值
*/
@AsmDepends
public int getIntHeader(String name, int defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的int值, 没有返回默认int值
*
* @param radix 进制数
* @param name header名
* @param defaultValue 默认int值
*
* @return header值
*/
@AsmDepends
public int getIntHeader(int radix, String name, int defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return (radix == 10 ? Integer.decode(value) : Integer.parseInt(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的long值, 没有返回默认long值
*
* @param name header名
* @param defaultValue 默认long值
*
* @return header值
*/
@AsmDepends
public long getLongHeader(String name, long defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return Long.decode(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的long值, 没有返回默认long值
*
* @param radix 进制数
* @param name header名
* @param defaultValue 默认long值
*
* @return header值
*/
@AsmDepends
public long getLongHeader(int radix, String name, long defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return (radix == 10 ? Long.decode(value) : Long.parseLong(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的float值, 没有返回默认float值
*
* @param name header名
* @param defaultValue 默认float值
*
* @return header值
*/
@AsmDepends
public float getFloatHeader(String name, float defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return Float.parseFloat(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的header的double值, 没有返回默认double值
*
* @param name header名
* @param defaultValue 默认double值
*
* @return header值
*/
@AsmDepends
public double getDoubleHeader(String name, double defaultValue) {
String value = getHeader(name);
if (isEmpty(value)) {
return defaultValue;
}
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
//------------------------------------------------------------------------------
/**
* 获取请求参数总对象
*
* @return AnyValue
*/
@AsmDepends
public HttpParameters getParameters() {
parseBody();
return params;
}
/**
* 将请求参数转换成String, 字符串格式为: bean1={}&amp;id=13&amp;name=xxx <br>
* 不会返回null没有参数返回空字符串
*
*
* @return String
*/
@ConvertDisabled
public String getParametersToString() {
return getParametersToString(null);
}
/**
* 将请求参数转换成String, 字符串格式为: bean1={}&amp;id=13&amp;name=xxx <br>
* 不会返回null没有参数返回空字符串
*
* @param prefix 拼接前缀, 如果无参数,返回的字符串不会含有拼接前缀
*
* @return String
*/
public String getParametersToString(String prefix) {
byte[] rbs = queryBytes;
if (rbs == null || rbs.length < 1) {
return "";
}
Charset charset = this.context.getCharset();
String str = charset == null ? new String(rbs, StandardCharsets.UTF_8) : new String(rbs, charset);
return (prefix == null) ? str : (prefix + str);
}
/**
* 获取所有参数名
*
* @return 参数名数组
*/
@ConvertDisabled
public String[] getParameterNames() {
parseBody();
return params.names();
}
/**
* 获取指定的参数值
*
* @param name 参数名
*
* @return 参数值
*/
public String getParameter(String name) {
parseBody();
return params.get(name);
}
/**
* 获取指定的参数值, 没有返回默认值
*
* @param name 参数名
* @param defaultValue 默认值
*
* @return 参数值
*/
public String getParameter(String name, String defaultValue) {
parseBody();
return params.get(name, defaultValue);
}
/**
* 获取指定的参数json值
*
* @param <T> 泛型
* @param type 反序列化的类名
* @param name 参数名
*
* @return 参数值
*/
public <T> T getJsonParameter(java.lang.reflect.Type type, String name) {
String v = getParameter(name);
return v == null || v.isEmpty() ? null : jsonConvert.convertFrom(type, v);
}
/**
* 获取指定的参数json值
*
* @param <T> 泛型
* @param convert JsonConvert对象
* @param type 反序列化的类名
* @param name 参数名
*
* @return 参数值
*/
public <T> T getJsonParameter(JsonConvert convert, java.lang.reflect.Type type, String name) {
String v = getParameter(name);
return v == null || v.isEmpty() ? null : convert.convertFrom(type, v);
}
/**
* 获取指定的参数boolean值, 没有返回默认boolean值
*
* @param name 参数名
* @param defaultValue 默认boolean值
*
* @return 参数值
*/
public boolean getBooleanParameter(String name, boolean defaultValue) {
parseBody();
String value = params.get(name);
return value == null || value.length() == 0 ? defaultValue : Boolean.parseBoolean(value);
}
/**
* 获取指定的参数short值, 没有返回默认short值
*
* @param name 参数名
* @param defaultValue 默认short值
*
* @return 参数值
*/
public short getShortParameter(String name, short defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Short.decode(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数short值, 没有返回默认short值
*
* @param radix 进制数
* @param name 参数名
* @param defaultValue 默认short值
*
* @return 参数值
*/
public short getShortParameter(int radix, String name, short defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return (radix == 10 ? Short.decode(value) : Short.parseShort(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数short值, 没有返回默认short值
*
* @param name 参数名
* @param defaultValue 默认short值
*
* @return 参数值
*/
public short getShortParameter(String name, int defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return (short) defaultValue;
}
try {
return Short.decode(value);
} catch (NumberFormatException e) {
return (short) defaultValue;
}
}
/**
* 获取指定的参数int值, 没有返回默认int值
*
* @param name 参数名
* @param defaultValue 默认int值
*
* @return 参数值
*/
public int getIntParameter(String name, int defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Integer.decode(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数int值, 没有返回默认int值
*
* @param radix 进制数
* @param name 参数名
* @param defaultValue 默认int值
*
* @return 参数值
*/
public int getIntParameter(int radix, String name, int defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return (radix == 10 ? Integer.decode(value) : Integer.parseInt(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数long值, 没有返回默认long值
*
* @param name 参数名
* @param defaultValue 默认long值
*
* @return 参数值
*/
public long getLongParameter(String name, long defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Long.decode(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数long值, 没有返回默认long值
*
* @param radix 进制数
* @param name 参数名
* @param defaultValue 默认long值
*
* @return 参数值
*/
public long getLongParameter(int radix, String name, long defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return (radix == 10 ? Long.decode(value) : Long.parseLong(value, radix));
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数float值, 没有返回默认float值
*
* @param name 参数名
* @param defaultValue 默认float值
*
* @return 参数值
*/
public float getFloatParameter(String name, float defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Float.parseFloat(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取指定的参数double值, 没有返回默认double值
*
* @param name 参数名
* @param defaultValue 默认double值
*
* @return 参数值
*/
public double getDoubleParameter(String name, double defaultValue) {
parseBody();
String value = params.get(name);
if (value == null || value.length() == 0) {
return defaultValue;
}
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 获取翻页对象 同 getFlipper("flipper", false, 0);
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper() {
return getFlipper(false, 0);
}
/**
* 获取翻页对象 同 getFlipper("flipper", autoCreate, 0);
*
* @param autoCreate 无参数时是否创建新Flipper对象
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(boolean autoCreate) {
return getFlipper(autoCreate, 0);
}
/**
* 获取翻页对象 同 getFlipper("flipper", false, maxLimit);
*
* @param maxLimit 最大行数, 小于1则值为Flipper.DEFAULT_LIMIT
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(int maxLimit) {
return getFlipper(false, maxLimit);
}
/**
* 获取翻页对象 同 getFlipper("flipper", autoCreate, maxLimit)
*
* @param autoCreate 无参数时是否创建新Flipper对象
* @param maxLimit 最大行数, 小于1则值为Flipper.DEFAULT_LIMIT
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(boolean autoCreate, int maxLimit) {
return getFlipper("flipper", autoCreate, maxLimit);
}
/**
* 获取翻页对象 https://redkale.org/pipes/users/list?flipper={'offset':0,'limit':20, 'sort':'createtime ASC'} <br>
*
*
* @param name Flipper对象的参数名默认为 "flipper"
* @param autoCreate 无参数时是否创建新Flipper对象
* @param maxLimit 最大行数, 小于1则值为Flipper.DEFAULT_LIMIT
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(String name, boolean autoCreate, int maxLimit) {
org.redkale.source.Flipper flipper = getJsonParameter(org.redkale.source.Flipper.class, name);
if (flipper == null) {
// if (maxLimit < 1) maxLimit = org.redkale.source.Flipper.DEFAULT_LIMIT;
// String limitstr = getParameter("limit");
// if (limitstr != null && !limitstr.isEmpty()) {
// String offsetstr = getParameter("offset");
// if (offsetstr != null && !offsetstr.isEmpty()) {
// int limit = Integer.parseInt(limitstr);
// int offset = Integer.parseInt(offsetstr);
// String sort = getParameter("sort");
// if (limit > maxLimit) limit = maxLimit;
// flipper = new org.redkale.source.Flipper(limit, offset, sort);
// }
// }
} else if (flipper.getLimit() < 1 || (maxLimit > 0 && flipper.getLimit() > maxLimit)) {
flipper.setLimit(maxLimit);
}
if (flipper != null || !autoCreate) {
return flipper;
}
if (maxLimit < 1) {
maxLimit = org.redkale.source.Flipper.DEFAULT_LIMIT;
}
return new org.redkale.source.Flipper(maxLimit);
}
}