<dd id="saiiy"></dd>
  1. <s id="saiiy"></s>

    1. <s id="saiiy"></s>
      1. <span id="saiiy"><blockquote id="saiiy"></blockquote></span>

        Java,for,Web學(xué)習筆記(八一):RESTful(1)設置Rest,Contextx

        發(fā)布時(shí)間:2024-10-31 13:27:03   來(lái)源:黨團工作    點(diǎn)擊:   
        字號:

         Java for Web 學(xué)習筆記(八一):RESTful (1 )設置 Rest Context Wei:我想了想,還是小步快跑,控制每篇學(xué)習筆記的篇幅。

         我們將給出 Rest Context 和 web Context 共存的例子。Service 是方在 Root Context 的,Controller 則是位于下一級的 Rest Context 或者 web context,需要能夠識別掃描,最簡(jiǎn)單的,我們可以將它們分別放在不同的 package 中,通過(guò)@ComponentScan 中的 basePackages,掃描不同的位置來(lái)實(shí)現。這種方式能適應大部分的場(chǎng)景。但在小例子中,我們采用另一種方式,通過(guò)定義不同的標記來(lái)進(jìn)行區分這個(gè) controller 是屬于 rest 的還是 web 的。

         定 義繼承@Controller 的標記:@WebController 和@RestEndpoint 我們定義@WebController,用來(lái)標記 web context 下的 controller。標記在之前的validator 中已經(jīng)學(xué)過(guò)。

         @Target({ElementType.TYPE})

         @Retention(RetentionPolicy.RUNTIME)

         @Documented

         @Controller

         //繼承@Controller

         public @interface WebController {

          //和其他的 spring 的標記一樣,提供一個(gè)可以覆蓋的方法,用于設置 bean 名字。

         String value() default "";

         }

         定義@RestEndpoint,用于 Restful 網(wǎng)絡(luò )接口 @Target({ElementType.TYPE})

         @Retention(RetentionPolicy.RUNTIME)

         @Documented

         @Controller

         public @interface RestEndpoint {

         String value() default "";

         }

         實(shí)現 REST 上下文的配置 REST 用于機器對機器,其上下文環(huán)境更為簡(jiǎn)單,不需要那么多的 message converters,小例子只需要對 json 或者 xml 進(jìn)行解析和封裝,不需要ViewResolver,RequestToViewNameResolver。

         //【1】掃描帶有@RestEndpoint 標記

         @Configuration

         @EnableWebMvc

         @ComponentScan(

         basePackages = "cn.wei.chapter17.site",

         useDefaultFilters = false,

         includeFilters = @ComponentScan.Filter({RestEndpoint.class}))

         public class RestServletContextConfiguration extends WebMvcConfigurerAdapter{

         // 之前已經(jīng)在強大的生態(tài)中講過(guò)對于 Json 和 XML,并不需要手動(dòng)設置 codec 的轉換器,Spring 能夠自動(dòng)在 lib 中找到合適的。這里沿用書(shū)中例子

         @Inject ObjectMapper objectMapper;

         @Inject Marshaller marshaller;

         @Inject Unmarshaller unmarshaller;

         //【2】驗證在 RESTful 接口很重要,要加上

         @Inject SpringValidatorAdapter validator;

          //【3】消息格式支持 Json 和 XML 兩種

         //(3.1) 根據 Content-Type 加上相關(guān)的轉換器作。

         @Override

         public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

         converters.add(new SourceHttpMessageConverter<>());

          MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();

         xmlConverter.setSupportedMediaTypes(Arrays.asList( new MediaType("application", "xml"),

          new MediaType("text", "xml")));

         xmlConverter.setMarshaller(this.marshaller);

         xmlConverter.setUnmarshaller(this.unmarshaller);

         converters.add(xmlConverter);

          MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();

         jsonConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("application", "json"),

          new MediaType("text", "json")));

         jsonConverter.setObjectMapper(this.objectMapper);

         converters.add(jsonConverter);

         }

          //(3.2) 對媒體格式的協(xié)商。如果請求中 Accept: application/xml,則采用 xml 的方式,若支持 json 和 xml,其先后順序具有優(yōu)先級別;若無(wú)相關(guān)信息,采用缺省的 json

         @Override

         public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

         configurer.favorPathExtension(false).favorParameter(false)

         .ignoreAcceptHeader(false)

         .defaultContentType(MediaType.APPLICATION_JSON); //缺

         省采用 json 方式

         }

          //(2.1) 設置 validator

         @Override

         public Validator getValidator() {

         return this.validator;

         }

          //(2.2) 設置 locale 解析器,可對 Restful 接口的返回信息進(jìn)行本地化,通常是錯誤信息。REST 沒(méi)有 session,根據 Accept-Language 獲取

          @Bean

         public LocaleResolver localeResolver(){

         return new AcceptHeaderLocaleResolver();

         }

          }

         WebServletContextConfiguration 和以前學(xué)習的沒(méi)有什么區別,只是在掃描是針對@WebController。

         依次啟動(dòng)不同的上下文 我們將在 Bootstrap 類(lèi)中一次啟動(dòng) Root 上下文,Web 上下文,和 Rest 上下文

         public class Bootstrap implements WebApplicationInitializer{

          @Override

         public void onStartup(ServletContext container) throws ServletException {

         container.getServletRegistration("default").addMapping("/resource/*");

          //(1)啟動(dòng) root 上下文

         AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

         rootContext.register(RootContextConfiguration.class);

         container.addListener(new ContextLoaderListener(rootContext));

          //(2)啟動(dòng) web 上下文

         AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();

         webContext.register(WebServletContextConfiguration.class);

         ServletRegistration.Dynamic dispatcher = container.addServlet(

         "springWebDispatcher", new DispatcherServlet(webContext));

         dispatcher.setLoadOnStartup(1);

         dispatcher.setMultipartConfig(new MultipartConfigElement(null, 20_971_520L, 41_943_040L, 512_000));

         dispatcher.addMapping("/");

          //(3)啟動(dòng) Rest 上下文,spring 將采用最佳匹配的方式,和 web 上下文的"/"不矛盾。

         AnnotationConfigWebApplicationContext restContext = new AnnotationConfigWebApplicationContext();

         restContext.register(RestServletContextConfiguration.class);

         // 小例子測試 OPTIONS,需要支持 OPTIONS,將此開(kāi)關(guān)打開(kāi)。FrameworkServlet 中此值為 false,但在 spring 4.3,已經(jīng)內置為 true。我們使用了 4.3.9.RELEASE,實(shí)際上無(wú)需手動(dòng)設置為 true。

         // ? false 為采用自動(dòng)處理,將會(huì )回復 200OK,body 長(cháng)度為 0;

         // ? true 將轉到我們的代碼處理,如果 url 沒(méi)有匹配,會(huì )回復 404。

         // DispatcherServlet restServlet = new DispatcherServlet(restContext);

         // restServlet.setDispatchOptionsRequest(true);

         // dispatcher = container.addServlet("springRestDispatcher", restServlet);

         dispatcher = container.addServlet("springRestDispatcher", new DispatcherServlet(restContext));

         dispatcher.setLoadOnStartup(2);

         dispatcher.addMapping("/services/Rest/*");

         //我們希望對無(wú)效的 url 進(jìn)行自定義的 404 回復(返回一個(gè) json 或者 xml 說(shuō)明),而非缺省方式(缺省返回一個(gè)頁(yè)面),需要將 NoHandlerFoundException 拋出,在代碼中處理,而非默認的 servlet 自行處理。

         dispatcher.setInitParameter("throwExceptionIfNoHandlerFound", "true");

          }

         }

          相關(guān)鏈接:

         我的 Professional Java for Web Applications 相關(guān)文章

        国产另类无码专区|日本教师强伦姧在线观|看纯日姘一级毛片|91久久夜色精品国产按摩|337p日本欧洲亚洲大胆精

        <dd id="saiiy"></dd>
        1. <s id="saiiy"></s>

          1. <s id="saiiy"></s>
            1. <span id="saiiy"><blockquote id="saiiy"></blockquote></span>