स्प्रिंग बूट में आराम के लिए बेस यूआरएल कैसे सेट करें?


118

मैं mvc को मिक्स करने और एक सिंगल स्प्रिंग बूट प्रोजेक्ट में आराम करने की कोशिश कर रहा हूं।

मैं एक ही स्थान पर सभी बाकी नियंत्रकों (जैसे। example.com/api) के लिए आधार पथ सेट करना चाहता हूं (मैं नहीं चाहता कि प्रत्येक नियंत्रक को @RequestMapping('api/products')इसके बजाय, केवल एनोटेट करें @RequestMapping('/products')

Mvc नियंत्रकों को example.com/whatever द्वारा एक्सेस किया जाना चाहिए

क्या यह संभव है?

(मैं वसंत डेटा बाकी का उपयोग नहीं करते हैं, बस वसंत पीवीसी)




स्प्रिंग बूट संस्करण 2.1.4। जारी करें, spring.mvc.servlet.path = / api और server.servlet.context-path = / api, दोनों कार्य
प्रयाग शर्मा

server.servlet.context-path = / api सॉल्यूशन APPLICATION के लिए है, केवल REST के लिए नहीं। यह SOAP सेवाओं के लिए भी मान्य है। आप अपने साबुन और बाकी सेवाओं पथ sperate करना चाहते हैं, तो आप @RequestMapping उपयोग करना चाहिए ( 'एपीआई / ...') ... medium.com/@bm.celalkartal/...
bmck

जवाबों:


89

स्प्रिंग बूट 1.2+ (<2.0) के साथ यह सब आवेदन में एक ही संपत्ति है।

spring.data.rest.basePath=/api

रेफरी लिंक: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#getting-started.changing-base-uri

2.x के लिए, का उपयोग करें

server.servlet.context-path=/api

4
यह सटीक जवाब है जो थोरिनकर ने दिया था।
जीन-फ्रांस्वा ब्यूशेफ

8
धन्यवाद, लेकिन यह मेरे लिए स्प्रिंग बूट संस्करण v1.5.7.RELEASE में काम नहीं करता है। अन्य उत्तर server.contextPath = / api ने काम किया
Jay

10
@Suroj यह समाधान केवल रिपॉजिटरी RestController एनोटेट नियंत्रकों के साथ काम करता है, रेस्टकंट्रोलर के साथ नहीं ...
नैनो

jira.spring.io/browse/DATAREST-1211 इस जीरा टिकट में उल्लेख किया गया है कि "स्प्रिंग बूट 2.0.0 के लिए" spring.data.rest.base-path "। अफसोस की बात है, दोनों मेरे लिए काम नहीं करते हैं।
कार्स्टन हेजमैन

6
SB 2+ के लिए यह server.servlet.context-path = / url
vicky

95

थोड़ा देर से, लेकिन एक ही सवाल जवाब तक पहुँचने से पहले मुझे यहाँ ले आया इसलिए मैंने इसे यहाँ पोस्ट किया। बनाएँ (यदि आपके पास अभी भी नहीं है) एक application.properties और जोड़ें

server.contextPath=/api

तो पिछले उदाहरण में यदि आपके पास एक RestController है तो आप @RequestMapping("/test")इसे पसंद करेंगेlocalhost:8080/api/test/{your_rest_method}

प्रश्न स्रोत: मैं अपने स्प्रिंग बूट वेबैप के लिए यूआरएल कैसे चुनूं


19
आप इसे केवल रेस्ट्रॉन्ट्रोलर्स के साथ काम करने के लिए कैसे लागू करते हैं और "/ एपीआई" के बिना सामान्य नियंत्रकों तक पहुंच प्राप्त करते हैं
सिया सोसिबो

@Stoan मैं समाधान पाया, मेरे जवाब की जाँच करें :-)
kravemir

यह मत करो! देखें थिनर का जवाब
स्टीफन

थोरिंकर का जवाब विशेष रूप से स्प्रिंग डेटा रीस्ट के लिए है।

8
server.contextPath अब हटा दिया गया है, इसके बजाय server.servlet.context-path का उपयोग करें
डी.एस.

46

स्प्रिंग बूट फ्रेमवर्क संस्करण के लिए 2.0.4.RELEASE+। इस लाइन को जोड़ेंapplication.properties

server.servlet.context-path=/api

