request error (invalid_request) spring rest api - rest

I wrote a Rest API using Spring boot and Rest Template .Simplest one . Here is the code that I wrote in the controller .
package wsJson;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api")
public class RestCon {
private AtomicLong id;
public Bean b;
#RequestMapping("/bean")
public Bean getBeans(#RequestParam(value="name")String name){
return new Bean(id.incrementAndGet(), name);
}
}
Bean is simple and the main class just runs the Spring Boot App .
Whenever I run the code it runs in localhost:8080 . But as I go to the URL
http://localhost:8080/api/bean?name=User1
it gives
Request Error (invalid_request)
Your request could not be processed. Request could not be handled This
could be caused by a misconfiguration, or possibly a malformed
request.
Can anyone help me understand the problem and how to solve it?
This code works normally, but in my office I am sitting behind proxy network and this code fails like this! Does anyone have any idea why is it so!
Edit:
After I run the app , I can see after entering the controller following gets logged in console:
2017-08-25 16:43:18.325 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for
#ControllerAdvice:
org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#d3d15a:
startup date [Fri Aug 25 16:43:16 IST 2017]; root of context hierarchy
2017-08-25 16:43:18.419 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped
"{[/greeting],methods=[GET]}" onto public hello.Greeting
hello.GreetingController.greeting(java.lang.String) 2017-08-25
16:43:18.422 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto
public
org.springframework.http.ResponseEntity>
org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-08-25 16:43:18.422 INFO 1056 --- [ main]
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped
"{[/error],produces=[text/html]}" onto public
org.springframework.web.servlet.ModelAndView
org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-08-25 16:43:18.444 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path
[/webjars/] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.444 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/] onto
handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.495 INFO 1056 --- [ main]
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path
[/**/favicon.ico] onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-25 16:43:18.633 INFO 1056 --- [ main]
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX
exposure on startup 2017-08-25 16:43:18.817 INFO 1056 --- [
main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on
port(s): 8080 (http) 2017-08-25 16:43:18.833 INFO 1056 --- [
main] hello.Application : Started Application
in 3.063 seconds (JVM running for 3.729)
main class:
package wsJson;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
bean class:
package wsJson;
public class Bean {
public long id;
public String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Bean(long id, String name) {
super();
this.id = id;
this.name = name;
}
}
App made using spring-boot 1.5.6-RELEASE

This has nothing to do with your spring-boot application.
If you have an exception in your application logs please let us know about the stack trace. In your code snippet id is not initialised so your code can't work:
here is an example of code i tested :
#SpringBootApplication
#RestController
#RequestMapping("/api")
public class TestApplication {
private AtomicLong id = new AtomicLong();
#RequestMapping("/bean")
public String getBeans(#RequestParam(value="name")String name){
return new Bean(id.incrementAndGet(), name).toString();
}
class Bean{
public Bean(long l, String name) {
}
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Test your application locally without that proxy so your can be sure your application works.
You posted your app startup logs and it looks like your controller is not mapper . Maybe your controller is not scanned by the application.
You controller has to be in a sub package of the package containing the class that is annotated by #SpringBootApplication so the component scanner can see it.

Related

Why MongoDB Atlas does not work with reactive Spring Data and Spring Boot?

I'm developing an easy sample application. One component is a gateway service using Spring Boot and Reactive Spring Data for Mongo, because that's where I want to store user and login informations.
For testing out different solutions, I wanted to use MongoDB Atlas. So, I set up an application. But when I want to save just a sample user, nothing happens, the data is not saved to the database. However it looks like the application is connected to the MongoDb Atlas. No error logs about failed connections.
This is the main class, where I have the #EnableReactiveMongoRepositories annotation:
#SpringBootApplication
#EnableReactiveMongoRepositories("com.bkk.sm.authentication.repository")
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
Here is how I set up Mongo in application.yml and the repository:
spring:
data:
mongodb:
database: users
uri: mongodb+srv://${MONGO_USER}:${MONGO_PASSWORD}#taocluster.qa3sd.mongodb.net/users?retryWrites=true&w=majority
#Repository
public interface ReactiveUserRepository extends ReactiveMongoRepository<User, String> {
Mono<User> findByUsername(String username);
}
I don't use any specific reactive MongoDB config, I don't extend the AbstractReactiveMongoConfiguration (this is really just a bout to experiment how does this work) and I use the defaults.
In my UserDetailsServiceImpl, I try to save a sample record, just right after the bean is constructed:
#Slf4j
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
private ReactiveUserRepository repository;
public UserDetailsServiceImpl(ReactiveUserRepository repository) {
this.repository = repository;
}
#PostConstruct
public void setup() {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String pwd = encoder.encode("user");
User user = User.builder()
.username("user")
.password(pwd)
.accountExpired(false)
.accountLocked(false)
.activationCode(null)
.activatedTime(Date.from(Instant.now()))
.email("user#user.com")
.enabled(true)
.firstName("User")
.failedLoginAttempts(0)
.lastModificationTime(Date.from(Instant.now()))
.lastName("User")
.middleName("User")
.passwordExpiryTime(Date.from(Instant.now()))
.registrationTime(Date.from(Instant.now()))
.roles(List.of(CompanyRole.builder().companyCode("bkk")
.companyName("Beszterce KK")
.role(Role.ROLE_USER)
.build())
)
.passwordExpiryTime(null)
.version(0)
.build();
this.repository.save(user).map(user1 -> {
log.info("User saved. {}", user1);
return user1;
}).onErrorResume(Objects::nonNull, throwable -> {
log.error("Something is not right here.", throwable);
return Mono.error(throwable);
}).switchIfEmpty(Mono.defer(() -> {
log.info("Cannot save ure={}", user.toString());
return Mono.error(new Exception("WTF?"));
}));
}
... SOME MORE METHODS COME HERE
}
When it executes the this.repository.save(user) line, nothing happens. Well, I tried to debug and went deeper into the framework but ultimately, nothing happens. That's why I added some log messages. But nothing. If I put a breakpoint to the map or onErrorResume or switchIfEmpty branches, the execution doesn't stop there. No log is written to console other that this line:
2022-04-09 00:02:46.061 INFO 72528 --- [ntLoopGroup-3-7] org.mongodb.driver.connection : Opened connection [connectionId{localValue:7, serverValue:78530}] to taocluster-shard-00-02.qa3sd.mongodb.net:27017
And here is my data object where I declare the collection name:
#Getter
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Document(collection = "users")
public class User implements UserDetails {
#Id
private String id;
#Indexed
#NonNull
private String username;
... SOME MORE FIELDS COME HERE ...
}
So, my question is, what am I doing wrong? Why I don't see anything added to my MongoDB Atlas sample database? Where I just set the 0.0.0.0/0 for accepting connections from everywhere for the time being of testing this stuff out.
Any help would be appreciated.

Sprint Boot Mongo Respositry Hangs on Second Reqeust

I'm running into a strange issue using SpringBoot MongoRepository.
I've localized the problem to returning the response to the request after it has successfully queried my Mongo instance. I have a simple object that I am querying. On start I can query and get back a response instantly. After that it just hangs after it has successfully queried Mongo.
This is the extent of the logs when the issue happens
2021-04-13 21:20:03 DEBUG [http-nio-8080-exec-2] [MongoQueryCreator.java:160] Created query Query: { "trackingCode" : "PERS4J"}, Fields: {}, Sort: {}
2021-04-13 21:20:03 DEBUG [http-nio-8080-exec-2] [MongoTemplate.java:2551] find using query: { "trackingCode" : "PERS4J"} fields: Document{{}} for class: class com.gotem.domain.Link in collection: link
2021-04-13 21:20:03 DEBUG [http-nio-8080-exec-2] [SLF4JLogger.java:56] Sending command '{"find": "link", "filter": {"trackingCode": "PERS4J"}, "limit": 2, "$db": "gotem"}' with request id 9 to database gotem on connection [connectionId{localValue:2, serverValue:11}] to server localhost:27017
2021-04-13 21:20:03 DEBUG [http-nio-8080-exec-2] [SLF4JLogger.java:56] Execution of command with request id 9 completed successfully in 2.47 ms on connection [connectionId{localValue:2, serverValue:11}] to server localhost:27017
This is using Spring Boot 2.2.0.RELEASE against Mongo 4.4.3.
I'm stumped :/
Adding simplified setup and config.
application.properties
spring.data.mongodb.uri=mongodb://localhost:27017/linkTrack
Repository
#Repository
public interface LinkRepository extends MongoRepository<Link, Long> {
Link findOneByTrackingCode(String trackingCode);
}
Query Controller
public class LinkController {
private static final Logger LOG = LoggerFactory.getLogger(LinkController.class);
#Autowired
private LinkRepository linkRepository;
#RequestMapping(value = "/retrieve/{trackingCode}", method = RequestMethod.GET)
public Link findOneByTrackingCode(#PathVariable String trackingCode) {
Link link = linkRepository.findOneByTrackingCode(trackingCode);
LOG.debug("Link: " + link);
return link;
}
}
Object
#Document
public class Link implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
private String trackingCode;
public Link() {
this.trackingCode = "123456"; // THIS WAS THE ISSUE :(
}
private getTrackingCode(){
return this.trackingCode
};
}
Well. Crap. I had a constructor in the Link Object that added a generated id to the trackingCode field and once removed it worked as expected.
I still am at a loss as to why it worked on the first request after restarting the service and only hung after.

Spring Boot Controller Test with Mock Service doesn't use the mock service

I have a simple RestController with a Service and want to test just the controller by providing a mock implementation for the Service.
However, I'm getting an empty response in resultActions = mockMvc.perform(get("/user")); object when I'm running the test.
Here is my code:
Controller
#RestController
public class UserController {
#Autowired
UserService userService;
#GetMapping("/user")
public ResponseEntity<List<String>> getUsers(){
return ResponseEntity.ok().body(userService.getUsers());
}
}
Contoller Test
#RunWith(SpringRunner.class)
#WebMvcTest(UserController.class)
public class UserControllerTest {
#MockBean
UserService userService;
private final Logger log = LoggerFactory.getLogger(UserControllerTest.class);
#Autowired
MockMvc mockMvc;
#Before
public void init(){
List<String> usrs = new ArrayList<>();
usrs.add("JUNIT-USER");
userService = Mockito.mock(UserService.class);
when(userService.getUsers()).thenReturn(usrs);
}
#Test
public void test1() throws Exception {
ResultActions resultActions = mockMvc.perform(get("/user"));
resultActions.andDo(mvcResult -> {
log.info(mvcResult.getResponse().getContentType());
log.info(mvcResult.getResponse().getContentAsString());
log.info(String.valueOf(mvcResult.getResponse().getContentLength()));
});
resultActions
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().json("[\"JUNIT-USER\"]"));
}
}
The output of the log statements in the test is as follows:
2021-02-24 15:23:16.161 INFO 22197 --- [ main] com.vi.learn.UserControllerTest : application/json
2021-02-24 15:23:16.161 INFO 22197 --- [ main] com.vi.learn.UserControllerTest : []
2021-02-24 15:23:16.161 INFO 22197 --- [ main] com.vi.learn.UserControllerTest : 0
The test hence fails with the below assertionError:
java.lang.AssertionError: []: Expected 2 values but got 0
What am I doing wrong here?
Two existing methods
Using the mock () method
Using the #MockBean annotation
#MockBean
UserService userService;
or
userService = Mockito.mock(UserService.class);
You have to choose one of them so simply use #MockBean :
#Before
public void init(){
List<String> usrs = new ArrayList<>();
usrs.add("JUNIT-USER");
when(userService.getUsers()).thenReturn(usrs);
}

