У меня проблема с развертыванием файла demo-boot-2.war на tomcat 9. Когда я запускаю Tomcat на localhost: 8081 / demo-boot-2 и запускаю сервер в наборе инструментов Spring, все, что я получаю, это (показано на рисунке):
Изображение веб-приложения
На рисунке выше показано, что оно объединяет представления папок и исполнителей. Это должны быть представления / певцы, а не зрители. Я не знаю, как это исправить. Мой код: Контроллер:
package com.example.demo.web;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.demo.entities.Singer;
import com.example.demo.services.SingerService;
@RequestMapping("/singers")
@Controller
public class SingerController {
private final Logger logger = LoggerFactory.getLogger(SingerController.class);
private SingerService singerService;
//private MessageSource messageSource;
@RequestMapping(method = RequestMethod.GET)
public String list(Model uiModel) {
logger.info("Listing singers");
List<Singer> singers = singerService.findAll();
uiModel.addAttribute("singers", singers);
logger.info("No. of singers: " + singers.size());
return "singers/list";
}
@Autowired
public void setSingerService(SingerService singerService) {
this.singerService = singerService;
}
}
Службы и инициализатор базы данных:
package com.example.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.entities.Singer;
import com.example.demo.repos.SingerRepository;
import com.google.common.collect.Lists;
@Transactional
@Service("singerService")
public class **SingerServiceImpl** implements SingerService {
private SingerRepository singerRepository;
@Override
@Transactional(readOnly = true)
public List<Singer> findAll() {
return Lists.newArrayList(singerRepository.findAll());
}
@Override
@Transactional(readOnly = true)
public Singer findById(Long id) {
return singerRepository.findById(id).get();
}
@Override
public Singer save(Singer singer) {
return singerRepository.save(singer);
}
@Autowired
public void setSingerRepository(SingerRepository singerRepository) {
this.singerRepository = singerRepository;
}
@Override
@Transactional(readOnly = true)
public Page<Singer> findAllByPage(Pageable pageable) {
return singerRepository.findAll(pageable);
}
}
package com.example.demo.services;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.example.demo.entities.Singer;
public interface **SingerService** {
List<Singer> findAll();
Singer findById(Long id);
Singer save(Singer singer);
Page<Singer> findAllByPage(Pageable pageable);
}
package com.example.demo.services;
import java.sql.Date;
import java.util.GregorianCalendar;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.entities.Singer;
@Service
public class **DBInitializer** {
private Logger logger = LoggerFactory.getLogger(DBInitializer.class);
@Autowired
SingerService singerService;
@PostConstruct
public void initDB() {
logger.info("Starting database initialization...");
Singer singer = new Singer();
singer.setFirstName("John");
singer.setLastName("Mayer");
singer.setBirthDate(new Date(
(new GregorianCalendar(1977, 9, 16)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Eric");
singer.setLastName("Clapton");
singer.setBirthDate(new Date(
(new GregorianCalendar(1945, 2, 30)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("John");
singer.setLastName("Butler");
singer.setBirthDate(new Date(
(new GregorianCalendar(1975, 3, 1)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("B.B.");
singer.setLastName("King");
singer.setBirthDate(new Date(
(new GregorianCalendar(1925, 9, 16)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Jimi");
singer.setLastName("Hendrix");
singer.setBirthDate(new Date(
(new GregorianCalendar(1942, 11, 27)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Jimmy");
singer.setLastName("Page");
singer.setBirthDate(new Date(
(new GregorianCalendar(1944, 1, 9)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Eddie");
singer.setLastName("Van Halen");
singer.setBirthDate(new Date(
(new GregorianCalendar(1955, 1, 26)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Saul (Slash)");
singer.setLastName("Hudson");
singer.setBirthDate(new Date(
(new GregorianCalendar(1965, 7, 23)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Stevie");
singer.setLastName("Ray Vaughan");
singer.setBirthDate(new Date(
(new GregorianCalendar(1954, 10, 3)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("David");
singer.setLastName("Gilmour");
singer.setBirthDate(new Date(
(new GregorianCalendar(1946, 3, 6)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Kirk");
singer.setLastName("Hammett");
singer.setBirthDate(new Date(
(new GregorianCalendar(1992, 11, 18)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Angus");
singer.setLastName("Young");
singer.setBirthDate(new Date(
(new GregorianCalendar(1955, 3, 31)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Dimebag");
singer.setLastName("Darrell");
singer.setBirthDate(new Date(
(new GregorianCalendar(1966, 8, 20)).getTime().getTime()));
singerService.save(singer);
singer = new Singer();
singer.setFirstName("Carlos");
singer.setLastName("Santana");
singer.setBirthDate(new Date(
(new GregorianCalendar(1947, 7, 20)).getTime().getTime()));
singerService.save(singer);
logger.info("Database initialization finished.");
}
}
Репозиторий:
package com.example.demo.repos;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.example.demo.entities.Singer;
public interface SingerRepository extends PagingAndSortingRepository<Singer, Long> {
}
Объект:
package com.example.demo.entities;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import static javax.persistence.GenerationType.IDENTITY;
@Entity
@Table(name = "singer")
public class Singer implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID")
private Long id;
@Version
@Column(name = "VERSION")
private int version;
@NotEmpty(message = "{validation.firstname.NotEmpty.message}")
@Size(min = 3, max = 60, message = "{validation.firstname.Size.message}")
@Column(name = "FIRST_NAME")
private String firstName;
@NotEmpty(message = "{validation.lastname.NotEmpty.message}")
@Size(min = 1, max = 40, message = "{validation.lastname.Size.message}")
@Column(name = "LAST_NAME")
private String lastName;
@Temporal(TemporalType.DATE)
@Column(name = "BIRTH_DATE")
private Date birthDate;
@Column(name = "DESCRIPTION")
private String description;
@Basic(fetch = FetchType.LAZY)
@Lob
@Column(name = "PHOTO")
private byte[] photo;
public Long getId() {
return id;
}
public int getVersion() {
return version;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setId(Long id) {
this.id = id;
}
public void setVersion(int version) {
this.version = version;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Date getBirthDate() {
return birthDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public byte[] getPhoto() {
return photo;
}
public void setPhoto(byte[] photo) {
this.photo = photo;
}
@Transient
public String getBirthDateString() {
String birthDateString = "";
if (birthDate != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
birthDateString = sdf.format(birthDate);
}
return birthDateString;
}
@Override
public String toString() {
return "Singer - Id: " + id + ", First name: " + firstName + ", Last name: " + lastName + ", Birthday: "
+ birthDate + ", Description: " + description;
}
}
WebInitializer и SecurityWebApplicationInitializer:
package com.example.demo.init;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.example.demo.config.DataServiceConfig;
import com.example.demo.config.SecurityConfig;
import com.example.demo.config.WebConfig;
import javax.servlet.Filter;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { SecurityConfig.class, DataServiceConfig.class };
}//,
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setEncoding("UTF-8");
cef.setForceEncoding(true);
return new Filter[] { new HiddenHttpMethodFilter(), cef };
}
}
package com.example.demo.init;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
Классы конфигурации:
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.example.demo" })
public class WebConfig implements WebMvcConfigurer {
//Declare the static resources.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/").setCachePeriod(31556926);
}
@Bean
InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views");
resolver.setSuffix(".jspx");
resolver.setRequestContextAttribute("requestContext");
return resolver;
}
// <=> <mvc:view-controller .../>
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("singers/list");
}
//<=> <mvc:default-servlet-handler/>
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("user")
.password(passwordEncoder.encode("user")).roles("USER");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/*").permitAll().and().formLogin().usernameParameter("username")
.passwordParameter("password").loginProcessingUrl("/login").loginPage("/singers")
.failureUrl("/security/loginfail").defaultSuccessUrl("/singers").permitAll().and().logout()
.logoutUrl("/logout").logoutSuccessUrl("/singers").and().csrf().disable();
// csrfTokenRepository(repo());
}
// @Bean
public CsrfTokenRepository repo() {
HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
repo.setParameterName("_csrf");
repo.setHeaderName("X-CSRF-TOKEN");
return repo;
}
}
package com.example.demo.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableJpaRepositories(basePackages = { "com.example.demo.repos" })
@ComponentScan(basePackages = { "com.example.demo.services" })
public class DataServiceConfig {
private static Logger logger = LoggerFactory.getLogger(DataServiceConfig.class);
@Bean
public DataSource dataSource() {
try {
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
return dbBuilder.setType(EmbeddedDatabaseType.H2).build();
} catch (Exception e) {
logger.error("Embedded DataSource bean cannot be created!", e);
return null;
}
}
@Bean
public Properties hibernateProperties() {
Properties hibernateProp = new Properties();
hibernateProp.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
hibernateProp.put("hibernate.hbm2ddl.auto", "create-drop");
hibernateProp.put("hibernate.show_sql", true);
hibernateProp.put("hibernate.max_fetch_depth", 3);
hibernateProp.put("hibernate.jdbc.batch_size", 10);
hibernateProp.put("hibernate.jdbc.fetch_size", 50);
return hibernateProp;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPackagesToScan("com.example.demo.entities");
factoryBean.setDataSource(dataSource());
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.setJpaProperties(hibernateProperties());
factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
factoryBean.afterPropertiesSet();
return factoryBean.getNativeEntityManagerFactory();
}
}
list.jspx в // src / main / webapp / WEB-INF / views / singers / list.jspx ниже:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:spring="http://www.springframework.org/tags"
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt" version="2.0">
<h1>Singer Listing</h1>
<c:if test="${not empty singers}">
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Birth Date</th>
</tr>
</thead>
<tbody>
<c:forEach items="${singers}" var="singer">
<tr>
<td>${singer.firstName}</td>
<td>${singer.lastName}</td>
<td><fmt:formatDate value="${singer.birthDate}"/></td>
</tr>
</c:forEach>
</tbody>
</table>
</c:if>
</div>
Может кто-нибудь помочь мне?