1
यह सार्वजनिक फ़ोल्डर को भी प्रभावित करता है :-(
मिशेल

5
यह स्प्रिंग बूट 2+ के लिए सही उत्तर है। spring.data.rest.basePathवसंत बूट 2 के लिए काम नहीं करता है
जैकबफ्लौ

27

चूंकि यह समस्या के लिए पहली Google हिट है और मुझे लगता है कि अधिक लोग इसके लिए खोज करेंगे। स्प्रिंग बूट '1.4.0' के बाद से एक नया विकल्प है। अब एक कस्टम RequestMappingHandlerMapping को परिभाषित करना संभव है, जो @RestController के साथ एनोटेट की गई कक्षाओं के लिए एक अलग पथ को परिभाषित करने की अनुमति देता है।

कस्टम एनोटेशन के साथ एक अलग संस्करण को जोड़ती है कि @RestController साथ @RequestMapping इस पर पाया जा सकता ब्लॉग पोस्ट

@Configuration
public class WebConfig {

    @Bean
    public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() {
        return new WebMvcRegistrationsAdapter() {
            @Override
            public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
                return new RequestMappingHandlerMapping() {
                    private final static String API_BASE_PATH = "api";

                    @Override
                    protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
                        Class<?> beanType = method.getDeclaringClass();
                        if (AnnotationUtils.findAnnotation(beanType, RestController.class) != null) {
                            PatternsRequestCondition apiPattern = new PatternsRequestCondition(API_BASE_PATH)
                                    .combine(mapping.getPatternsCondition());

                            mapping = new RequestMappingInfo(mapping.getName(), apiPattern,
                                    mapping.getMethodsCondition(), mapping.getParamsCondition(),
                                    mapping.getHeadersCondition(), mapping.getConsumesCondition(),
                                    mapping.getProducesCondition(), mapping.getCustomCondition());
                        }

                        super.registerHandlerMethod(handler, method, mapping);
                    }
                };
            }
        };
    }
}

2
स्प्रिंग बूट 2.0.0+ में, सीधे WebMvcRegistrations इंटरफ़ेस से काम करें। WebMvcRegistrationsAdapter इंटरफेस में डिफ़ॉल्ट तरीकों को जोड़ने के पक्ष में हटा दिया गया था।
गिल्बर्ट एरेनास डैगर

27

मुझे विश्वास नहीं हो रहा था कि इस सरल प्रश्न का उत्तर कितना जटिल है। यहाँ कुछ संदर्भ हैं:

विचार करने के लिए कई अलग चीजें हैं:

  1. आप server.context-path=/apiमें सेट करके सब कुछ केapplication.properties लिए एक उपसर्ग कॉन्फ़िगर कर सकते हैं । (इसका server.context-path not server.contextPath!)
  2. स्प्रिंग डाटा नियंत्रकों @RepositoryRestController साथ एनोटेट कि बाकी endpoint वातावरण चर का प्रयोग करेंगे के रूप में एक भंडार का पर्दाफाश spring.data.rest.base-pathमें application.properties। लेकिन सादा @RestControllerइसे ध्यान में नहीं रखेगा। स्प्रिंग डेटा रेस्ट डॉक्यूमेंटेशन के अनुसार एक एनोटेशन है @BasePathAwareControllerजिसे आप इसके लिए उपयोग कर सकते हैं। लेकिन मुझे इस तरह के नियंत्रक को सुरक्षित करने की कोशिश करने पर स्प्रिंग-सुरक्षा के संबंध में समस्याएं होती हैं। यह अब नहीं मिला है।

एक और समाधान एक सरल चाल है। आप एनोटेशन में एक स्थिर स्ट्रिंग को उपसर्ग नहीं कर सकते, लेकिन आप इस तरह से भावों का उपयोग कर सकते हैं:

@RestController
public class PingController {

  /**
   * Simple is alive test
   * @return <pre>{"Hello":"World"}</pre>
   */
  @RequestMapping("${spring.data.rest.base-path}/_ping")
  public String isAlive() {
    return "{\"Hello\":\"World\"}";
  }
}

आप एनोटेशन में कैसे डालेंगे?
तैमूरज

2
meh, तो आप हमेशा एक नया नियंत्रक बनाने के लिए हर बार इस उपसर्ग को जोड़ने के लिए याद रखना होगा
गिल्बर्ट एरेनास डैगर

13

बूट 2.0.0+ के लिए यह मेरे लिए काम करता है: server.servlet.context-path = / api


4
यह सब कुछ / एपीआई के तहत लगता है, न केवल @RestController मैपर। लेकिन फिर भी धन्यवाद। आपकी जानकारी अभी भी उपयोगी है।
सतर्क

