Can't read .properties file from library to spring maven project - spring-mvc

I have one maven spring project (as a library) and I am adding it as a dependency into spring maven project(web service).
I have some properties files in both projects. In library there is one validationmessages.properties file.
I am using hibernate validator annotations on my model.
For example,
#NotBlank(message = "{NotBlank-entityId}")
Private String entityId;
The class model which is in library,using as a request body in webservice.here library hibernate validation messages are not working in webservice.
Here's the code:
Model:
Task.java (In library)
public class Task {
#NotBlank(message = "{NotNull-EntityID}")
private String entityId;
public String getEntityId() {
return entityId;
}
public void setEntityId(final String entityId) {
this.entityId = entityId;
}
}
Taskvalidationmessages.properties (In library)
NotNull-EntityID = Entity ID can not be null.
TaskManagementConfiguration.java (In library)
#Configuration
#PropertySources({ #PropertySource("classpath:queries.properties"),
#PropertySource("classpath:Taskvalidationmessages.properties") })
#Import(DataSourceConfiguration.class)
public class TaskManagementConfiguration {
}
TaskResource.java (Controller in webservice project)
#RequestMapping(value = WebserviceConstant.CREATE_TASK, method = RequestMethod.POST, produces = WebserviceConstant.APPLICATION_JSON)
public ResponseEntity<CreateTaskResponse> createTask(
#Valid #RequestBody final Task request,
#RequestHeader(value = "access-token") final String accessToken) {
return new ResponseEntity<CreateTaskResponse>(
taskService.createTask(request, receivedToken), HttpStatus.CREATED);
}
App.java (In Web service project)
#Configuration
#SpringBootApplication
#PropertySources({ #PropertySource("classpath:user-queries.properties") })
#Import({ TaskManagementConfiguration.class })
public class App {
public static void main(final String[] args) {
SpringApplication.run(App.class, args);
}
}
Whenever I hit the resource url with empty value of entityId.
It gives error like:
{
"fieldErrors": [
{
"field": "entityId",
"code": 200,
"message": "{NotNull-EntityID}"
}
]
}

Related

An error occurred when trying to create a controller of type 'XXXXController'. Make sure that the controller has a parameterless public constructor

I have created a asp.net web api project and implemented the below HTTP GET method in AccountController and the related service method & repository method in AccountService & AccountRepository respectively.
// WEB API
public class AccountController : ApiController
{
private readonly IAccountService _accountService;
public AccountController(IAccountService accountService)
{
_accountService = accountService;
}
[HttpGet, ActionName("UserProfile")]
public JsonResult<decimal> GetUserSalary(int userID)
{
var account = _accountService.GetUserSalary(userID);
if (account != null)
{
return Json(account.Salary);
}
return Json(0);
}
}
Service / Business Layer
public interface IAccountService
{
decimal GetUserSalary(int userId);
}
public class AccountService : IAccountService
{
readonly IAccountRepository _accountRepository = new AccountRepository();
public decimal GetUserSalary(int userId)
{
return _accountRepository.GetUserSalary(userId);
}
}
Repository / Data Access Layer
public interface IAccountRepository
{
decimal GetUserSalary(int userId);
}
public class AccountRepository : IAccountRepository
{
public decimal GetUserSalary(int userId)
{
using (var db = new AccountEntities())
{
var account = (from b in db.UserAccounts where b.UserID == userId select b).FirstOrDefault();
if (account != null)
{
return account.Salary;
}
}
return 0;
}
}
UnityConfig
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IAccountService, AccountService>();
container.RegisterType<IAccountRepository, AccountRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
But when I invoke the API method GetUserSalary() I get an error saying
An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor.
Check that you did not forget to register Unity IoC container itself:
if you use ASP.NET Framework it could be - Global.asax or Startap.cs (Owin) via UnityConfig.RegisterComponents() method.
if you use ASP.NET Core then in the Startup.cs file (I was unable to find official guides for its configuting)
Your current constructor has parameters (or args if you prefer).
see:
public AccountController(IAccountService accountService)
{
_accountService = accountService;
}
All you need to do is add a "Parameter-less Constructor" into the controller as well.
public AccountController()
{
}
Parameter-less constructors are usually above the ones that have params, though as far as I am aware this is only due to standards not any actual effect(s) it may cause.
There is also an already existing issue/question similar to this I will link below that may provide further details.
Make sure that the controller has a parameterless public constructor error

