新增@RequestParam、@RequestBody注解支持.
This commit is contained in:
@@ -28,6 +28,8 @@ import fun.asgc.neutrino.core.annotation.NonIntercept;
|
||||
import fun.asgc.neutrino.core.constant.MetaDataConstant;
|
||||
import fun.asgc.neutrino.core.context.ApplicationConfig;
|
||||
import fun.asgc.neutrino.core.util.*;
|
||||
import fun.asgc.neutrino.core.web.annotation.RequestBody;
|
||||
import fun.asgc.neutrino.core.web.annotation.RequestParam;
|
||||
import fun.asgc.neutrino.core.web.param.HttpContextHolder;
|
||||
import fun.asgc.neutrino.core.web.param.HttpRequestParser;
|
||||
import fun.asgc.neutrino.core.web.router.DefaultHttpRouter;
|
||||
@@ -41,6 +43,9 @@ import io.netty.handler.codec.http.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -73,9 +78,9 @@ public class HttpRequestHandler {
|
||||
}
|
||||
if (HttpRouterType.METHOD == httpRouteResult.getType()) {
|
||||
try {
|
||||
Object invokeResult = httpRouteResult.getMethod().invoke(httpRouteResult.getInstance());
|
||||
Object invokeResult = invoke(httpRouteResult.getInstance(), httpRouteResult.getMethod());
|
||||
String res = String.valueOf(invokeResult);
|
||||
if (!TypeUtil.isNormalBasicType(invokeResult.getClass())) {
|
||||
if (null != invokeResult && !TypeUtil.isNormalBasicType(invokeResult.getClass())) {
|
||||
res = JSONObject.toJSONString(invokeResult);
|
||||
}
|
||||
FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes()));
|
||||
@@ -109,6 +114,44 @@ public class HttpRequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private Object invoke(Object instance, Method method) throws InvocationTargetException, IllegalAccessException {
|
||||
Object[] params = new Object[method.getParameterCount()];
|
||||
if (method.getParameterCount() > 0) {
|
||||
for (int i = 0; i < method.getParameters().length; i++) {
|
||||
Parameter parameter = method.getParameters()[i];
|
||||
if (FullHttpRequest.class.isAssignableFrom(parameter.getType())) {
|
||||
params[i] = HttpContextHolder.getFullHttpRequest();
|
||||
} else if (HttpRequestParser.class.isAssignableFrom(parameter.getType())) {
|
||||
params[i] = HttpContextHolder.getHttpRequestParser();
|
||||
} else if (ChannelHandlerContext.class.isAssignableFrom(parameter.getType())) {
|
||||
params[i] = HttpContextHolder.getChannelHandlerContext();
|
||||
} else if (parameter.isAnnotationPresent(RequestBody.class)) {
|
||||
String bodyString = HttpContextHolder.getHttpRequestParser().getContentAsString();
|
||||
if (TypeUtil.isNormalBasicType(parameter.getType())) {
|
||||
params[i] = TypeUtil.conversion(bodyString, parameter.getType());
|
||||
}
|
||||
// TODO 实体转换
|
||||
} else if (parameter.isAnnotationPresent(RequestParam.class)) {
|
||||
RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
|
||||
if (StringUtil.isEmpty(requestParam.value())) {
|
||||
throw new RuntimeException(String.format("类:%s 方法:%s @RequestParam必须指定参数名称" ));
|
||||
}
|
||||
String val = HttpContextHolder.getHttpRequestParser().getParameter(requestParam.value());
|
||||
if (StringUtil.isEmpty(val)) {
|
||||
if (requestParam.required()) {
|
||||
throw new RuntimeException(String.format("类:%s 方法:%s 参数:%s 未指定" ));
|
||||
}
|
||||
params[i] = null;
|
||||
} else {
|
||||
params[i] = TypeUtil.conversion(val, parameter.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Object invokeResult = method.invoke(instance, params);
|
||||
return invokeResult;
|
||||
}
|
||||
|
||||
private void release() {
|
||||
HttpContextHolder.remove();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2022 aoshiguchen
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.web.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/7/23
|
||||
*/
|
||||
@Target({ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RequestBody {
|
||||
boolean required() default true;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2022 aoshiguchen
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.web.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/7/23
|
||||
*/
|
||||
@Target({ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RequestParam {
|
||||
String value() default "";
|
||||
boolean required() default true;
|
||||
}
|
||||
@@ -23,6 +23,8 @@ package fun.asgc.neutrino.core.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -46,4 +48,27 @@ public class ClassUtilTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() throws InvocationTargetException, IllegalAccessException {
|
||||
Method method = ReflectUtil.getMethods(Student.class).stream().filter(m -> m.getName().equals("say")).findFirst().get();
|
||||
Student student = new Student();
|
||||
method.invoke(student, new Object[]{"1", "2"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() throws InvocationTargetException, IllegalAccessException {
|
||||
Method method = ReflectUtil.getMethods(Student.class).stream().filter(m -> m.getName().equals("hello")).findFirst().get();
|
||||
Student student = new Student();
|
||||
method.invoke(student, new Object[0]);
|
||||
}
|
||||
|
||||
public static class Student {
|
||||
public void say(String msg1, String msg2) {
|
||||
System.out.println("msg1:" + msg1 + " msg2:" + msg2);
|
||||
}
|
||||
public void hello() {
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,14 +24,21 @@ package fun.asgc.neutrino.core.web.test1;
|
||||
import fun.asgc.neutrino.core.annotation.Autowired;
|
||||
import fun.asgc.neutrino.core.web.annotation.GetMapping;
|
||||
import fun.asgc.neutrino.core.web.annotation.RequestMapping;
|
||||
import fun.asgc.neutrino.core.web.annotation.RequestParam;
|
||||
import fun.asgc.neutrino.core.web.annotation.RestController;
|
||||
import fun.asgc.neutrino.core.web.param.HttpContextHolder;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/7/23
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/test1")
|
||||
public class TestController {
|
||||
@@ -43,4 +50,17 @@ public class TestController {
|
||||
System.out.println("拿到参数 a = " + HttpContextHolder.getHttpRequestParser().getParameterForInteger("a"));
|
||||
return testService.hello();
|
||||
}
|
||||
|
||||
@GetMapping("add")
|
||||
public Integer add(@RequestParam("x") int x, @RequestParam("y") int y) {
|
||||
log.info("另一种取参方式 msg:{}", HttpContextHolder.getHttpRequestParser().getParameterForString("msg"));
|
||||
return x + y;
|
||||
}
|
||||
|
||||
@GetMapping("hello2")
|
||||
public void hello2(ChannelHandlerContext context) {
|
||||
FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer("aoshiguchen".getBytes()));
|
||||
fullHttpResponse.headers().add(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON);
|
||||
context.writeAndFlush(fullHttpResponse).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user