2015-11-03 51 views
0

我有一個用Spring Boot/Spring MVC構建的REST API,使用通過Jackson的隱式JSON序列化。隱式Jackson序列化之前,可以將消息資源中的值「注入」模型對象嗎?

現在,就在隱式序列化之前,我想從消息資源中「注入」一些UI文本到Jackson轉換成JSON的對象中。有沒有一些簡潔的方法可以做到這一點?

作爲一個簡單的例子,下面我想將Section標題設置爲純粹基於其SectionType的用戶可見值。

(當然,我可以在SectionType中對UI文本進行硬編碼,但我寧願將它們分開放置在資源文件中,因爲它更乾淨,並且可能會在某個時間點進行本地化。而且我無法自動將MessageSource (我想保持獨立於代碼

@RequestMapping(value = "/entry/{id}", method = RequestMethod.GET) 
public Entry entry(@PathVariable("id") Long id) { 
    return service.findEntry(id); 
} 

UI文本messages_en.properties):這不是Spring管理實體/模型對象)

@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

section.MAIN=Main Section 
section.FOO=Proper UI text for the FOO section 
section.BAR=This might get localised one day, you know 

而我想在Spring管理服務/豆地方做(使用Messagesa very simple helper包裝一MessageSource):

section.title = messages.get(section.type.getUiTextKey()) 

需要注意的是,如果我叫entry.getSections()並設置標題爲每個,它不會影響JSON輸出,因爲這些部分是在getSections()中動態生成的。

我是否必須一路去定製deseriazation,或者是否有一種更簡單的方法在模型對象被傑克遜序列化之前掛鉤?

對不起,如果問題不清楚;如果需要,我可以嘗試澄清。

+1

您可以嘗試在每個控制器方法周圍編寫一個方面,返回Section。在該方面調用'joinPoint.proceed();'後,您將從控制器獲取返回的值,並且可以設置消息(您可以自動裝入方面)。不確定它可以用於控制器... http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-ataspectj-around-advice –

+0

@Evgeni,可以確認它應該工作。我們做類似的事情。 – luboskrnac

+0

@luboskrnac是的,它只是測試它。看到我的答案。 –

回答

1

正如我在評論中所說的,您可以在返回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在裏面。

相關問題