No mapping found for HTTP request with URI [/api/transactions] in DispatcherServlet with name ''

I thought this is a standard configuration. But I get a 404 back. Where else should I configure Spring Boot ?
#RestController
#RequestMapping("/api")
public class TransactionStatisticsController {
public static final Logger logger = LoggerFactory.getLogger(TransactionStatisticsController.class);
#RequestMapping(value = "/transactions",
method = RequestMethod.POST)
public ResponseEntity sendTransaction(#RequestBody Transaction request) {
logger.info( request.toString());
return new ResponseEntity(HttpStatus.OK);
}
}
This is my test.
#JsonTest
#SpringBootTest(classes = Application.class)
#AutoConfigureMockMvc
#RunWith(SpringRunner.class)
public class TransactionStatisticsRestTest {
#Autowired
private MockMvc mockMvc;
#Autowired
private JacksonTester<Transaction> json;
private static Transaction transaction;
#BeforeClass
public static void createTransaction(){
BigDecimal amount = new BigDecimal(12.3343);
transaction = new Transaction(amount.toString(),
"2010-10-02T12:23:23Z");
}
#Test
public void getTransactionStatus() throws Exception {
final String transactionJson = json.write(transaction).getJson();
mockMvc
.perform(post("/api/transactions")
.content(transactionJson)
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}
public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsBytes(transaction);
}
}
Request being made is
MockHttpServletRequest:
HTTP Method = POST
Request URI = /api/transactions
Parameters = {}
Headers = {Content-Type=[application/json;charset=UTF-8]}
Body = {"amount":"12.3343000000000007077005648170597851276397705078125","timestamp":"2010-10-02T12:23:23Z[UTC]"}
Session Attrs = {}
Handler:
Type = null
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Update : I added a component scan pointing to a base package. I don't see that error now. Please see the comments where there is an answer.
As in the comment section ,there was only requirement was to bind a component scan base package location .
#Component scan -->Configures component scanning directives for use with #Configuration classes. Provides support parallel with Spring XML's element.
Either basePackageClasses() or basePackages() (or its alias value()) may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
Please share your project folder architecture. It might be possible that your controller package is out of the main class package. That's why it is showing 404.
This code :
#RestController
#RequestMapping("/api")
public class TransactionStatisticsController {
public static final Logger logger = LoggerFactory.getLogger(TransactionStatisticsController.class);
#RequestMapping(value = "/transactions",
method = RequestMethod.POST)
public ResponseEntity sendTransaction(#RequestBody Transaction request) {
logger.info( request.toString());
return new ResponseEntity(HttpStatus.OK);
}
}
This should be into your main package where
#SpringBootApplication
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
this main class resides.
I hope, this will help.
Seems using #JsonTest does not even allow to load Application Context, results mapping is not loaded and its throw 404 so #JsonTest is not a replacement for #SpringBootTest, it is a way to easily test json serialization/de-serialization.
As per documentation:
you can use the #JsonTest annotation. #JsonTest auto-configures the
available supported JSON mapper, which can be one of the following
libraries:
Jackson ObjectMapper, any #JsonComponent beans and any Jackson Modules
Gson
Jsonb
If by using Gson and removing #JsonTest your test run fine..(add Gson Dependency in pom)
#SpringBootTest
#AutoConfigureMockMvc
#RunWith(SpringRunner.class)
public class DemoKj01ApplicationTests {
#Autowired
private MockMvc mockMvc;
private static Transaction transaction;
#BeforeClass
public static void createTransaction(){
BigDecimal amount = new BigDecimal(12.3343);
transaction = new Transaction(amount.toString(),
"2010-10-02T12:23:23Z");
}
#Test
public void getTransactionStatus() throws Exception {
//final String transactionJson = json.write(transaction).getJson();
Gson gson = new Gson();
String jsonRequest = gson.toJson(transaction);
mockMvc
.perform(post("/api/transactions")
.content(jsonRequest)
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}
It is beacause of the trailing slas in #RequestMapping(value = "/transactions/", method = RequestMethod.POST)
Remove it and it will be ok : value = "/transactions/" => value = "/transactions"

CordaApp with Spring Boot Api different response

I have integrated the cordapp with spring boot .One strange observation we found that the response differs coming from the cordawebserver and spring boot server for example
Blockquote
API :GET: market/me
gives
{
“me”: {
“commonName”: null,
“organisationUnit”: null,
“organisation”: “PartyG-CT”,
“locality”: “Tokyo”,
“state”: null,
“country”: “JP”,
“x500Principal”: {
“name”: “O=PartyG-CT,L=Tokyo,C=JP”,
“encoded”: “MDExCzAJBgNVBAYTAkpQMQ4wDAYDVQQHDAVUb2t5bzESMBAGA1UECgwJUGFydHlHLUNU”
}
}
}
with Spring boot
while with cordawebserver we are getting :
{
“me”: “C=JP,L=Tokyo,O=PartyG-CT”
}
Same behaviour we are finding the same for different APIs Any help will be appreciated
#GET
#Path("peers")
#Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
// CordaX500Name
public Map<String, List<CordaX500Name>> getPeers() {
List<NodeInfo> nodeInfoSnapshot = proxy.networkMapSnapshot();
return ImmutableMap.of(
"peers",
nodeInfoSnapshot
.stream()
.map(node -> node.getLegalIdentities().get(0).getName())
.filter(name -> !name.equals(myLegalName) && !name.getOrganisation().equals(controllerName)
&& !name.getOrganisation().equals(NETWORK_MAP_NAME))
.collect(toList()));
}
//boot entry point
#SpringBootApplication
public class FacilityServer {
#Autowired
public static NodeRPCConnection nodeRPCConnection;
/**
* Starts our Spring Boot application.
*/
public static void main(String[] args) throws Exception {
SpringApplication springApplication = new SpringApplication();
springApplication.setBannerMode(Banner.Mode.OFF);
springApplication.run(FacilityServer.class, args);
}
#EventListener(ApplicationReadyEvent.class)
public void initiateFacilityObserverPostStartup() throws Exception{
FacilityObserver.startFacilityWatch();
}
// this class for using the jersey instead of spring rest impltn
#Configuration
#ApplicationPath("rest")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
}
#PostConstruct
public void setUp() {
register(MarketApi.class);
//register(GenericExceptionMapper.class);
}
}
I found the solution ;According to the corda documentation we need to register cordajackson mapper .Then, we will be able to get the same response as in corda webserer.
for example:
List<StateAndRef<YourState>> vaultStatesList = vaultStates.getStates();
ObjectMapper mapper = JacksonSupport.createNonRpcMapper();
String json = mapper.writeValueAsString(vaultStatesList);

ASP.NET 5 DI app setting outside controller

I can DI app setting in the controller like this
private IOptions<AppSettings> appSettings;
public CompanyInfoController(IOptions<AppSettings> appSettings)
{
this.appSettings = appSettings;
}
But how to DI that in my custom class like this
private IOptions<AppSettings> appSettings;
public PermissionFactory(IOptions<AppSettings> appSetting)
{
this.appSettings = appSettings;
}
my register in Startup.cs is
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
The "proper" way
Register your custom class in the DI, the same way you register other dependencies in ConfigureServices method, for example:
services.AddTransient<PermissionFactory>();
(Instead of AddTransient, you can use AddScoped, or any other lifetime that you need)
Then add this dependency to the constructor of your controller:
public CompanyInfoController(IOptions<AppSettings> appSettings, PermissionFactory permFact)
Now, DI knows about PermissionFactory, can instantiate it and will inject it into your controller.
If you want to use PermissionFactory in Configure method, just add it to it's parameter list:
Configure(IApplicationBuilder app, PermissionFactory prov)
Aspnet will do it's magic and inject the class there.
The "nasty" way
If you want to instantiate PermissionFactory somewhere deep in your code, you can also do it in a little nasty way - store reference to IServiceProvider in Startup class:
internal static IServiceProvider ServiceProvider { get;set; }
Configure(IApplicationBuilder app, IServiceProvider prov) {
ServiceProvider = prov;
...
}
Now you can access it like this:
var factory = Startup.ServiceProvider.GetService<PermissionFactory>();
Again, DI will take care of injecting IOptions<AppSettings> into PermissionFactory.
Asp.Net 5 Docs in Dependency Injection
I recommend not passing AppSettings. A class shouldn't depend on something vague - it should depend on exactly what it needs, or close to it. ASP.NET Core makes it easier to move away from the old pattern of depending on AppSettings. If your class depends on AppSettings then you can't really see from the constructor what it depends on. It could depend on any key. If it depends on a more specific interface then its dependency is clearer, more explicit, and you can mock that interface when unit testing.
You can create an interface with the specific settings that your class needs (or something less specific but not too broad) and a class that implements it - for example,
public interface IFooSettings
{
string Name { get; }
IEnumerable Foos { get; }
}
public interface IFoo
{
string Color { get; }
double BarUnits { get; }
}
public class FooSettings : IFooSettings
{
public string Name { get; set; }
public List<Foo> FooList { get; set; }
public IEnumerable Foos
{
get
{
if (FooList == null) FooList = new List<Foo>();
return FooList.Cast<IFoo>();
}
}
}
public class Foo : IFoo
{
public string Color { get; set; }
public double BarUnits { get; set; }
}
Then add a .json file, fooSettings.json:
{
"FooSettings": {
"Name": "MyFooSettings",
"FooList": [
{
"Color": "Red",
"BarUnits": "1.5"
}, {
"Color": "Blue",
"BarUnits": "3.14159'"
}, {
"Color": "Green",
"BarUnits": "-0.99999"
}
]
}
}
Then, in Startup() (in Startup.cs) where we specify what goes into our Configuration, add fooSettings.json:
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json")
.AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("fooSettings.json");
Finally, in ConfigureServices() (also in Startup.cs) tell it to load an instance of FooSettings, cast it as IFooSettings (so the properties appear read-only) and supply that single instance for all dependencies on IFooSettings:
var fooSettings = (IFooSettings)ConfigurationBinder.Bind<FooSettings>(
Configuration.GetConfigurationSection("FooSettings"));
services.AddInstance(typeof (IFooSettings), fooSettings);
Now your class - controller, filter, or anything else created by the DI container - can have a dependency on IFooSettings and it will be supplied from the .json file. But you can mock IFooSettings for unit testing.
Original blog post - it's mine so I'm not plagiarizing.
You can do dependency injection in your non-controller classes as well.
In your startup class,
public class Startup
{
public IConfigurationRoot Configuration { get; set; }
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
// register other dependencies also here
services.AddInstance<IConfiguration>(Configuration);
}
}
Now in your custom class, Have the constructor accept an implementation of IConfiguration
private IConfiguration configuration;
public PermissionFactory(IConfiguration configuration)
{
this.configuration = configuration;
}
public void SomeMethod()
{
var someSection = this.configuration.GetSection("SomeSection");
var someValue= this.configuration.Get<string>("YourItem:SubItem");
}
If you want to DI to action filter reference to Action filters, service filters and type filters in ASP.NET 5 and MVC 6 service filter part.

