0

I am now extracting my project to three parts: a core project used for US & India with features that can by applied for both of them, a US project with US features only, a India project with India features only.

But now I get a problem that in spring boot. In US, there are two new fileds added to the original core entity, so the input object changed from PromSeckillRequest to UsPromSeckillRequest,

Now I want to override my seckill interface, I have no good choice but first write an abandon seckill interface and then write another seckill interface that I want. code below:

@RestController("usShoppingController")
@RequestMapping(value = "/prom", method = RequestMethod.POST)
public class UsPromShoppingController extends PromShoppingController {

@RequestMapping("/seckillAbandon")
@Override
public JsonResponse seckill(@Valid @RequestBody PromSeckillRequest request)    {
    return null;
}

@RequestMapping("/seckill")
public JsonResponse usSeckill(@Valid @RequestBody UsPromSeckillRequest request) {
        return super.seckill(request);
    }
}

But what my goal is like below:

@RestController("usPromShoppingController")
@RequestMapping(value = "/prom", method = RequestMethod.POST)
public class UsPromShoppingController extends PromotionShoppingController {

@RequestMapping("/seckill")
@Override
public JsonResponse usSeckill(@Valid @RequestBody UsPromSeckillRequest request) {
        return super.seckill(request);
    }
}

Is there any good resolution for this? I am using spring boot.

EDIT:

I checked with google and found that, it's a weak point for spring boot until now. I don't know why spring boot don't pay full supportage for this point. I think maybe we can do it like this only.

I want to add a wrapper to solve this, but seems I can only change the request to HashMap type Or String type, But this is not what I want Because it will hard to valid the input request params.

6
  • Honestly I have no clue what your problem is. In case you are referring to some other posting of your please include the relevant code. Commented Dec 13, 2016 at 2:59
  • @ChristophGrimmer-Dietrich how will you override your rest controller when input param entity changed? Commented Dec 13, 2016 at 6:16
  • Both your Controllers listen to different endpoints? Commented Dec 13, 2016 at 6:19
  • No, listen to one endpoint. Commented Dec 13, 2016 at 6:21
  • Imagine this scenario: you wrote a seckill controller with A param in. Then the boss said we need to migrate the code to US, because US is not that same to original feature, so in the A param, we add a new field, said B. Based on original code , we need to override the seckill controller with B param in. How will you override the controller? Commented Dec 13, 2016 at 6:25

1 Answer 1

3

Ok, from what information I have I will try to guess what exactly your problem is and how to fix it :-)

First of all I'm assuming that you somehow (e.g. using a profile) toggle which controller is active since you cannot have two controllers bound to the same endpoint. This is not really spring's fault but has to do with the routing inside the application server (e.g. tomcat).

Soooo... If you are using profiles you can use the active profile as a qualifier by simply annotating your controller class with @Profile and toggle which one is used. That way no overriding whatsoever is needed.

On top of that I strongly recommend that you remove the inheritance in lieu of composition. Put all your shared logic into a central class (like the one you inherit from) and inject it into your constructor.

Your code then might look something like this (I added some Lombok sugar on top)

@RestController
@PostMapping("/prom")
@Profile("us")
@RequiredArgsConstructor
public class UsShoppingController {

    private final ShoppingController helper;

    @RequestMapping("/seckill")
    public JsonResponse seckill(@Valid @RequestBody UsPromSeckillRequest request) {
        return helper.seckill(request);
    }
}

If you are using some older version of spring boot you have to add an onMethod Annotation to @RequiredArgsConstructor or write it by hand.

If you really need your two controllers to run in parallel at the same time you will have to add an indirection layer inside your application code which does the routing based on the parameter type. The application server cannot help you there.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.