将Spring ModelAttribute应用于使用特定参数类型

时间:2015-10-15 18:28:29

标签: java spring spring-mvc

在SpringBoot REST应用程序中,我有TableRequest类型,其中包含表格数据的GET请求的列排序,过滤和分页详细信息。它的通用性在于它并不关心所请求的特定数据是什么,它只指定通用表参数。因此,它适用于许多不同的控制器方法。此外,因为它适用于GET请求,所以字段作为请求参数传递(无@RequestBody json参数)。我在控制器类中有一个@ModelAttribute方法将请求参数解析为TableRequest对象,然后实际的@RequestMapping方法将该对象作为@ModelAttribute接收参数。

因为TableRequest类是通用的,所以我希望能够跨多个控制器使用它,而不必将解析逻辑复制到每个控制器中。我想知道在控制器有@ModelAttribute输入参数时,是否存在基于Spring-y注释的方法重用相同的TableRequest方法。

提前致谢:)

我的解决方案(根据以下选定的答案)

我创建了一个@TableRequestController注释和一个相应的@ControllerAdvice类,它只适用于具有该注释的控制器类。该ControllerAdvice类包含@ModelAttribute方法,将GET请求参数解析为TableRequest对象。

这里一个重要的警告是新的@TableRequestController可能只作为一个整体应用于Controller类,而不是单独的控制器方法。因此,我创建了一个单独的内部控制器类,用该注释标记,其@RequestMapping方法都接受TableRequest对象。

@TableRequestController:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableRequestController {}

ControllerAdvice类:

@ControllerAdvice(annotations = TableRequestController.class)
public class TableRequestControllerAdvice {

    @ModelAttribute
    public TableRequest tableRequest(
            @RequestParam Map<String, String> params,
            @RequestParam int pageStart,
            @RequestParam int pageSize) {

        return new TableRequest(params, pageStart, pageSize);
    }
}

TableRequest REST控制器类:

@RestController
@TableRequestController
public static class MyTableRequestController {

    @RequestMapping("/the/table/request/url")
    public MyResponse makeTableRequest(
            TableRequest tableRequest) {

        return new MyResponse(tableRequest);
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用var clientSource = read(require.resolve('socket.io-client/socket.io.js'), 'utf-8'); Server.prototype.serve = function(req, res){ var etag = req.headers['if-none-match']; if (etag) { if (clientVersion == etag) { debug('serve client 304'); res.writeHead(304); res.end(); return; } } debug('serve client source'); res.setHeader('Content-Type', 'application/javascript'); res.setHeader('ETag', clientVersion); res.writeHead(200); res.end(clientSource); }; /** * Attaches the static file serving. * * @param {Function|http.Server} http server * @api private */ Server.prototype.attachServe = function(srv){ debug('attaching client serving req handler'); var url = this._path + '/socket.io.js'; var evs = srv.listeners('request').slice(0); var self = this; srv.removeAllListeners('request'); srv.on('request', function(req, res) { if (0 === req.url.indexOf(url)) { self.serve(req, res); } else { for (var i = 0; i < evs.length; i++) { evs[i].call(srv, req, res); } } }); }; 。如果您愿意,此处定义的所有内容都适用于所有控制器或已定义的子集。

Documentation

另一种选择(更好的imho)是写message converter。它只处理一种特定类型。您不再需要@ControllerAdvice,而只需在控制器方法中使用@ModelAttribute参数。

答案 1 :(得分:0)

  

在SpringBoot REST应用程序中,我有一个TableRequest类型   包含GET的列排序,过滤和分页详细信息   请求表格数据。它的通用性在于它不关心所请求的特定数据是什么,它只指定通用表参数

这意味着您拥有的是实用程序服务。

因此,将类定义为服务并在视图中访问它。

使用SpringEL的语法访问应用程序上下文中的任何bean:${@myBean.doSomething()}