java controller json_java – 在Spring MVC Controller中选择JsonView

我目前正在使用Jackson(2.4.0-rc3)和spring mvc(4.0.3)编写REST api,我正在尝试使其安全.

通过这种方式,我尝试使用JsonView来选择可以序列化的对象部分.

我找到了解决方案(不适合我)用我想要的视图注释我的Controller方法.但我想动态选择控制器内部的视图.

是否可以扩展ResponseEntity类以指定我想要的JsonView?

一小段代码:

这是帐户类

public class Account {

@JsonProperty(value = "account_id")

private Long accountId;

@JsonProperty(value = "mail_address")

private String mailAddress;

@JsonProperty(value = "password")

private String password;

@JsonProperty(value = "insert_event")

private Date insertEvent;

@JsonProperty(value = "update_event")

private Date updateEvent;

@JsonProperty(value = "delete_event")

private Date deleteEvent;

@JsonView(value = PublicView.class)

public Long getAccountId() {

return accountId;

}

@JsonView(value = PublicView.class)

public void setAccountId(Long accountId) {

this.accountId = accountId;

}

@JsonView(value = OwnerView.class)

public String getMailAddress() {

return mailAddress;

}

@JsonView(value = OwnerView.class)

public void setMailAddress(String mailAddress) {

this.mailAddress = mailAddress;

}

@JsonIgnore

public String getPassword() {

return password;

}

@JsonView(value = OwnerView.class)

public void setPassword(String password) {

this.password = password;

}

@JsonView(value = AdminView.class)

public Date getInsertEvent() {

return insertEvent;

}

@JsonView(value = AdminView.class)

public void setInsertEvent(Date insertEvent) {

this.insertEvent = insertEvent;

}

@JsonView(value = AdminView.class)

public Date getUpdateEvent() {

return updateEvent;

}

@JsonView(value = AdminView.class)

public void setUpdateEvent(Date updateEvent) {

this.updateEvent = updateEvent;

}

@JsonView(value = AdminView.class)

public Date getDeleteEvent() {

return deleteEvent;

}

@JsonView(value = OwnerView.class)

public void setDeleteEvent(Date deleteEvent) {

this.deleteEvent = deleteEvent;

}

@JsonProperty(value = "name")

public abstract String getName();

}

这是帐户控制器

@RestController

@RequestMapping("/account")

public class AccountCtrlImpl implements AccountCtrl {

@Autowired

private AccountSrv accountSrv;

public AccountSrv getAccountSrv() {

return accountSrv;

}

public void setAccountSrv(AccountSrv accountSrv) {

this.accountSrv = accountSrv;

}

@Override

@RequestMapping(value = "/get_by_id/{accountId}", method = RequestMethod.GET, headers = "Accept=application/json")

public ResponseEntity getById(@PathVariable(value = "accountId") Long accountId) {

try {

return new ResponseEntity(this.getAccountSrv().getById(accountId), HttpStatus.OK);

} catch (ServiceException e) {

return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);

}

}

@Override

@RequestMapping(value = "/get_by_mail_address/{mail_address}", method = RequestMethod.GET, headers = "Accept=application/json")

public ResponseEntity getByMailAddress(@PathVariable(value = "mail_address") String mailAddress) {

try {

return new ResponseEntity(this.getAccountSrv().getByMailAddress(mailAddress), HttpStatus.OK);

} catch (ServiceException e) {

return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);

}

}

@Override

@RequestMapping(value = "/authenticate/{mail_address}/{password}", method = RequestMethod.GET, headers = "Accept=application/json")

public ResponseEntity authenticate(@PathVariable(value = "mail_address") String mailAddress, @PathVariable(value = "password") String password) {

return new ResponseEntity(HttpStatus.NOT_IMPLEMENTED);

}

}

解决方法:

我已经解决了扩展ResponseEntity的问题,如下所示:

public class ResponseViewEntity extends ResponseEntity> {

private Class extends BaseView> view;

public ResponseViewEntity(HttpStatus statusCode) {

super(statusCode);

}

public ResponseViewEntity(T body, HttpStatus statusCode) {

super(new ContainerViewEntity(body, BaseView.class), statusCode);

}

public ResponseViewEntity(T body, Class extends BaseView> view, HttpStatus statusCode) {

super(new ContainerViewEntity(body, view), statusCode);

}

}

和ContainerViewEntity封装对象和选定的视图

public class ContainerViewEntity {

private final T object;

private final Class extends BaseView> view;

public ContainerViewEntity(T object, Class extends BaseView> view) {

this.object = object;

this.view = view;

}

public T getObject() {

return object;

}

public Class extends BaseView> getView() {

return view;

}

public boolean hasView() {

return this.getView() != null;

}

}

之后,我们只转换具有良好视图的对象.

public class JsonViewMessageConverter extends MappingJackson2HttpMessageConverter {

@Override

protected void writeInternal(Object object, HttpOutputMessage outputMessage)

throws IOException, HttpMessageNotWritableException {

if (object instanceof ContainerViewEntity && ((ContainerViewEntity) object).hasView()) {

writeView((ContainerViewEntity) object, outputMessage);

} else {

super.writeInternal(object, outputMessage);

}

}

protected void writeView(ContainerViewEntity view, HttpOutputMessage outputMessage)

throws IOException, HttpMessageNotWritableException {

JsonEncoding encoding = this.getJsonEncoding(outputMessage.getHeaders().getContentType());

ObjectWriter writer = this.getWriterForView(view.getView());

JsonGenerator jsonGenerator = writer.getFactory().createGenerator(outputMessage.getBody(), encoding);

try {

writer.writeValue(jsonGenerator, view.getObject());

} catch (IOException ex) {

throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);

}

}

private ObjectWriter getWriterForView(Class> view) {

ObjectMapper mapper = new ObjectMapper();

mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);

return mapper.writer().withView(view);

}

}

为了完成,我启用了转换器

就是这样,我可以在控制器中选择View

@Override

@RequestMapping(value = "/get_by_id/{accountId}", method = RequestMethod.GET, headers = "Accept=application/json")

public ResponseViewEntity getById(@PathVariable(value = "accountId") Long accountId) throws ServiceException {

return new ResponseViewEntity(this.getAccountSrv().getById(accountId), PublicView.class, HttpStatus.OK);

}

标签:java,spring-mvc,spring,jackson

来源: https://codeday.me/bug/20190713/1449688.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值