REST Works on some computers

This is really confusing, i have a rest service that works on some computers but refuses to work on others, no idea why.
The project is using Maven, EJB and glassfish
This is the rest service:
#Path("/")
public class ArticleService {
#EJB
private LocalArticle articleEJB;
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("article/{articleId}")
public Article getArticleXML(#PathParam("articleId") int id) {
return articleEJB.getArticleById(id);
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("article/{articleId}")
public Article getArticleJSON(#PathParam("articleId") int id) {
return articleEJB.getArticleById(id);
}
}
The return value is a object, and if i instead return article.getName i get a 200 response, however if i try to return the entire object i get 500
Here is a rest management class(I'm not sure what this does, I followed an example from a book):
#ApplicationPath("rest")
public class ArticleMgmtRESTApplication extends ResourceConfig {
public ArticleMgmtRESTApplication () {
packages("se.alager.rest.ws.services");
}
}
}
Here is the Article in question:
#Entity
#NamedQueries({
#NamedQuery(name="Article.findAll", query="SELECT a FROM Article a"),
#NamedQuery(name="Article.findById", query="SELECT a FROM Article a WHERE a.id = :id")
})
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="id_article")
#XmlAttribute
private int id;
private int amount;
private String description;
private String name;
}
This exact code works flawlessly for mt friend, but I can't seem to get it to work, any ideas as to why?
Here is the Glassfish log for the error (ther was some 500 more lines of log, I hope this is relevant, I have no idea what I'm doing here)
[2016-10-20T16:31:44.140+0200] [glassfish 4.1]
[INFO] [] [org.jboss.weld.Bootstrap]
[tid: _ThreadID=142 _ThreadName=admin-listener(7)] [timeMillis: 1476973904140]
[levelValue: 800] [[
WELD-000119: Not generating any bean definitions from
org.glassfish.jersey.server.internal.inject.ParamConverters$CharacterProvider
because of underlying class loading error: Type [unknown] not found.
If this is unexpected, enable DEBUG logging to see the full error.]]
[2016-10-20T16:31:45.000+0200] [glassfish 4.1] [INFO] []
[org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer]
[tid: _ThreadID=142 _ThreadName=admin-listener(7)] [timeMillis: 1476973905000]
[levelValue: 800] [[
Registering the Jersey servlet application, named
se.alager.rest.ws.ManagementRESTApplication,
at the servlet mapping /rest/*, with the Application class of the same name.]]

Not able to resolve PUT and POST issue with spring boot

I am building an application with spring boot with REST my GET method is working but POST and PUT method is not working giving exception :
2015-05-28 16:30:09.498 DEBUG 22670 --- [qtp536775614-18] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /api/v1/user
2015-05-28 16:30:09.500 DEBUG 22670 --- [qtp536775614-18] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2015-05-28 16:30:09.500 DEBUG 22670 --- [qtp536775614-18] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2015-05-28 16:30:09.500 DEBUG 22670 --- [qtp536775614-18] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported
2015-05-28 16:30:09.501 WARN 22670 --- [qtp536775614-18] o.s.web.servlet.PageNotFound : Request method 'PUT' not supported
2015-05-28 16:30:09.501 DEBUG 22670 --- [qtp536775614-18] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2015-05-28 16:30:09.502 DEBUG 22670 --- [qtp536775614-18] o.s.web.servlet.DispatcherServlet : Successfully completed request
I searched a lot for this issue but not found satisfactorily solution.
My controller code is :
package com.samepinch.controllers;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.samepinch.services.UserService;
import com.samepinch.utills.response.ResponseHandler;
#RestController
#RequestMapping("/api/v1")
public class UserController {
public static Logger log = LoggerFactory.getLogger(UserController.class);
#Autowired
UserService userService;
/**
* to pass user info to service
*/
/*#RequestMapping(value = "/signup",method = RequestMethod.POST)
public Map<String, Object> saveUser(#RequestBody User user) {
successfully", HttpStatus.ACCEPTED, false, null);
}*/
/**
* to delete user by id
*/
#RequestMapping(value = "/user", method = RequestMethod.DELETE)
public void deleteUser(#PathVariable("id") String id) {
userService.deleteUser(id);
}
/**
* to update user by id
*/
#RequestMapping(value = "/user", method = RequestMethod.PUT)
public String updateUser() {
System.out.println("in update method");
// userService.updateUser(user);
return "success";
}
#RequestMapping(value = "/user" , method = RequestMethod.GET)
public Map<String,Object> getUsers(){
log.info("getting user");
return ResponseHandler.generateResponse("", HttpStatus.ACCEPTED, false, null);
}
} userService.saveUser(user);
return ResponseHandler.generateResponse("User registerted successfully", HttpStatus.ACCEPTED, false, null);
}*/
/**
* to delete user by id
*/
#RequestMapping(value = "/user", method = RequestMethod.DELETE)
public void deleteUser(#PathVariable("id") String id) {
userService.deleteUser(id);
}
/**
* to update user by id
*/
#RequestMapping(value = "/user", method = RequestMethod.PUT)
public String updateUser() {
System.out.println("in update method");
// userService.updateUser(user);
return "success";
}
#RequestMapping(value = "/user" , method = RequestMethod.GET)
public Map<String,Object> getUsers(){
log.info("getting user");
return ResponseHandler.generateResponse("", HttpStatus.ACCEPTED, false, null);
}
}