Merge 80a1f205b5 into ca1ae1f4b6
This commit is contained in:
commit
14665ef49e
|
|
@ -25,16 +25,23 @@ import org.apache.dubbo.rpc.protocol.tri.rest.util.DefaultRestToolKit;
|
|||
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.ext.ParamConverter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
final class JaxrsRestToolKit extends DefaultRestToolKit {
|
||||
|
||||
private final BeanArgumentBinder binder;
|
||||
|
||||
private final ParamConverterFactory paramConverterFactory;
|
||||
|
||||
public JaxrsRestToolKit(FrameworkModel frameworkModel) {
|
||||
super(frameworkModel);
|
||||
binder = new BeanArgumentBinder(frameworkModel);
|
||||
paramConverterFactory = new ParamConverterFactory();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public Object convert(Object value, ParameterMeta parameter) {
|
||||
if (MultivaluedMap.class.isAssignableFrom(parameter.getType())) {
|
||||
|
|
@ -43,6 +50,19 @@ final class JaxrsRestToolKit extends DefaultRestToolKit {
|
|||
}
|
||||
return typeConverter.convert(value, MultivaluedHashMap.class);
|
||||
}
|
||||
|
||||
Optional<ParamConverter> optional = paramConverterFactory.getParamConverter(
|
||||
parameter.getType(), parameter.getGenericType(), parameter.getRealAnnotations());
|
||||
if (optional.isPresent()) {
|
||||
ParamConverter paramConverter = optional.get();
|
||||
Object result = value.getClass() == String.class
|
||||
? paramConverter.fromString((String) value)
|
||||
: paramConverter.toString(value);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return super.convert(value, parameter);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs;
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.Pair;
|
||||
|
||||
import javax.ws.rs.ext.ParamConverter;
|
||||
import javax.ws.rs.ext.ParamConverterProvider;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_ERROR_LOAD_EXTENSION;
|
||||
|
||||
@SuppressWarnings({"rawtypes"})
|
||||
public class ParamConverterFactory {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger =
|
||||
LoggerFactory.getErrorTypeAwareLogger(ParamConverterFactory.class);
|
||||
private final Map<Pair<Pair<Class<?>, Type>, Annotation[]>, Optional<ParamConverter>> cache =
|
||||
CollectionUtils.newConcurrentHashMap();
|
||||
private final List<ParamConverterProvider> providers = new ArrayList<>();
|
||||
|
||||
ParamConverterFactory() {
|
||||
ServiceLoader<ParamConverterProvider> serviceLoader = ServiceLoader.load(ParamConverterProvider.class);
|
||||
Iterator<ParamConverterProvider> iterator = serviceLoader.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
try {
|
||||
ParamConverterProvider paramConverterProvider = iterator.next();
|
||||
providers.add(paramConverterProvider);
|
||||
} catch (Throwable e) {
|
||||
logger.error(COMMON_ERROR_LOAD_EXTENSION, "", "", "Spi Fail to load ParamConverterProvider");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Optional<ParamConverter> getParamConverter(
|
||||
Class<T> rawType, Type genericType, Annotation[] annotations) {
|
||||
Pair<Pair<Class<?>, Type>, Annotation[]> pair = Pair.of(Pair.of(rawType, genericType), annotations);
|
||||
return cache.computeIfAbsent(pair, k -> {
|
||||
for (ParamConverterProvider provider : providers) {
|
||||
ParamConverter converter = provider.getConverter(rawType, genericType, annotations);
|
||||
if (converter != null) {
|
||||
return Optional.of(converter);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,8 @@ import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.Anot
|
|||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.AnotherUserRestServiceImpl;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.HttpMethodService;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.HttpMethodServiceImpl;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterService;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterServiceImpl;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoForTestException;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoService;
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoServiceImpl;
|
||||
|
|
@ -562,4 +564,24 @@ class JaxrsRestProtocolTest {
|
|||
repository.registerProvider(providerModel);
|
||||
return url.setServiceModel(providerModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParamConverter() {
|
||||
ParamConverterService service = new ParamConverterServiceImpl();
|
||||
URL exportUrl = URL.valueOf(
|
||||
"tri://127.0.0.1:" + availablePort + "/rest?interface=" + ParamConverterService.class.getName());
|
||||
|
||||
URL nettyUrl = this.registerProvider(exportUrl, service, ParamConverterService.class);
|
||||
|
||||
tProtocol.export(proxy.getInvoker(service, ParamConverterService.class, nettyUrl));
|
||||
|
||||
ParamConverterService paramConverterService =
|
||||
this.proxy.getProxy(protocol.refer(ParamConverterService.class, nettyUrl));
|
||||
|
||||
User user = paramConverterService.convert(User.getInstance());
|
||||
User u = new User();
|
||||
u.setAge(20);
|
||||
u.setId(1L);
|
||||
Assertions.assertEquals(u, user);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
|
||||
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
|
||||
|
||||
import javax.ws.rs.ext.ParamConverter;
|
||||
import javax.ws.rs.ext.ParamConverterProvider;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ParamConverterProviderImpl implements ParamConverterProvider {
|
||||
|
||||
@Override
|
||||
public <T> ParamConverter<T> getConverter(Class<T> rawType, Type type, Annotation[] annotations) {
|
||||
if (rawType.isAssignableFrom(User.class)) {
|
||||
return (ParamConverter<T>) new UserParamConverter();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class UserParamConverter implements ParamConverter<User> {
|
||||
@Override
|
||||
public User fromString(String param) {
|
||||
User user = new User();
|
||||
user.setId(1L);
|
||||
user.setAge(20);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(User user) {
|
||||
return "User{" + "id=" + user.getId() + ", name='" + user.getName() + '\'' + ", age=" + user.getAge() + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
|
||||
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.QueryParam;
|
||||
|
||||
@Path("/ParamConverterService")
|
||||
public interface ParamConverterService {
|
||||
|
||||
@GET()
|
||||
@Path("/convert")
|
||||
User convert(@QueryParam("user") User user);
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
|
||||
|
||||
import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
|
||||
|
||||
public class ParamConverterServiceImpl implements ParamConverterService {
|
||||
@Override
|
||||
public User convert(User user) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterProviderImpl
|
||||
Loading…
Reference in New Issue