Swagger: Not showing UI

I want to use Swagger with Spring MVC. I have following entries in the build.gradle file
compile 'com.mangofactory:swagger-springmvc:0.9.4'
compile 'com.wordnik:swagger-annotations:1.3.12'
compile 'org.webjars:swagger-ui:2.0.12'
I have enable it using #EnableSwagger annotation.
#EnableAutoConfiguration(exclude = {EmbeddedServletContainerAutoConfiguration.EmbeddedJetty.class, LiquibaseAutoConfiguration.class, org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class})
#EnableSwagger
#EnableWebMvc
#Configuration
public class App extends WebMvcConfigurerAdapter{
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
private SpringSwaggerConfig springSwaggerConfig;
#SuppressWarnings("SpringJavaAutowiringInspection")
#Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
this.springSwaggerConfig = springSwaggerConfig;
}
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
.apiInfo(apiInfo())
.includePatterns(".*feed.*"); // assuming the API lives at something like http://myapp/api
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"My Project's REST API",
"This is a description of your API.",
"API TOS",
"me#wherever.com",
"API License",
"API License URL"
);
return apiInfo;
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("*.html").addResourceLocations("/");
}
}
But when run the application using spring boot and hit the endpoint http://localhost:8080/api-docs, I just see the response in Json,
{"apiVersion":"1.0","apis":[{"description":"Basic Error Controller","path":"/default/basic-error-controller","position":0},{"description":"Manage people","path":"/default/people","position":0}],"authorizations":{},"info":{"contact":"Contact Email","description":"Api Description","license":"Licence Type","licenseUrl":"License URL","termsOfServiceUrl":"Api terms of service","title":"default Title"},"swaggerVersion":"1.2"}
I copied the static files from swagger-ui and copied it to my /main/webapp/doc
I am still missing fancy UI.

Resources