我们公司计划将微服务技术转换为Spring Boot。作为一项计划,我做了一些高级阅读,并注意到它的潜在影响和语法等价物。我也开始移植我们作为辅助项目的最小服务。
阻止我进度的一个问题是尝试将我们的Json请求/响应交换转换为Spring Boot。
以下是代码示例:(对于那些不认识这一点的人来说,这是Nutz框架)
@POST
@At // These two lines are equivalent to @PostMapping("/create")
@AdaptBy(type=JsonAdapter.class)
public Object create(@Param("param_1") String param1, @Param("param_2) int param2) {
MyModel1 myModel1 = new MyModel1(param1);
MyModel2 myModel2 = new MyModel2(param2);
myRepository1.create(myMode12);
myRepository2.create(myModel2);
return new MyJsonResponse();
}
在PostMan或任何其他REST客户端上,我只是传递POST:
{
"param_1" : "test",
"param_2" : 1
}
我在Spring Boot中做到了这一点:
@PostMapping("/create")
public Object create(@RequestParam("param_1") String param1, @RequestParam("param_2) int param2) {
MyModel1 myModel1 = new MyModel1(param1);
MyModel2 myModel2 = new MyModel2(param2);
myRepository1.create(myMode12);
myRepository2.create(myModel2);
return new MyJsonResponse();
}
我不知道如何在这里做类似JsonAdapter的事情。 Spring并不认识我传递的数据。
我尝试了这个但基于这些例子,它希望Json参数是实体的形式。
@RequestMapping(path="/wallet", consumes="application/json", produces="application/json")
但是如果我这样做的话,我只能做到这一点:
public Object (@RequestBody MyModel1 model1) {}
我的问题是MyModel1可能不一定包含我的json数据所具有的字段/参数。
关于Nutz非常有用的一点是,如果我删除了JsonAdapter,它在春天的行为就像一个常规的表单请求端点。
我无法在Stack中找到答案,或者如果可能的话,我调用它的方式与现有的Spring开发人员所称的不同。
我们的老板希望我们(不切实际地)实施这些变更,而不必强迫前端开发人员适应这些变化。 (自治和所有爵士乐)。如果这是不可避免的,对此会有什么明智的解释?
答案 0 :(得分:3)
在这种情况下,您可以使用Map
类来读取输入json,例如
@PostMapping("/create")
public Object create(@RequestBody Map<String, ?> input) {
sout(input.get("param1")) // cast to String, int, ..
}
答案 1 :(得分:2)
我实际上找到了一个更直接的解决方案。
显然这有效:
@PostMapping("/endpoint")
public Object endpoint(@RequestBody MyWebRequestObject request) {
String value1 = request.getValue_1();
String value2 = request.getValue_2();
}
json有效载荷是这样的:
{
"value_1" : "hello",
"value_2" : "world"
}
如果MyRequestObject像json请求对象一样被映射,则这是有效的。例如:
public class MyWebRequestObject {
String value_1;
String value_2
}
忽略未映射的值。春天很聪明。
我知道这是我刚开始的地方,但是由于我们为其余控件引入了一个服务层来进行交互,因此创建我们自己的请求模型对象(DTO)与持久性模型是分开的。
答案 2 :(得分:0)
您可以使用@RequestBody Map作为@PostMapping,@ PutMapping和@PatchMapping的参数。对于@GetMapping和@DeleteMapping,您可以编写一个实现Converter的类,以便将json形成的请求参数转换为Map。并且您将该类注册为具有@Component注释的bean。然后,您可以将参数绑定到@RequestParameter Map。
以下是转换器的示例。
@Component
public class StringToMapConverter implements Converter<String, Map<String, Object>> {
private final ObjectMapper objectMapper;
@Autowired
public StringToMapConverter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public Map<String, Object> convert(String source) {
try {
return objectMapper.readValue(source, new TypeReference<Map<String, Object>>(){});
} catch (IOException e) {
return new HashMap<>();
}
}
}
如果要排除MyModel1类的特定字段,请在字段中使用@JsonIgnore注释,如下所示。
class MyModel1 {
private field1;
@JsonIgnore field2;
}
然后,我猜你可以使用你所做的事情。(我不确定。)
public Object (@RequestBody MyModel1 model1) {}
答案 3 :(得分:0)
我认为您可以使用涉及dto的策略 https://auth0.com/blog/automatically-mapping-dto-to-entity-on-spring-boot-apis/
您可以将json发送到您的rest api,这是一个dto对象的地图,之后您可以像实体一样映射或根据您的需要使用它