我正在尝试使用自定义注释从Controller中记录所有方法并通过JPARepository
保存到数据库当我运行时,没有任何内容被写入" logs"表 我是堆栈和Java Spring的新手,所以请备用错误并根据需要更正。
package com.davidoladeji.epx.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {
String page();
String action();
String description();
}
package com.davidoladeji.epx.controller;
import com.davidoladeji.epx.annotation.Loggable;
import com.davidoladeji.epx.model.*;
import com.davidoladeji.epx.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
import java.util.List;
import java.util.Locale;
@Controller
@SessionAttributes("airplane")
public class AirplaneController {
@Autowired
JobRepository jobRepository;
@Autowired
AirplaneRepository airplaneRepository;
@Autowired
QualificationRepository qualificationRepository;
@Autowired
UserRepository userRepository;
@Autowired
LogRepository logRepository;
@ModelAttribute("airplane")
public Airplane createModel() {
return new Airplane();
}
@Loggable(page="Airplane", action ="Changed Page to All Airplanes", description = "Entered List of all Airplanes Page")
@RequestMapping(value = "/allairplanes", method = RequestMethod.GET)
public ModelAndView allJobs(ModelAndView modelx) {
List<Airplane> airplanes = airplaneRepository.findAll();
modelx.addObject("airplanex", airplanes);
modelx.addObject("title", "AirX System: All Airplanes");
modelx.setViewName("allairplanes");
//Get List of All Managers for Statistics
List<User> managers = userRepository.findByUserRole_Rolename("ROLE_ADMIN");
modelx.addObject("managerx", managers);
//Get List of All Engineers for Statistics
List<User> engineers = userRepository.findByUserRole_Rolename("ROLE_USER");
modelx.addObject("engineerx", engineers);
//Get List of All Jobs for Statistics
List<Job> alljobs = jobRepository.findAll();
modelx.addObject("jobx", alljobs);
//Personalisation
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
//get user role to determine stuff to display like username and dashboard title
Role usersrole = new Role();
boolean isAdminhasRolen = usersrole.hasRole("ROLE_ADMIN");
UserDetails userDetail = (UserDetails) auth.getPrincipal();
if (isAdminhasRolen) {
modelx.addObject("title", "AirX System: Administrator Dashboard");
modelx.addObject("userrolelabel", "Administrator");
} else {
modelx.addObject("title", "AirX System: Engineer Dashboard");
modelx.addObject("userrolelabel", "Engineer");
}
modelx.addObject("username", userDetail.getUsername());
//General Stuff for Display ends
return modelx;
}
@Loggable(page="Airplane", action ="Changed Page to New Airplane", description = "Entered New Airplanes Page")
@RequestMapping(value = "/newairplane", method = RequestMethod.GET)
public ModelAndView newAirplane(Locale locale, ModelAndView modelx) {
List<Airplane> airplanes = airplaneRepository.findAll();
modelx.addObject("airplanex", airplanes);
//////////////////////////////////////////////////////////
//Get List of All Managers for Statistics
List<User> managers = userRepository.findByUserRole_Rolename("ROLE_ADMIN");
modelx.addObject("managerx", managers);
//Get List of All Engineers for Statistics
List<User> engineers = userRepository.findByUserRole_Rolename("ROLE_USER");
modelx.addObject("engineerx", engineers);
//Get List of All Jobs for Statistics
List<Job> alljobs = jobRepository.findAll();
modelx.addObject("jobx", alljobs);
//Personalisation
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
//get user role to determine stuff to display like username and dashboard title
Role usersrole = new Role();
boolean isAdminhasRolen = usersrole.hasRole("ROLE_ADMIN");
UserDetails userDetail = (UserDetails) auth.getPrincipal();
if (isAdminhasRolen) {
modelx.addObject("title", "AirX System: Administrator Dashboard");
modelx.addObject("userrolelabel", "Administrator");
} else {
modelx.addObject("title", "AirX System: Engineer Dashboard");
modelx.addObject("userrolelabel", "Engineer");
}
modelx.addObject("username", userDetail.getUsername());
//General Stuff for Display ends
modelx.setViewName("newairplane");
return modelx;
}
@Loggable(page="Airplane", action ="Added Airplane", description = "Clicked on add airplane button")
@RequestMapping(value = "/addairplane", method = RequestMethod.POST)
@Transactional
public String addAirplane(@Valid Airplane airplane, BindingResult result) {
if (result.hasErrors()) {
return "redirect:/newairplane";
} else {
airplaneRepository.save(airplane);
return "redirect:/allairplanes";
}
// return "redirect:/";
}
@Loggable(page="Airplane", action ="Delete Airplane", description = "Clicked on Delete Airplanes Button")
@RequestMapping(value = "/delete/airplane/{airplane}", method = RequestMethod.POST)
@Transactional
public String deleteAirplane(@PathVariable("airplane") Long airplaneId, ModelAndView modelx) {
airplaneRepository.delete(airplaneRepository.findOne(airplaneId));
return "redirect:/allairplanes";
}
@Loggable(page="Airplane", action ="Changed Page to Single-Edit Airplane", description = "Entered Edit Airplanes Page")
@RequestMapping(value = "/edit/airplane/{airplane}", method = RequestMethod.GET)
public ModelAndView editAirplane(Locale locale, ModelAndView modelx) {
modelx.setViewName("editairplane");
return modelx;
}
}
@Aspect
public class LoggableAdvice {
@Autowired
private LoggableService loggableService;
@Before("execution(public String com.davidoladeji.epx.controller.*Controller.*(..)) && @annotation(logAnnotation) ")
public void myBeforeLogger(Loggable logAnnotation) {
loggableService.saveLog(logAnnotation.page(), logAnnotation.action(), logAnnotation.description());}
}
@Entity
@Table(name = "logs")
public class MyLog {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", unique = true, nullable = false)
private long id;
private String action;
private String description;
private String page;
private String date;
private String time;
private String username;
private String role;
public MyLog() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
}
package com.davidoladeji.epx.service;
import com.davidoladeji.epx.log.MyLog;
import com.davidoladeji.epx.repository.LogRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
@Service
public class LoggableService{
private static Logger logger = LoggerFactory.getLogger(LoggableService.class);
Locale locale = new Locale(Locale.UK.toString());
@Autowired
LogRepository logRepository;
String username, userrole, currentdate, currenttime, datetime;
/**
* Log the current page and store details to a Log Instance and Save Via Repository to DB the logger checks*/
public void saveLog(String page, String action, String description) {
String username = getCurrentUsername();
String date = getCurrentDate();
String time = getCurrentTime();
String userrole = getCurrentUserRole();
MyLog myLog = new MyLog();
myLog.setUsername(username);
myLog.setAction(action);
myLog.setDate(date);
myLog.setTime(time);
myLog.setDescription(description);
myLog.setPage(page);
myLog.setRole(userrole);
logRepository.save(myLog);
logger.info("CUSTOM LOG: {} - {}", username +"\n"+ page +"\n"+ action +"\n"+ description);
}
private String getCurrentUsername() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetail = (UserDetails) auth.getPrincipal();
username = userDetail.getUsername();
return username;
}
private String getCurrentUserRole() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails userDetail = (UserDetails) auth.getPrincipal();
userrole = userDetail.getAuthorities().toString();
return userrole;
}
public String getCurrentDate() {
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
currentdate = dateFormat.format(date);
return currentdate;
}
public String getCurrentTime() {
Date date = new Date();
DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
currenttime = dateFormat.format(date);
return currenttime;
}
public String getCurrentDateTime() {
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
datetime = dateFormat.format(date);
return datetime;
}
}
我离开了名称空间(希望不是问题)。虽然使用Spring 3.25和IntelliJ(如果这很重要)
的applicationContext.xml
<beans>
<context:property-placeholder properties-ref="deployProperties"/>
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config/>
<!--I need this for all packages to be scanned -->
<!-- check for duplicates: DONE -->
<context:component-scan base-package="com.davidoladeji.epx">
<context:include-filter type="aspectj"
expression="com.davidoladeji.epx.log.LoggableAdvice" />
</context:component-scan>
<!-- Configures the annotation-driven Spring MVC Controller programming model.
Note that, with Spring 3.0, this tag works in Servlet MVC only! -->
<mvc:annotation-driven/>
<mvc:resources mapping="/resources/**" location="/resources/"/>
<!-- Imports logging configuration -->
<import resource="tracers-context.xml"/>
<!-- Imports datasource configuration -->
<import resource="spring-data.xml"/>
<bean id="deployProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
p:location="/WEB-INF/spring.properties"/>
<!--<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>-->
MVC-调度-servlet.xml中
<bean>
<context:component-scan base-package="com.davidoladeji.epx"/>
<mvc:annotation-driven/>
<mvc:resources mapping="/css/**" location="resources/assets/css/"/>
<mvc:resources mapping="/images/**" location="resources/assets/images/"/>
<mvc:resources mapping="/js/**" location="resources/assets/js/"/>
<mvc:resources mapping="/fonts/**" location="resources/assets/fonts/"/>
<mvc:resources mapping="/img/**" location="resources/assets/img/"/>
<mvc:resources mapping="/prettify/**" location="resources/assets/prettify/"/>
<mvc:resources mapping="/ajax/**" location="resources/assets/ajax/"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--<bean id="loggingAspect" class="com.davidoladeji.epx.log.LoggableAdvice"/>
<bean class="com.davidoladeji.epx.service.LoggableService"/>-->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
Spring-data.xml
<beans>
<context:property-placeholder properties-ref="deployProperties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Activate Spring Data JPA repository support -->
<jpa:repositories base-package="com.davidoladeji.epx.repository"/>
<!-- Declare a datasource that has pooling capabilities-->
<bean id="jpaDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10"/>
<!-- Declare a JPA entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
p:persistenceUnitName="hibernatePersistenceUnit"
p:dataSource-ref="jpaDataSource"
p:jpaVendorAdapter-ref="hibernateVendor"/>
<!-- Specify ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false"/>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
</beans>
web.xml
<web-app>
<display-name>Spring MVC Application</display-name>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name>
<param-value>en</param-value>
</context-param>-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/404.jsp</location>
</error-page>
</web-app>
AOP配置在这里
示踪剂context.xml中
<beans>
<bean id="customizableTraceInterceptor" class="com.davidoladeji.epx.model.itools.Tracer"
p:enterMessage="Entering $[targetClassShortName].$[methodName]($[arguments])"
p:exitMessage="Leaving $[targetClassShortName].$[methodName](): $[returnValue]"/>
<aop:aspectj-autoproxy/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- e.g. getUserRoles in LoginService-->
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userServicePointCut"
expression="execution(* com.davidoladeji.epx.service.*Service.*(..))"/>
<!--Where should the advice be applied all files ending with Service-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointCut"/>
</aop:config>
</beans>