I am using swagger to create API documentation for one of my Spring Rest API project, but the swagger.json file created is having an issue.
One of my Super class is not getting converted properly.
Library used to implement the swagger is springfox. Please find the implementation details below.
Configuration
EnableWebMvc
EnableSwagger2
ComponentScan
public class MvcConfig extends WebMvcConfigurerAdapter {
}
This is the class causing the problem
public class ListResultModel MODEL extends BaseModel {
}
Json Created
"schema":{"$ref":"#/definitions/RedirectAttributes"}}],"responses":{"200":{"description":"OK","schema":{"type":"string"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/admin/migration/vat":{"get":{"tags":["migration-controller"],"summary":"vatMigration","operationId":"vatMigrationUsingGET","consumes":["application/json"],"produces":["/"],"parameters":[{"name":"retailerId","in":"query","description":"retailerId","required":true,"type":"string"}
{"$ref":"#/definitions/**ListResultModel«Item»"**}},"401":{"description":""},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/items/withoutPictures/{departmentId}/{vendorId}/{status}":{"200":{"description":"OK","schema":{"$ref":"#/definitions/**ListResultModel«Item»"}**},"401":{"description":""},"403":{"description":"Forbidden"},"404":{"description":"Not }
{"$ref":"#/definitions/ListResultModel«Lead»"}},"201":{"description":"Created"},"401":{"description":""},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}
I am trying to resolve this for a long time and there is no clue how to do it. Can anybody help me please!
Thanks in advance.
Vivek
This Got Fixed by the below Thread.
https://github.com/springfox/springfox/issues/1283
Regards
Vivek
Related
I have an application using Glide 3.8.0 and I've just migrated it to 4.8.0. After migrating all the code to use the new Glide's API, I've found that my app launches this error when trying to load an image from the network:
java.lang.AbstractMethodError: abstract method "void com.bumptech.glide.module.RegistersComponents.registerComponents(android.content.Context, com.bumptech.glide.Glide, com.bumptech.glide.Registry)"
at com.bumptech.glide.Glide.initializeGlide(Glide.java:268)
at com.bumptech.glide.Glide.initializeGlide(Glide.java:221)
at com.bumptech.glide.Glide.checkAndInitializeGlide(Glide.java:182)
at com.bumptech.glide.Glide.get(Glide.java:166)
at com.bumptech.glide.Glide.getRetriever(Glide.java:680)
at com.bumptech.glide.Glide.with(Glide.java:732)
at com.fewlaps.android.quitnow.usecase.main.MainActivity.updateAvatar(MainActivity.java:356)
etc...
I've done the setup explained in the official documentation. As it requests, I wrote a class that extends AppGlideModule, it's annotated by #GlideModule, and it's empty. Empty? The official documentation says:
You’re not required to implement any of the methods in AppGlideModule for the API to be generated. You can leave the class blank as long as it extends AppGlideModule and is annotated with #GlideModule.
According to the Error's message, my issue is related with registerComponents() for sure, but I also tried to implement it with a blank implementation, and the issue remains.
As explained in AppGlideModule's JavaDoc (and as far as I know, only there...), if you are done with the migration from 3.x.x to 4.x.x, you have to implement isManifestParsingEnabled() returning false.
So, you'll end with a CustomAppGlideModule like this one:
#GlideModule
public class QNGlideModule extends AppGlideModule {
#Override
public boolean isManifestParsingEnabled() {
return false;
}
}
Recently i tried to create a MVC application using ASP.NET Core 2.0 and i had some values defined in appsettings.json,
"MySettings": {
"WebApiBaseUrl": "http://localhost:6846/api/"
}
In order to read these values i have added
services.Configure<MySettingsModel>(Configuration.GetSection("MySettings"));
above line in ConfigureServices method in Startup.cs
and in my home controller i have added
private readonly IOptions<MySettingsModel> appSettings;
public HomeController(IOptions<MySettingsModel> app)
{
appSettings = app;
}
MySettingsModel class is just a model with property same as key define in appsettings.json.
by this method i'm able to read the value of this key.
Now my issue is that i want to use this key in many controllers so i don't want to repeat this code in every controller so what i did was i created a BaseConntroller, added its constructor and i got my values there. But when i inherit other controllers with my BaseController , it throws me an error and tells me to generate it's constructor, so basically it tells me to add constructor in every controller which is what i wanted to avoid.
How can i achieve this?
You can see the image for the error
And these are the potential fixes that it shows me.
This is just basic C# inheritance. Derived classes must re-implement constructors on base classes (at least the ones you want or need). The only exception is the empty constructor, which is implicit. In other words, you simply need:
public class HomeController : BaseController
{
public HomeController(IOptions<MySettingsModel> app)
: base(app)
{
}
And, of course, you need to change the accessibility of the base class field to protected instead of private. Otherwise, derived classes will not be able to access it.
Of course, this doesn't really save you that much. However, there's no free lunch here. Like I said, this is a limitation of C#, itself, so you have no choice. Although, it's worth mentioning, that while this can sometimes be annoying, it's actually a kind of useful feature of C#. You can look at any class and see exactly what constructors it has available, without having to trace down all its ancestors.
Actually, there is a good solution here:
https://stackoverflow.com/a/48886242/2060975
I am mostly using this method.
[Authorize]
[ApiController]
public abstract class ApiControllerBase : ControllerBase
{
private IOptions<AppSettings> _appSettings;
protected IOptions<AppSettings> appSettings => _appSettings ?? (_appSettings = (IOptions<AppSettings>)this.HttpContext.RequestServices.GetService(typeof(IOptions<AppSettings>)));
...
}
I hope it helps someone:)
I want to create a Link to a resource within a Spring Data REST Repository. I know that we can use ControllerLinkBuilder.linkTo method to create links to MVC controllers. As far is I understand Spring Data REST creates MVC controllers out of our Repository interfaces. But if I use
Instance createdInstance = instanceRepository.save(instance);
Link link = linkTo(InstanceRepository.class).slash(createdInstance.getId()).withSelfRel();
to create the link, I just get http://localhost:8080/2 (without the Repository path). Nothing changes if I specify the path explicitly with the #RepositoryRestResource at the Repository.
Of course I could just create the link explicitly, but I don't want to repeat myself.
public interface InstanceRepository extends CrudRepository<Instance, Long> {
}
Any advice on what I could do to resolve this issue without having to violate DRY principles?
Searching through the Spring Data REST source code I found the class RepositoryEntityLinks, which is used within the framework. It has a pretty nasty constructor, but (at least in my project) I am able to #Autowire the class.
In short the following code does the trick. Nevertheless I would be pleased to hear another persons more educated opinion on this!
Link link = entityLinks.linkToSingleResource(InstanceRepository.class, 1L);
If anyone is confused on how to piece it all together, you need to inject RepsitoryEntityLinks into your controller like so. Note no AutoWired is needed since spring will automatically inject the values if theres just the 1 constructor.
entityLinks.linkToCollectionResource(TodoRepository.class) is saying to spring - "give me the link to the TodoRepositories collection endpoint which would be something like localhost:8080/api/todos"
#RestController
#RequestMapping(value="/api")
public class PriorityController {
private RepositoryEntityLinks entityLinks;
public PriorityController(RepositoryEntityLinks entityLinks) {
this.entityLinks = entityLinks;
}
#GetMapping(value = "/priorities", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity<Resources<Priority>> getPriorities() {
Link link = entityLinks.linkToCollectionResource(TodoRepository.class);
resources.add(link);
return ResponseEntity.ok(resources);
}
}
I am having trouble getting #ControllerAdvice to work. I updated my namespace location, which were 3.1 in my xml files. I moved the class with the controller to the same package as the controller. I am using 3.2.0 release jars. If I put the #ExceptionHandler annotation in the controller code, it works, but not in a separate class with the #ControllerAdvice. When the #ControllerAdvice class fails, I get my uncaught exception handler view. Anyone have ideas on how to trouble shoot this one?
If you use classpath scanning, probably you have to add new include filter to your <context:component-scan> element:
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice" />
Default scanning does not lookup this annotation, following spring-context-3.2.xsd for component-scan:
"Scans the classpath for annotated components that will be auto-registered as Spring beans. By default, the Spring-provided #Component, #Repository, #Service, and #Controller stereotypes will be detected."
For this problem, The first thing is confirming your config,
You need make sure that the #ControllerAdvice Class under your component-scan base package.
Make suer you use <mvc:annotation-driven/> in your spring-servlet.xml. or have #EnableWebMvc in your #ControllerAdvice Class
When you have the config right, the ControllerAdvice should already work, Now you said You got your uncaught exception handler view. I guess you got that in your InegrationTest, And you used mockMvc to test that, If so, you need put #WebAppConfiguration and build mokcMvc as follow:
#Autowired
private WebApplicationContext wac;
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
Using standaloneSetup(controller) will not work because lack of WebApplicationContext.
There is no extra configuration required. It should just work. Look at this link for more details. This provide very simple example:
https://javabeat.net/exception-controlleradvice-spring-3-2/
https://javabeat.net/controlleradvice-improvements-spring-4-0/
I had this same problem, in my case the problem was that there was a dependent library that had inside it a class with the #ControllerAdvice and #Order(Ordered.HIGHEST) annotation, to solve the problem I added the #Order(Ordered.HIGHEST) annotation in my classe, and now it works.
Since my exception class is in the same controller package spring gave my class higher priority even though both classes have the same #Order(Ordered.HIGHEST)
#ControllerAdvice
#Order(Ordered.HIGHEST)
public class RestResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
I struggled with the same problem where my #ControllerAdvice class would not load while unit testing REST controllers' exceptions. If you are using spring boot (version 4) then you can use additional methods added by spring to load controller advice classes in standalone setting up your controllers.
mockMvc = MockMvcBuilders
.standaloneSetup(new YourRestController())
.setControllerAdvice(new ControllerAdviceClass())
.build();
This will straight-away initialize your controller advice class and your Junit test should be able to jump in to #ExceptionHandler methods defined in your controller advice class.
For me, #ControllerAdvice was not working at all cost. Even adding #EnableWebMvc or #WebAppConfiguration didn't make any change.
The way I was able make it working was,
adding #ExceptionHandler methods for my AbstractController class, the class that all the other controllers are extending upon.
I think #ControllerAdvice is supposed to do the same thing, i.e. compile the #ExceptionHandler methods defined under the class specified by #ControllerAdvice, into a common place where every controller can refer from. But unfortunately it was not working for me.
I solved it by defining ControlAdvice class in Configuration beans as shown below:
#Primary
#Bean
public RestResponseEntityExceptionHandler restResponseEntityExceptionHandler (){
return new RestResponseEntityExceptionHandler ();
}
I am currently working on a Custom MembershipProvider implementation. But I need additional methods. I would like to call those methods directly on the Membership object within my Controller like this:
Membership.DoStuff()
Is it possible to do that with an extension method? Where would I start?
thanks!
learning more about extension methods is a good start. Please refer to following articles
http://technico.qnownow.com/2012/03/17/how-to-create-extension-methods-in-net/
extension methods (MSDN)
Why don't you add it directly to you class (which have the custom MemebershipProvider) then cast the membership clasd to your then you will find it.
If you asking about the extension methods it should work on any class, so the answer to your question is Yes.
After trying a lot of examples I have found this post where they state that you cannot write extension methods to a static class.
Membership is a static class and you cannot extend it.
yes, Membership is extensible, but you don't extends static class Membership (because it's impossible), you must extends abstract class MembershipProvider, and calls extension methods like Membership.Provider.DoStuff().
For example:
extension class
namespace Infrastructure.Extensions
{
public static class MembershipProviderExtensions
{
public static void DoStuff(this MembershipProvider provider)
{
// do stuff
}
}
}
in your code
using Infrastructure.Extensions;
...
Membership.Provider.DoStuff()
...