2015-10-08 40 views
8

Tôi hiện đang có một dự án sử dụng bộ điều khiển Spring và Thymeleaf để tạo một ứng dụng trình duyệt nhỏ. Lớp điều khiển được khai báo làSpring MVC, Thymeleaf & REST

@Controller public class MyController { 

Bên trong bộ điều khiển Tôi có một như

@RequestMapping(value = "/foobars", method = RequestMethod.GET) 
String index(Model model, --- more params ---) { 
    //call repository and get foobarsList 
    //model.addAttribute("foobars", foobarsList); 
      ... 
    return "foobars/foobarThymeleafTemplate" 
} 

các kho lưu trữ cuộc gọi GET định nghĩa và nhận foobarList là một cuộc gọi đến một MongoRepository định nghĩa là:

public interface FoobarRepository extends MongoRepository< ... cut for brevity> { 

    @RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

    ... additional @RestResources cut for brevity ... 
} 

Một lần nữa, Br owser App sẽ rất tuyệt. Số GET gọi đến kho lưu trữ, điền vào mô hình với danh sách các foobars và Thymeleaf thực hiện điều đó với danh sách đó.

VẤN ĐỀ: Bây giờ tôi cần phải truy cập vào dữ liệu tương tự từ một Android App và tôi muốn sử dụng REST và chỉ tiêu thụ JSON trong App Android. Tôi muốn giữ Thymeleaf nhưng sẽ cấu trúc lại ứng dụng trình duyệt nếu cần.

CÂU HỎI: Có cách nào bằng cách nào đó sử dụng cùng @Controller hoặc tôi sẽ phải duy trì FoobarRestController thứ hai bằng cách sử dụng @RestController với/restFoobars thiết bị đầu cuối không? Bộ điều khiển REST thứ hai hoạt động chắc chắn nhưng nó có vẻ hơi cẩu thả ... thiết kế kém.

Suy nghĩ và đề xuất của bạn?

Xin cảm ơn một lần nữa. -Rich

Trả lời

1

phương pháp ưa thích của tôi ở đây là sử dụng thừa kế:

@RequestMapping('/foobars') 
abstract class FoobarBaseController { 

    @RequestMapping 
    abstract listAll() 
} 

@Controller 
class FoobarHtmlController extends FoobarBaseController { 
    @Override ModelAndView listAll() { 
     new ModelAndView('foobars/foobarThymeleafTemplate', [foobars: foobarsList]) 
    } 
} 

@RestController 
@RequestMapping('/foobars', produces = MediaType.APPLICATION_JSON_VALUE) 
class FoobarJsonController extends FoobarBaseController { 
    @Override Collection<Foobar> listAll() { 
     foobarsList 
    } 
} 

Ngoài ra, nếu có công việc quan trọng phải làm kiểm tra đầu vào hoặc tương tự, bạn có thể thực hiện điều đó trong BaseController và có một abstract listAllResponse(DomainObject foo) rằng sau đó trả về ModelAndView (HTML) hoặc DTO (JSON) thích hợp.

Một điểm yếu của phương pháp này là bạn không thể ghi đè chỉ một phần của @RequestMapping, vì vậy bạn phải lặp lại phần của lớp khi ánh xạ khi bạn chỉ định tham số produces, nhưng bạn có thể kế thừa mức phương thức ánh xạ không có vấn đề gì.

1

Expose CRUD

Sử dụng @Controller để làm công việc xử lý trang HTML và sử dụng Repository bạn có thể tiếp xúc với các tổ chức qua phần còn lại API cho các hoạt động cơ bản như crud bằng cách sử dụng SPRING-DATA-REST để lộ các đơn vị của bạn. Tôi nghĩ rằng bạn đang làm việc đó bằng cách nhìn vào mã

@RestResource(rel = "by-id") 
    Marker findMarkerById(String id); 

Expose Kinh doanh logic

Nếu bạn muốn để lộ bất kỳ logic kinh doanh, bạn phải tạo một lớp Service và chỉ cần gọi nó qua của bạn @Controller cho trang web.và tạo một bộ điều khiển khác là @RestController cho giao diện web API.

Bạn có thể lưu ý, bạn không sao chép bất kỳ mã nào ở đây, vì logic được viết tại điểm duy nhất trong lớp Dịch vụ. Nhưng sử dụng các bộ điều khiển khác nhau cho các mục đích khác nhau.

Như bạn không cần tất cả các logic trong trang web để được tiếp xúc với API, sử dụng các bộ điều khiển riêng biệt cho Văn có thể thực hiện được một thiết kế sạch cho mã của bạn nếu bạn có thể không gian tên mã của bạn như app.webapp.api.

Thực phẩm cho các tư tưởng

Sử dụng thực hiện REST API hoàn chỉnh cho các trang web và Android. Sau đó, sử dụng AngualarJS hoặc backboneJs để thực hiện phía khách hàng với HTML5. Tôi nghĩ đây là tương lai.

+0

dù bạn đã trả lời câu hỏi này hai năm trước và tôi đồng ý sử dụng api hoàn chỉnh cho phần cuối và sau đó sử dụng một khung javascript cho giao diện người dùng nên được cộng đồng nên phấn đấu, tuy nhiên vẫn chưa có câu hỏi nào trên stackoverflow và hầu như không có tài liệu hoặc hướng dẫn về cách làm điều này, hoặc cộng đồng Java là rất kháng cự để thay đổi, hoặc điều này chỉ không hoạt động tốt về lâu dài, bạn nghĩ gì? –

Các vấn đề liên quan