在用Spring MVC框架做Web应用开发中,在一些特殊请款下我们都会用自定标签来完成一些特殊的功能。
在通常情况下,自定义标签的内容如果不通过访问服务就能实现,那么继承TagSupport,重写doStartTag()方法就可以实现基本功能。
eg. 实现一个html标记的反转义功能的自定义标签
/**
* @Comment
* @Author Ron
* @date 2016年8月30日 上午9:02:56
*/
public class HtmlUnEncodeTags extends TagSupport {
private Logger logger = LogManager.getLogger(this.getClass());
private String encodeStr;
private static final long serialVersionUID = 1L;
@Override
public int doStartTag() throws JspException {
String outStr = "";
try {
if(StringUtils.isNotBlank(encodeStr)){
outStr = StringEscapeUtils.unescapeHtml4(encodeStr);
}
pageContext.getOut().write(outStr);
} catch (IOException e) {
logger.error("",e);
}
return super.doStartTag();
}
public String getEncodeStr() {
return encodeStr;
}
public void setEncodeStr(String encodeStr) {
this.encodeStr = encodeStr;
}
}
但是在特殊情况下,我们需要在自定义标签的逻辑代码中访问服务层获取信息,那么如何通过注解的方式自动装配服务呢?在Spring MVC中,用上面所说的方法是不行的。
这里需要自定义标签继承的是RequestContextAwareTag 而不是TagSupport。
例如我们需要实现一个获取未读邮件数目的功能,我们首先需要在自己的服务中写好获取或者计算邮件未读数量的方法,这里假定为:
queryMsgCount(userId,EmailConsts.ReadStatus.NO.getValue());
userId:用户唯一标示
EmailConsts.ReadStatus.NO.getValue():获取枚举的邮件未读状态值
自定义标签逻辑class为MsgUnReadMsgTags
那么要实现获取未读邮件数目的功能,那么实现代码如下所示:
public class MsgUnReadMsgTags extends RequestContextAwareTag {
private Logger logger = LogManager.getLogger(this.getClass());
private int userId;
private static final long serialVersionUID = 1L;
@Autowired
private UserMessageFacade userMessageService;
@Override
public int doStartTagInternal() throws JspException {
String outStr = "";
try {
JspWriter writer = pageContext.getOut();
userMessageService = this.getRequestContext().getWebApplicationContext().getBean(UserMessageFacade.class);
int count = userMessageService.queryMsgCount(userId,EmailConsts.ReadStatus.NO.getValue());
if(count > 0){
if(count > 99){
outStr = "<span class=\"badge\">99+</span>";
}else{
outStr = "<span class=\"badge\">"+ count +"</span>";
}
}
writer.write(outStr);
writer.flush();
} catch (IOException e) {
logger.error("Get Messages Count IOException-------------->>>>>>>>>>",e);
}
return 0;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
注意:
在定义userMessageService服务时用@Autowired自动装配注解是不够的,你还需要在使用时使用ApplicationContext的getBean方法获取服务的Bean。
如以上代码中的代码块:
userMessageService = this.getRequestContext().getWebApplicationContext().getBean(UserMessageFacade.class);