我正在尝试编写一个请求路由器,该路由器将接收HTTP POST请求,并基于请求的URL,将请求正文中的Json转换为相应的Java类。
我有一个Route类,用于封装路由url,处理程序,请求和响应类类型。下面是Route类的基本版本,其中没有任何getter和setter。
public class Route {
public String url;
public Class requestClass;
public Class responseClass;
public Route(String url, Class requestClass, Class responseClass) {
this.url = url;
this.requestClass = requestClass;
this.responseClass = responseClass;
}
}
我为在路由器中注册的所有路由保留一个ImmutableList。
ImmutableList.<Route>builder()
.add(
new Route(
"/getemployeebyfilters",
GetEmployeeByFiltersRequest.class,
GetEmployeeByFiltersResponse.class,
new GetEmployeeByFiltersHandler()))
.add(
new Route(
"/getcompanybyfilters",
GetCompanyByFiltersRequest.class,
GetCompanyByFiltersResponse.class,
new GetCompanyByFiltersHandler()))
.build();
在接收到新请求后,我读取了请求的Json主体,并尝试将其解析为相应类的对象。
import com.google.gson.Gson;
Gson gson = new Gson();
for (Route route : routes) {
if (route.url.equals(requestPath)) {
GetEmployeeByFiltersRequest request = gson.fromJson(body, route.requestClass);
}
}
这使编译器抛出以下错误/警告:
./Router.java:61: warning: [unchecked] unchecked method invocation: method fromJson in class Gson is applied to given types
GetEmployeeByFiltersRequest request = gson.fromJson(body, route.requestClass);
^
required: String,Class<T>
found: String,Class
where T is a type-variable:
T extends Object declared in method <T>fromJson(String,Class<T>)
./Router.java:61: warning: [unchecked] unchecked conversion
GetEmployeeByFiltersRequest request = gson.fromJson(body, route.requestClass);
^
required: Class<T>
found: Class
where T is a type-variable:
T extends Object declared in method <T>fromJson(String,Class<T>)
./Router.java:61: error: incompatible types: Object cannot be converted to GetEmployeeByFiltersRequest
GetEmployeeByFiltersRequest request = gson.fromJson(body, route.requestClass);
^
1 error
2 warnings
如果有人能指出我正确的方向,我将不胜感激。我可以灵活地更改Route类。
谢谢
答案 0 :(得分:0)
您可以使用com.fasterxml.jackson.databind.ObjectMapper进行转换
示例代码
public static <T> T convertJsonToObject(String jsonString, Class<T> clazz) {
T object = null;
ObjectMapper objectMapper = new ObjectMapper();
object = objectMapper.reader().forType(clazz).readValue(jsonString);
return object;
}
答案 1 :(得分:0)
阻止编译Java项目的错误是由于类型安全引起的:
./Router.java:61: error: incompatible types: Object cannot be converted to GetEmployeeByFiltersRequest
GetEmployeeByFiltersRequest request = gson.fromJson(body, route.requestClass);
fromJson
方法是Generic Method,这意味着它将返回类类型的对象,该对象作为参数传入。但是,在这种情况下,在编译时不知道route.requestClass
的类类型(它可以是GetEmployeeByFiltersRequest
类型或GetCompanyByFiltersRequest
类型)。>
在这种情况下,gson.fromJson
无法保证它将返回类型为GetEmployeeByFiltersRequest
的对象。实际上route.requestClass
可以很容易地成为GetCompanyByFiltersRequest
类型,这是Java为什么不编译它的反例。
将行更改为以下内容即可编译,但是我不建议将其作为设计模式:
Object request = gson.fromJson(body, route.requestClass);
现在,请求将是通用Object
类型的,并且将失去所有类型的安全性。
我认为处理请求路由的一个更好的选择是使用类似于WebServlet的注释。
它允许您指定与HTTP端点相对应的类:
@WebServlet("/employees")
class Employees extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// do stuff for employees
}
}
@WebServlet("/companies")
class Companies extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// do stuff for companies
}
}