我有一个使用Spring Boot/Spring MVC构建的REST API,通过Jackson使用隐式JSON序列化。
现在,就在隐式序列化之前,我想将消息资源中的一些UI文本"注入"到Jackson转换为JSON的对象中。有没有一些简洁的方法可以做到这一点?
作为一个非常简化的示例,下面我想将Section
标题设置为用户可见的值,完全基于其SectionType
。
(当然,我可以在SectionType中对UI文本进行硬编码,但我宁愿在资源文件中将它们分开,因为这样更干净,而且它们可能在某个时候被本地化。而且我不能在非Spring管理的实体/模型对象中自动连接MessageSource
。)
@Entity
public class Entry {
// persistent fields omitted
@JsonProperty
public List<Sections> getSections() {
// Sections created on-the-fly, based on persistent data
}
}
public class Section {
public SectionType type;
public String title; // user-readable text whose value only depends on type
}
public enum SectionType {
MAIN,
FOO,
BAR;
public String getUiTextKey() {
return String.format("section.%s", name());
}
}
@RestController
:中的某个位置
@RequestMapping(value = "/entry/{id}", method = RequestMethod.GET)
public Entry entry(@PathVariable("id") Long id) {
return service.findEntry(id);
}
我想与代码分开的UI文本(messages_en.properties
):
section.MAIN=Main Section
section.FOO=Proper UI text for the FOO section
section.BAR=This might get localised one day, you know
我想在某个地方的Spring托管服务/bean中做什么(使用Messages
,一个包装MessageSource
的非常简单的助手):
section.title = messages.get(section.type.getUiTextKey())
注意,如果我调用entry.getSections()
并为每个设置标题,它将不会影响JSON输出,因为Sections是在getSections()
中动态生成的。
我必须一直进行自定义取消序列化吗?或者有没有一种更简单的方法可以在Jackson序列化模型对象之前挂接到模型对象中
如果问题不清楚,很抱歉;如果需要,我可以试着澄清。
正如我在评论中所说,您可以围绕每个返回Section的控制器方法编写一个Aspect。
我写了一个简单的例子。您必须使用消息源对其进行修改。
控制器:
@RestController
@RequestMapping("/home")
public class HomeController {
@RequestMapping("/index")
public Person index(){
Person person = new Person();
person.setName("evgeni");
return person;
}
}
方面
@Aspect
@Component
public class MyAspect {
@Around("execution(public Person com.example..*Controller.*(..))")//you can play with the pointcut here
public Object addSectionMessage(ProceedingJoinPoint pjp) throws Throwable {
Object retVal = pjp.proceed();
Person p = (Person) retVal; // here cast to your class(Section) instead of Person
p.setAge(26);//modify the object as you wish and return it
return p;
}
}
由于方面也是@Component
,您可以在其中使用@Autowire
。