9

मुझे एक स्वच्छ समाधान मिला, जो केवल बाकी नियंत्रकों को प्रभावित करता है।

@SpringBootApplication
public class WebApp extends SpringBootServletInitializer {

    @Autowired
    private ApplicationContext context;

    @Bean
    public ServletRegistrationBean restApi() {
        XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
        applicationContext.setParent(context);
        applicationContext.setConfigLocation("classpath:/META-INF/rest.xml");

        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setApplicationContext(applicationContext);

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/rest/*");
        servletRegistrationBean.setName("restApi");

        return servletRegistrationBean;
    }

    static public void main(String[] args) throws Exception {
        SpringApplication.run(WebApp.class,args);
    }
}

स्प्रिंग बूट दो डिस्पैचर सर्वलेट को पंजीकृत करेगा - dispatcherServletनियंत्रकों के लिए डिफ़ॉल्ट , और परिभाषित के restApiलिए डिस्पैचर :@RestControllersrest.xml

2016-06-07 09:06:16.205  INFO 17270 --- [           main] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'restApi' to [/rest/*]
2016-06-07 09:06:16.206  INFO 17270 --- [           main] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]

उदाहरण rest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="org.example.web.rest"/>
    <mvc:annotation-driven/>

    <!-- Configure to plugin JSON as request and response in method handler -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter"/>
            </list>
        </property>
    </bean>

    <!-- Configure bean to convert JSON to POJO and vice versa -->
    <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </bean>
</beans>

लेकिन, आप इसके लिए सीमित नहीं हैं :

  • उपयोग XmlWebApplicationContext, आप उपलब्ध किसी भी अन्य संदर्भ प्रकार का उपयोग कर सकते हैं, अर्थात। AnnotationConfigWebApplicationContext, GenericWebApplicationContext, GroovyWebApplicationContext, ...
  • परिभाषित करें jsonMessageConverter, messageConvertersबाकी संदर्भों में सेम, उन्हें मूल संदर्भ में परिभाषित किया जा सकता है

क्या xml के उपयोग के बिना यह प्रोग्रामिक रूप से करना संभव है?
एरियन

@ एरियनहोसिनज़ादेह हाँ। यह प्रोग्रामेटिक रूप से करना संभव है। वसंत संदर्भ स्थापित करने के कई तरीके हैं। उदाहरण में, मैंने दिखाया है कि REST API हैंडलिंग के लिए बाल संदर्भ कैसे बनाया जाता है। बस जावा के भीतर संदर्भ सेट करना सीखें, और फिर इस उत्तर में इस तरह के ज्ञान को ज्ञान के साथ जोड़ दें। उसे प्रोग्रामिंग कहा जाता है।
क्राव्रीमिर

7

आप अपने नियंत्रकों के लिए एक कस्टम एनोटेशन बना सकते हैं:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
@RequestMapping("/test")
public @interface MyRestController {
}

अपने नियंत्रक वर्गों पर सामान्य @RestController के बजाय इसका उपयोग करें और @RequestMapping के साथ तरीकों को एनोटेट करें।

बस परीक्षण किया गया - स्प्रिंग 4.2 में काम करता है!


धन्यवाद। मैंने यह कोशिश की है। लेकिन अब मुझे @RequestMapping ("/ उत्पादों"), @RequestMapping ("/ उत्पादों / {id}") के साथ प्रत्येक विधि को एनोटेट करना होगा। इसके बजाय मुझे @RequestMapping ("/ उत्पादों") और @RequestMapping, @RequestMapping ("/: id") विधियों के साथ नियंत्रक की आवश्यकता है। और उत्पाद नियंत्रक को एपीआई / उत्पादों (जैसे एक ही स्थान पर एपी उपसर्ग सेट) में प्रयोग करने योग्य होना चाहिए
तीमुराज़

2
उस स्थिति में, नहीं, बॉक्स से कोई समाधान नहीं है, AFAIK। आप अपने खुद के कार्यान्वयन की कोशिश कर सकते हैं RequestMappingHandlerMapping। स्प्रिंग डेटा रीस्ट में आपकी आवश्यकता के समान मैपर है - BasePathAwareHandlerMapping
इल्या नोवोसेल्टसेव

@ ममो, क्या आपको उचित समाधान मिला? मुझे खुशी होगी अगर आप इसे प्रतिक्रिया के रूप में पोस्ट कर सकते हैं। मैं यहाँ एक ही आवश्यकता है।
fischermatte

@fischermatte, नहीं, मुझे वह नहीं मिला जो मैं चाहता था, मैं प्रत्येक नियंत्रक वर्ग से पहले @RequestMapping ("/ एपीआई / उत्पाद") या @RequestMapping ("/ एपीआई / उपयोगकर्ता") रखता हूं और फिर विधि से पहले एक और @ RequestMapping ( "/ {आईडी}")। लेकिन मुझे नहीं लगता कि यह एक बड़ा मुद्दा है, अगर मैं "एपी" को किसी चीज़ में बदलना चाहता हूं, तो मैं इसे प्रत्येक कक्षा की शुरुआत में बदल दूंगा।
तैमूराराज

@IlyaNovoseltsev एक समाधान है, मेरा जवाब
देखिए

7

मुझे थोड़ा देर हो सकती है, लेकिन ... मेरा मानना ​​है कि यह सबसे अच्छा समाधान है। इसे अपने application.yml (या एनालॉग कॉन्फिगर फाइल) में सेट करें:

spring:
    data:
        rest:
            basePath: /api

जैसा कि मुझे याद है कि यह हो सकता है - इस यूआरआई के नीचे आपके सभी रिपॉजिटरी उजागर हो जाएंगे।


क्या आप इसे थोड़ा समझा सकते हैं या किसी releavant प्रलेखन की ओर इशारा कर सकते हैं?
दिमित्री सर्डियुक


11
environemnt वैरिएबल spring.data.rest.base-path केवल स्प्रिंग-डेटा-रेस्ट और स्प्रिंग-हटियो को प्रभावित करता है। सादा @RestController अभी भी जड़ पर बैठ जाएगा!
रॉबर्ट

4
@thorinkor के आधार पर आप क्या कह रहे हैं कि ज्यादातर मामलों में लोग स्प्रिंग डेटा रीस्ट रिपोजिटरी का निर्माण करेंगे? और ओपी स्पष्ट रूप से कह रहा है कि उसके पास बाकी नियंत्रक हैं ...
जीन-फ्रांस्वा ब्यूशफ

1
मुझे लगता है कि यह केवल तभी काम करेगा जब आप स्प्रिंगडैरेस्ट का उपयोग कर रहे हों।
जुमजेरा

6

एक PathMatchConfigurer (स्प्रिंग बूट 2.x) का उपयोग करने का प्रयास करें:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer  {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("api", HandlerTypePredicate.forAnnotation(RestController.class));
    }
}

1
धन्यवाद, यह वही था जिसकी मुझे तलाश थी! यह आपको इस WebMvcConfig के माध्यम से कॉन्फ़िगर किए गए सभी RestControllers के लिए एक संदर्भ पथ तत्व सेट करने की अनुमति देता है, जो स्प्रिंग.डेटा .rest.base-path के समान है।
बुउरमैन

आपका जवाब @HaraldWendel पर है: +1: आप उस पर थोड़ा विस्तार करके उस पर कुछ और सुधार कर सकते हैं, जैसे कि यह बताना कि आपका कोड वास्तव में क्या करता है (जैसा कि मैंने अपनी टिप्पणी में करने की कोशिश की है) और / या शायद लिंक कुछ javadoc या प्रलेखन जो इस उपयोग का वर्णन करते हैं।
बुउरमैन

यह एकमात्र समाधान है जिसने मेरे लिए काम किया है क्योंकि मैं नियंत्रक इंटरफेस का उपयोग कर रहा हूं
अनातोली याकिमचुक

4

आप @RequestMapping("rest")एनोटेशन के साथ एक बेस क्लास बना सकते हैं और इस बेस क्लास के साथ आप सभी अन्य वर्गों का विस्तार कर सकते हैं।

@RequestMapping("rest")
public abstract class BaseController {}

अब इस बेस क्लास का विस्तार करने वाली सभी कक्षाएं सुलभ होंगी rest/**


3
यह सही उत्तर नहीं है, उपयोगकर्ता नियंत्रक एनोटेशन की बात कर रहा है। यदि आप एक RequestMapping एनोटेशन के साथ एक अमूर्त वर्ग का विस्तार करते हैं, और नए वर्ग के पास एक RequestMapping भी है, तो यह अंतिम पहले वाले को ओवरराइड करेगा, यह दोनों को समाप्‍त नहीं करेगा।
मैसिमो

क्या आप जानते हैं कि एनोटेशन जावा में विरासत में नहीं मिले हैं जब तक कि यह मेटा एनोटेशन विरासत में नहीं मिला है? इसे देखें: stackoverflow.com/a/21409651 । और @RequestMapping में ऐसा प्रतीत नहीं होता है कि: docs.spring.io/spring-framework/docs/current/javadoc-api/org/……
मशूर

3

जो लोग YAML कॉन्फ़िगरेशन (application.yaml) का उपयोग करते हैं।

नोट : यह केवल के लिए काम करता हैSpring Boot 2.x.x

server:
  servlet:
    contextPath: /api

यदि आप अभी भी उपयोग कर रहे हैं Spring Boot 1.x

server:
  contextPath: /api


1

server.servlet.context-path=/apiमुझे लगता है कि समाधान होगा। मेरे पास एक ही मुद्दा था और इससे मुझे हल हो गया। मैंने server.context-path का इस्तेमाल किया। हालाँकि, ऐसा लगता है कि पदावनत हो गया और मैंने पाया कि server.servlet.context-pathअब इस मुद्दे को हल कर दिया गया है। एक और वर्कअराउंड मैंने पाया कि मेरे फ्रंट एंड (H5) पेजों में एक बेस टैग जोड़ा गया था। मुझे उम्मीद है कि इससे किसी को मदद मिलेगी।

चियर्स


0

यह समाधान लागू होता है यदि:

  1. आप उपसर्ग करना चाहते हैं RestControllerलेकिन नहीं Controller
  2. आप स्प्रिंग डेटा रेस्ट का उपयोग नहीं कर रहे हैं।

    @Configuration
    public class WebConfig extends WebMvcConfigurationSupport {
    
    @Override
    protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
        return new ApiAwareRequestMappingHandlerMapping();
    }
    
    private static class ApiAwareRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    
        private static final String API_PATH_PREFIX = "api";
    
        @Override
        protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
            Class<?> beanType = method.getDeclaringClass();
            if (AnnotationUtils.findAnnotation(beanType, RestController.class) != null) {
                PatternsRequestCondition apiPattern = new PatternsRequestCondition(API_PATH_PREFIX)
                        .combine(mapping.getPatternsCondition());
    
                mapping = new RequestMappingInfo(mapping.getName(), apiPattern, mapping.getMethodsCondition(),
                        mapping.getParamsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(),
                        mapping.getProducesCondition(), mapping.getCustomCondition());
            }
            super.registerHandlerMethod(handler, method, mapping);
        }
    }

    }

यह एमएच-देव द्वारा पोस्ट किए गए समाधान के समान है , लेकिन मुझे लगता है कि यह थोड़ा क्लीनर है और इसे 2.0.0+ सहित स्प्रिंग बूट 1.4.0+ के किसी भी संस्करण पर समर्थित होना चाहिए।


मैं अपने RestControler, एपीआई / कुछ में पृष्ठांकन योग्य उपयोग कर रहा हूँ, तो मुझे देता है कोई प्राथमिक या डिफ़ॉल्ट निर्माता इंटरफ़ेस org.springframework.data.domain.Pageable के लिए मिला
लालकृष्ण अयूब

0

प्रति स्प्रिंग डेटा रीस्ट डॉक्स , यदि एप्लिकेशन का उपयोग कर रहे हैं। तो , अपना आधार पथ सेट करने के लिए इस संपत्ति का उपयोग करें:

spring.data.rest.basePath=/api

लेकिन ध्यान दें कि वसंत आरामदायक बंधन का उपयोग करता है , इसलिए इस भिन्नता का उपयोग किया जा सकता है:

spring.data.rest.base-path=/api

... या यह एक अगर आप पसंद करते हैं:

spring.data.rest.base_path=/api

यदि आप application.yml का उपयोग कर रहे हैं , तो आप कुंजी विभाजकों के लिए कॉलन का उपयोग करेंगे:

spring:
  data:
    rest:
      basePath: /api

(संदर्भ के लिए, डॉक्स को स्पष्ट करने के लिए मार्च 2018 में एक संबंधित टिकट बनाया गया था।)



0

आप अपने नियंत्रकों के लिए एक कस्टम एनोटेशन बना सकते हैं:

अपने नियंत्रक वर्गों पर सामान्य @RestController के बजाय इसका उपयोग करें और @RequestMapping के साथ तरीकों को एनोटेट करें।

वसंत 4.2 में ठीक काम करता है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.