优化HttpUtil
This commit is contained in:
parent
ebf0e4fef6
commit
07550a2287
@ -3,6 +3,8 @@ package com.foxinmy.weixin4j.dispatcher;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
@ -180,8 +182,11 @@ public class WeixinMessageDispatcher {
|
||||
if (alwaysResponse) {
|
||||
context.write(BlankResponse.global);
|
||||
} else {
|
||||
context.writeAndFlush(HttpUtil.createHttpResponse(NOT_FOUND))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
request.getProtocolVersion(), NOT_FOUND);
|
||||
HttpUtil.resolveHeaders(response);
|
||||
context.writeAndFlush(response).addListener(
|
||||
ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
package com.foxinmy.weixin4j.request;
|
||||
|
||||
import io.netty.handler.codec.DecoderResult;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpMessage;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -16,14 +23,21 @@ import com.foxinmy.weixin4j.util.AesToken;
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class WeixinRequest implements Serializable {
|
||||
public class WeixinRequest implements Serializable, HttpMessage {
|
||||
|
||||
private static final long serialVersionUID = -9157395300510879866L;
|
||||
|
||||
/**
|
||||
* 请求的表头
|
||||
*/
|
||||
private HttpHeaders headers;
|
||||
/**
|
||||
* 请求的方式
|
||||
*/
|
||||
private String method;
|
||||
private HttpMethod method;
|
||||
/**
|
||||
* 请求的URI
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
// 以下字段每次被动消息时都会带上
|
||||
/**
|
||||
@ -71,12 +85,16 @@ public class WeixinRequest implements Serializable {
|
||||
* url parameter
|
||||
*/
|
||||
private Map<String, List<String>> parameters;
|
||||
private DecoderResult decoderResult;
|
||||
private HttpVersion protocolVersion;
|
||||
|
||||
public WeixinRequest(String method, EncryptType encryptType,
|
||||
String echoStr, String timeStamp, String nonce, String signature,
|
||||
String msgSignature, String originalContent, String encryptContent,
|
||||
AesToken aesToken, Map<String, List<String>> parameters) {
|
||||
public WeixinRequest(HttpHeaders headers, HttpMethod method, String uri,
|
||||
EncryptType encryptType, String echoStr, String timeStamp,
|
||||
String nonce, String signature, String msgSignature,
|
||||
String originalContent, String encryptContent, AesToken aesToken) {
|
||||
this.headers = headers;
|
||||
this.method = method;
|
||||
this.uri = uri;
|
||||
this.encryptType = encryptType;
|
||||
this.echoStr = echoStr;
|
||||
this.timeStamp = timeStamp;
|
||||
@ -86,13 +104,16 @@ public class WeixinRequest implements Serializable {
|
||||
this.originalContent = originalContent;
|
||||
this.encryptContent = encryptContent;
|
||||
this.aesToken = aesToken;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
public HttpMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public String getEchoStr() {
|
||||
return echoStr;
|
||||
}
|
||||
@ -130,16 +151,47 @@ public class WeixinRequest implements Serializable {
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getParameters() {
|
||||
if (parameters == null) {
|
||||
this.parameters = new QueryStringDecoder(uri, true).parameters();
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderResult getDecoderResult() {
|
||||
return decoderResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDecoderResult(DecoderResult decoderResult) {
|
||||
this.decoderResult = decoderResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpVersion getProtocolVersion() {
|
||||
return protocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMessage setProtocolVersion(HttpVersion protocolVersion) {
|
||||
this.protocolVersion = protocolVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders headers() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeixinRequest [encryptContent=" + encryptContent
|
||||
+ ", encryptType=" + encryptType + ", echoStr=" + echoStr
|
||||
+ ", timeStamp=" + timeStamp + ", nonce=" + nonce
|
||||
+ ", signature=" + signature + ", originalContent="
|
||||
+ originalContent + ", method=" + method + ", aesToken="
|
||||
+ aesToken + ", parameters=" + parameters + "]";
|
||||
return "WeixinRequest [headers=" + headers + ", method=" + method
|
||||
+ ", uri=" + uri + ", echoStr=" + echoStr + ", timeStamp="
|
||||
+ timeStamp + ", nonce=" + nonce + ", signature=" + signature
|
||||
+ ", msgSignature=" + msgSignature + ", encryptType="
|
||||
+ encryptType + ", originalContent=" + originalContent
|
||||
+ ", encryptContent=" + encryptContent + ", aesToken="
|
||||
+ aesToken + ", decoderResult=" + decoderResult
|
||||
+ ", protocolVersion=" + protocolVersion + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.foxinmy.weixin4j.response;
|
||||
|
||||
|
||||
/**
|
||||
* 微信被动消息回复
|
||||
*
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.socket;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
@ -32,7 +31,7 @@ public class SingleResponseEncoder extends
|
||||
protected void encode(ChannelHandlerContext ctx, SingleResponse response,
|
||||
List<Object> out) throws WeixinException {
|
||||
String content = response.toContent();
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(content, OK,
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(content,
|
||||
ServerToolkits.CONTENTTYPE$TEXT_PLAIN));
|
||||
logger.info("encode single response:{}", content);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.socket;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
@ -46,9 +47,9 @@ public class WeixinMessageDecoder extends
|
||||
String messageContent = req.content().toString(ServerToolkits.UTF_8);
|
||||
QueryStringDecoder queryDecoder = new QueryStringDecoder(req.getUri(),
|
||||
true);
|
||||
String methodName = req.getMethod().name();
|
||||
HttpMethod method = req.getMethod();
|
||||
logger.info("decode request:{} use {} method invoking", req.getUri(),
|
||||
methodName);
|
||||
method);
|
||||
Map<String, List<String>> parameters = queryDecoder.parameters();
|
||||
EncryptType encryptType = parameters.containsKey("encrypt_type") ? EncryptType
|
||||
.valueOf(parameters.get("encrypt_type").get(0).toUpperCase())
|
||||
@ -86,8 +87,12 @@ public class WeixinMessageDecoder extends
|
||||
messageContent = MessageUtil.aesDecrypt(aesToken.getWeixinId(),
|
||||
aesToken.getAesKey(), encryptContent);
|
||||
}
|
||||
out.add(new WeixinRequest(methodName, encryptType, echoStr, timeStamp,
|
||||
nonce, signature, msgSignature, messageContent, encryptContent,
|
||||
aesToken, parameters));
|
||||
WeixinRequest request = new WeixinRequest(req.headers(), method,
|
||||
req.getUri(), encryptType, echoStr, timeStamp, nonce,
|
||||
signature, msgSignature, messageContent, encryptContent,
|
||||
aesToken);
|
||||
request.setDecoderResult(req.getDecoderResult());
|
||||
request.setProtocolVersion(req.getProtocolVersion());
|
||||
out.add(request);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,10 @@ import static io.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
@ -58,7 +61,7 @@ public class WeixinRequestHandler extends
|
||||
if (aesToken == null
|
||||
|| (ServerToolkits.isBlank(request.getSignature()) && ServerToolkits
|
||||
.isBlank(request.getMsgSignature()))) {
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(BAD_REQUEST))
|
||||
ctx.writeAndFlush(resolveResponse(BAD_REQUEST, request))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
}
|
||||
@ -66,7 +69,7 @@ public class WeixinRequestHandler extends
|
||||
* 公众平台:无论Get,Post都带signature参数,当开启aes模式时带msg_signature参数
|
||||
* 企业号:无论Get,Post都带msg_signature参数
|
||||
**/
|
||||
if (request.getMethod().equals(HttpMethod.GET.name())) {
|
||||
if (request.getMethod() == HttpMethod.GET) {
|
||||
if (!ServerToolkits.isBlank(request.getSignature())
|
||||
&& MessageUtil.signature(aesToken.getToken(),
|
||||
request.getTimeStamp(), request.getNonce()).equals(
|
||||
@ -83,15 +86,15 @@ public class WeixinRequestHandler extends
|
||||
aesToken.getAesKey(), request.getEchoStr())));
|
||||
return;
|
||||
}
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
ctx.writeAndFlush(resolveResponse(FORBIDDEN, request)).addListener(
|
||||
ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
} else if (request.getMethod().equals(HttpMethod.POST.name())) {
|
||||
} else if (request.getMethod() == HttpMethod.POST) {
|
||||
if (!ServerToolkits.isBlank(request.getSignature())
|
||||
&& !MessageUtil.signature(aesToken.getToken(),
|
||||
request.getTimeStamp(), request.getNonce()).equals(
|
||||
request.getSignature())) {
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN))
|
||||
ctx.writeAndFlush(resolveResponse(FORBIDDEN, request))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
}
|
||||
@ -100,18 +103,27 @@ public class WeixinRequestHandler extends
|
||||
request.getTimeStamp(), request.getNonce(),
|
||||
request.getEncryptContent()).equals(
|
||||
request.getMsgSignature())) {
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(FORBIDDEN))
|
||||
ctx.writeAndFlush(resolveResponse(FORBIDDEN, request))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(METHOD_NOT_ALLOWED))
|
||||
ctx.writeAndFlush(resolveResponse(METHOD_NOT_ALLOWED, request))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
}
|
||||
WeixinMessageTransfer messageTransfer = MessageTransferHandler
|
||||
.parser(request);
|
||||
ctx.channel().attr(ServerToolkits.MESSAGE_TRANSFER_KEY).set(messageTransfer);
|
||||
ctx.channel().attr(ServerToolkits.MESSAGE_TRANSFER_KEY)
|
||||
.set(messageTransfer);
|
||||
messageDispatcher.doDispatch(ctx, request, messageTransfer);
|
||||
}
|
||||
|
||||
private FullHttpResponse resolveResponse(HttpResponseStatus responseStatus,
|
||||
WeixinRequest request) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
request.getProtocolVersion(), responseStatus);
|
||||
HttpUtil.resolveHeaders(response);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.socket;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
@ -74,7 +73,7 @@ public class WeixinResponseEncoder extends
|
||||
encrtypt));
|
||||
content.append("</xml>");
|
||||
}
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(content.toString(), OK,
|
||||
ctx.writeAndFlush(HttpUtil.createHttpResponse(content.toString(),
|
||||
ServerToolkits.CONTENTTYPE$APPLICATION_XML));
|
||||
logger.info("{} encode weixin response:{}", encryptType, content);
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.DATE;
|
||||
@ -9,8 +8,6 @@ import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Values;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
@ -32,20 +29,6 @@ public class HttpUtil {
|
||||
private static String SERVER = "netty4";
|
||||
private static String WEIXIN4J = "weixin4j-server";
|
||||
|
||||
/**
|
||||
* 创建只有状态的HttpResponse响应
|
||||
*
|
||||
* @param status
|
||||
* 响应状态
|
||||
* @return HttpResponse
|
||||
*/
|
||||
public static HttpResponse createHttpResponse(HttpResponseStatus status) {
|
||||
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1,
|
||||
status);
|
||||
createHeaders(httpResponse);
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建有内容的HttpResponse响应
|
||||
*
|
||||
@ -55,28 +38,34 @@ public class HttpUtil {
|
||||
* 响应状态
|
||||
* @param contentType
|
||||
* 响应类型
|
||||
* @param request
|
||||
* 请求对象
|
||||
* @return HttpResponse
|
||||
*/
|
||||
public static HttpResponse createHttpResponse(String content,
|
||||
HttpResponseStatus status, String contentType) {
|
||||
FullHttpResponse httpResponse = null;
|
||||
|
||||
httpResponse = new DefaultFullHttpResponse(HTTP_1_1, status,
|
||||
Unpooled.copiedBuffer(content, ServerToolkits.UTF_8));
|
||||
String contentType) {
|
||||
FullHttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1,
|
||||
HttpResponseStatus.OK, Unpooled.copiedBuffer(content,
|
||||
ServerToolkits.UTF_8));
|
||||
httpResponse.headers().set(
|
||||
CONTENT_TYPE,
|
||||
String.format("%s;encoding=%s", contentType,
|
||||
ServerToolkits.UTF_8.displayName()));
|
||||
httpResponse.headers().set(CONTENT_LENGTH,
|
||||
content.getBytes(ServerToolkits.UTF_8).length);
|
||||
createHeaders(httpResponse);
|
||||
resolveHeaders(httpResponse);
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
private static void createHeaders(FullHttpResponse httpResponse) {
|
||||
public static void resolveHeaders(FullHttpResponse httpResponse) {
|
||||
/*if (HttpHeaders.isKeepAlive(httpRequest)) {
|
||||
httpResponse.headers().set(CONNECTION, Values.KEEP_ALIVE);
|
||||
}
|
||||
if (HttpHeaders.isTransferEncodingChunked(httpRequest)) {
|
||||
httpResponse.headers().set(TRANSFER_ENCODING, Values.CHUNKED);
|
||||
}*/
|
||||
httpResponse.headers().set(DATE, new Date());
|
||||
httpResponse.headers().set(HttpHeaders.Names.SERVER, SERVER);
|
||||
httpResponse.headers().set(SERVER, SERVER);
|
||||
httpResponse.headers()
|
||||
.set(USER_AGENT,
|
||||
String.format("%s/%s", WEIXIN4J,
|
||||
|
||||
@ -27,7 +27,7 @@ import com.foxinmy.weixin4j.util.ServerToolkits;
|
||||
*/
|
||||
public class MessagePush {
|
||||
|
||||
private final String server = "http://localhost:10003";
|
||||
private final String server = "http://localhost:30000";
|
||||
private final HttpClient httpClient;
|
||||
private final HttpPost httpPost;
|
||||
private final HttpGet httpGet;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user