日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC:带有CNVR卷的REST应用程序。 1个

發(fā)布時(shí)間:2023/12/3 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC:带有CNVR卷的REST应用程序。 1个 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

不久前,我閱讀了Paul Chapman撰寫的有關(guān)內(nèi)容協(xié)商視圖解析器 (CNVR)的文章。 Spring Framework Blog上的那篇文章啟發(fā)了我研究這個(gè)框架的領(lǐng)域。 因此,我開發(fā)了一個(gè)基于Spring MVC和CNVR的 REST示例應(yīng)用程序。 該應(yīng)用程序演示了REST服務(wù)的基本流程-實(shí)體的創(chuàng)建,刪除,讀取和版本。

Spring Framework很長時(shí)間以來都支持REST服務(wù),您可以更早地使用Message Converters開發(fā)一些服務(wù)。 在Spring 3.2中,所有這些東西在配置和開發(fā)中變得更加容易。 因此,讓我們停止交談,因?yàn)槲覍⒄故編в蠧NVR的Spring REST服務(wù)的基本設(shè)置和開發(fā)。

CNVR的基本思想是,根據(jù)CNVR從客戶端請(qǐng)求中獲取的信息,定義資源的哪種表示形式回饋給客戶端。 您可以問我:請(qǐng)求中可影響CNVR決策的信息是什么? 答案很簡單:

  • 網(wǎng)址后綴(例如.xml,.json,.html等
  • URL參數(shù)(默認(rèn)格式 )
  • HTTP Accept標(biāo)頭屬性

這是高級(jí)CNVR工作流程的圖示:

有關(guān)更多信息,我建議閱讀Paul Chapman的完整文章。

使用CNVR設(shè)置Spring MVC REST項(xiàng)目

我將與一個(gè)Maven項(xiàng)目一起工作,一如既往,我將提供一個(gè)指向項(xiàng)目的GitHub存儲(chǔ)庫的鏈接。 這是整個(gè)項(xiàng)目的屏幕截圖:

我已經(jīng)多次解釋了如何在Eclipse中設(shè)置Dynamic Web Project,因此現(xiàn)在我僅提供帶有一些簡短說明的源文件。 您可以在下面找到所需的Maven依賴項(xiàng):

<properties><mysql.connector>5.1.25</mysql.connector><hibernate.version>4.2.3.Final</hibernate.version><spring.version>3.2.3.RELEASE</spring.version><spring.data.version>1.3.2.RELEASE</spring.data.version><jackson.version>1.9.12</jackson.version></properties><dependencies><!-- DataBase libs --><dependency><groupid>mysql</groupid><artifactid>mysql-connector-java</artifactid><version>${mysql.connector}</version></dependency><dependency><groupid>commons-dbcp</groupid><artifactid>commons-dbcp</artifactid><version>1.4</version></dependency><!-- Hibernate --><dependency><groupid>org.hibernate</groupid><artifactid>hibernate-core</artifactid><version>${hibernate.version}</version></dependency><dependency><groupid>org.hibernate</groupid><artifactid>hibernate-entitymanager</artifactid><version>${hibernate.version}</version></dependency><!-- Spring --><dependency><groupid>org.springframework</groupid><artifactid>spring-webmvc</artifactid><version>${spring.version}</version></dependency><dependency><groupid>org.springframework.data</groupid><artifactid>spring-data-jpa</artifactid><version>${spring.data.version}</version><exclusions><exclusion><artifactid>spring-aop</artifactid><groupid>org.springframework</groupid></exclusion></exclusions></dependency><dependency><groupid>org.springframework</groupid><artifactid>spring-orm</artifactid><version>${spring.version}</version></dependency><dependency><groupid>org.springframework</groupid><artifactid>spring-tx</artifactid><version>${spring.version}</version></dependency><!-- CGLIB is required to process @Configuration classes --><dependency><groupid>cglib</groupid><artifactid>cglib</artifactid><version>3.0</version></dependency><!-- Other --><dependency><groupid>javax.servlet</groupid><artifactid>javax.servlet-api</artifactid><version>3.0.1</version><scope>provided</scope></dependency><dependency><groupid>jstl</groupid><artifactid>jstl</artifactid><version>1.2</version></dependency><!-- CNVR resources --><dependency><groupid>org.codehaus.jackson</groupid><artifactid>jackson-mapper-asl</artifactid><version>${jackson.version}</version></dependency></dependencies>

您可以在GitHub上找到pom.xml文件的完整版本。 因此,讓我們繼續(xù)進(jìn)行準(zhǔn)備。 我將使用MySQL作為數(shù)據(jù)庫。 我需要在其中創(chuàng)建一個(gè)下表:

CREATE TABLE `smartphones` (`id` int(6) NOT NULL AUTO_INCREMENT,`producer` varchar(20) NOT NULL,`model` varchar(20) NOT NULL,`price` double NOT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

現(xiàn)在我們需要適當(dāng)?shù)膉ava對(duì)象,它將代表智能手機(jī)表:

@Entity @Table(name="smartphones") public class Smartphone {@Id@GeneratedValueprivate Integer id;private String producer;private String model;private double price;/*** Method updates already existed {@link Smartphone} object with values from the inputed argument.* @param sPhone - Object which contains new Smartphone values.* @return {@link Smartphone} object to which this method applied.*/public Smartphone update(Smartphone sPhone) {this.producer = sPhone.producer;this.model = sPhone.model;this.price = sPhone.price;return this;}@Overridepublic String toString() {return producer+": "+model+" with price "+price;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getProducer() {return producer;}public void setProducer(String producer) {this.producer = producer;}public String getModel() {return model;}public void setModel(String model) {this.model = model;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}}

準(zhǔn)備工作大部分完成。 服務(wù)和DAO層是我需要做的最后一件事。 我將使用Spring Data作為DAO層,在我以前的一篇文章中,我對(duì)它的設(shè)置進(jìn)行了詳細(xì)的回顧。

public interface SmartphoneRepository extends JpaRepository< Smartphone, Integer >{ }

這里是對(duì)應(yīng)的服務(wù)接口及其實(shí)現(xiàn):

public interface SmartphoneService {public Smartphone create(Smartphone sp);public Smartphone get(Integer id);public List< Smartphone > getAll();public Smartphone update(Smartphone sp) throws SmartphoneNotFoundException;public Smartphone delete(Integer id) throws SmartphoneNotFoundException;}

服務(wù)實(shí)施:

@Service @Transactional(rollbackFor=SmartphoneNotFoundException.class) public class SmartphoneServiceImpl implements SmartphoneService {@Autowiredprivate SmartphoneRepository smartphoneRepository;@Overridepublic Smartphone create(Smartphone sp) {return smartphoneRepository.save(sp);}@Overridepublic Smartphone get(Integer id) {return smartphoneRepository.findOne(id);}@Overridepublic List< Smartphone > getAll() {return smartphoneRepository.findAll();}@Overridepublic Smartphone update(Smartphone sp) throws SmartphoneNotFoundException {Smartphone sPhoneToUpdate = get(sp.getId());if (sPhoneToUpdate == null)throw new SmartphoneNotFoundException(sp.getId().toString());sPhoneToUpdate.update(sp);return sPhoneToUpdate;}@Overridepublic Smartphone delete(Integer id) throws SmartphoneNotFoundException {Smartphone sPhone = get(id);if (sPhone == null)throw new SmartphoneNotFoundException(id.toString());smartphoneRepository.delete(id);return sPhone;} }

在項(xiàng)目設(shè)置的最后,讓我們考慮配置的“核心”: Initializer和WebAppConfig文件。

@Configuration @EnableWebMvc @EnableTransactionManagement @ComponentScan("com.mobapp") @PropertySource("classpath:application.properties") @EnableJpaRepositories("com.mobapp.repository") public class WebAppConfig extends WebMvcConfigurerAdapter {private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";private static final String PROPERTY_NAME_DATABASE_URL = "db.url";private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";@Resourceprivate Environment env;@Beanpublic DataSource dataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));return dataSource;}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();entityManagerFactoryBean.setDataSource(dataSource());entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);entityManagerFactoryBean. setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));entityManagerFactoryBean.setJpaProperties(hibProperties());return entityManagerFactoryBean;}private Properties hibProperties() {Properties properties = new Properties();properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));return properties; }@Beanpublic JpaTransactionManager transactionManager() {JpaTransactionManager transactionManager = new JpaTransactionManager();transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());return transactionManager;}@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer.favorPathExtension(true).useJaf(false).ignoreAcceptHeader(true).mediaType("html", MediaType.TEXT_HTML).mediaType("json", MediaType.APPLICATION_JSON).defaultContentType(MediaType.TEXT_HTML);}@Beanpublic ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {List< ViewResolver > resolvers = new ArrayList< ViewResolver >();InternalResourceViewResolver r1 = new InternalResourceViewResolver();r1.setPrefix("/WEB-INF/pages/");r1.setSuffix(".jsp");r1.setViewClass(JstlView.class);resolvers.add(r1);JsonViewResolver r2 = new JsonViewResolver();resolvers.add(r2);ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setViewResolvers(resolvers);resolver.setContentNegotiationManager(manager);return resolver;}/*** View resolver for returning JSON in a view-based system. Always returns a* {@link MappingJacksonJsonView}.*/public class JsonViewResolver implements ViewResolver {public View resolveViewName(String viewName, Locale locale)throws Exception {MappingJacksonJsonView view = new MappingJacksonJsonView();view.setPrettyPrint(true);return view;}}}

