我有一个Java Web应用程序,目前我有两个控制器。
一个用于REST调用的控制器和另一个用于将ModelAndView(使用Spring MVC)对象传递给视图的控制器。
我担心的是这两种方法都引用了相同的服务层调用。我是否应该创建一个包含与服务层交互的代码的抽象类?
REST控制器是否应该与其他控制器合并?
答案 0 :(得分:0)
我会确保控制器中没有任何逻辑。控制器应该只获取请求,调用另一个方法(位于服务层 - 比API层更低的层)并以适当的格式返回数据。
例如:
public class MyServiceLayer() {
public List<SomeObject> getAllSomeObjects() {
// Do some logic to get the object back
}
}
然后你可以拥有这样的控制器:
@Controller
public class MyController {
@Autowired
private MyServiceLayer myService;
// Put annotation for getting it in Json
public List<SomeObject> getAllSomeObjectsInJson() {
return myService.getAllSomeObjects();
}
// Put annotation for getting the view data
public ModelAndView getAllSomeObjectsView() {
// Return your ModelAndView here.
}
}
在这种情况下,如果你喜欢这样,你也可以将它拆分为2个控制器。
无论如何,你不应该有2个带有重复代码的控制器 - 这很糟糕!并且你不应该被强制将2个不同的控制器合二为一。这就是为什么你应该把逻辑带到一个不同的,打包的层。
这样你就可以遵循&#34;做一件事原则&#34;这说明一个班级应该有一个目的。在这种情况下,MyServiceLayer
有一个目的 - 处理获取对象的逻辑。控制器层有一个目的 - 传达数据(以您想要的格式)。
如果明天要添加JMX API,则不必复制代码或扩展原始控制器。只需添加另一个类来处理JMX调用并使用MyServiceLayer
答案 1 :(得分:0)
代码重复几乎总是一个迹象,表明有问题的代码应该打包在某种可重用的组件中。这是我对Spring MVC控制器结构采取的方法:
代表某种逻辑操作的代码应该放在服务bean中。系统中的某些其他组件可以合理地调用此代码作为其工作流程的一部分,并且需要可以独立测试。
控制器类仅包含将HTTP请求转换为系统操作所需的代码;在许多情况下,这意味着他们只需要对服务方法进行单次调用。
当我在同一路径上公开资源的JSON和HTML视图时,我在正确的位置创建了一个带有@RequestMapping
注释的抽象控制器类,并使用@RestController
扩展它返回有问题的对象的资源表示(从Spring HATEOAS的ResourceSupport
开始),以及一个加载模型和视图的基于HTML的资源表示。