盡管文件足夠大,但我只想將您的注意力集中在幾件事上。 第一個(gè)是JsonViewResolver內(nèi)部類。 處理JSON請(qǐng)求是必需的。 當(dāng)然,可以將其與WebAppConfig類分開聲明,也可以將其導(dǎo)入其中。 但是我決定將其直接放在WebAppConfig中,以避免分散注意力。 第二個(gè)是configureContentNegotiation方法。 在這里,我為內(nèi)容協(xié)商視圖解析器設(shè)置了選項(xiàng)。 最后,在contentNegotiatingViewResolver bean中,我確定了哪些視圖解析器將在我的應(yīng)用程序中可用。

public class Initializer implements WebApplicationInitializer {private static final String DISPATCHER_SERVLET_NAME = "dispatcher";@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(WebAppConfig.class);ctx.setServletContext(servletContext); registerHiddenHttpMethodFilter(servletContext); Dynamic servlet = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(ctx));servlet.addMapping("/");servlet.setLoadOnStartup(1);}private void registerHiddenHttpMethodFilter(ServletContext servletContext) {FilterRegistration.Dynamic fr = servletContext.addFilter("hiddenHttpMethodFilter", HiddenHttpMethodFilter.class);fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), false, DISPATCHER_SERVLET_NAME);}}

在Initializer類中,本教程僅涉及一件事。 它是registerHiddenHttpMethodFilter方法。 此方法將有助于處理諸如PUT和DELETE之類的HTTP方法。

希望您不要感到疲倦,因?yàn)樽钣腥さ膬?nèi)容將在本教程的以下部分等您。

參考: Spring MVC:具有CNVR卷的REST應(yīng)用程序。 Fruzenshtein的筆記博客中來自JCG合作伙伴 Alexey Zvolinskiy的1 。

翻譯自: https://www.javacodegeeks.com/2013/07/spring-mvc-rest-application-with-cnvr-vol-1.html

總結(jié)

以上是生活随笔為你收集整理的Spring MVC:带有CNVR卷的REST应用程序。 1个的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。