I have to consume value of #RequestBody to forwarded controller. As I passed JSON as a request body and from one controller it will forward to another controller. But it second controller it gives java.io.IOException
MyController.java
#Controller
public class MyController {
/*
Request JSON like
{"personeId":"123789","personName":"Fitz"}
*/
#RequestMapping(value = "/myapp/first/", method = RequestMethod.POST,
consumes = { "application/json" })
public String authorize(#RequestBody Person person) {
//Looking good
if(Validator.validatePerson(perosn)) {
return "forward:/myapp/second/";
} else {
return "forward:/myapp/secondError/";
}
}
#RequestMapping(value = "/myapp/second/", method = RequestMethod.POST,
consumes = { "application/json" })
public #ResponseBody String login(#RequestBody Person person) {
// Not able to get Person object here.
// Getting java.io.IOException: Stream closed :(
System.out.println("---> "+person.getPersonName());
return "success";
}
#RequestMapping(value = "/myapp/secondError/", method = RequestMethod.POST,
consumes = { "application/json" })
public #ResponseBody String loginError() {
return "error";
}
}
StackTrace
org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet dispatcher threw exception
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:339)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:94)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at java.io.PushbackInputStream.read(PushbackInputStream.java:139)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:168)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:105)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:466)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:391)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:74)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1015)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1575)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1533)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
So there is any way to achieve this scenario with Spring MVC.
you are getting the exception because #RequestBody annotation reads the underlying servlet input streams and consumes it, so you cannot read it twice.
If you look closer at the stack trace you can note the origin
org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:339)
You are trying to (re)read the data from a stream that is closed.
If you want to keep the first controller as it now you must change the second, you can choose for example to redirect to the second controller and put the object in session or to extract a method from the second controller that does the business logic and call it from the first controller.
If you can put the json in a parameter of the http call (authorize) you can avoid this problem, but (authorize) it's not a REST ednpoint anymore, but something like a "simple" http integration.
You should not forward in that case, but simply call the other methods :
#RequestMapping(value = "/myapp/first/", method = RequestMethod.POST,
consumes = { "application/json" })
public String authorize(#RequestBody Person person) {
//Looking good
if(Validator.validatePerson(perosn)) {
return login(person);
} else {
return loginError();
}
}
And this would only have sense if /myapp/second/ and /myapp/secondError/ are real URLs, if not, and if methods login and loginError should only be called from authorize method, they should simply be private methods in the controller.
Of course, if it involved business rules, it should go in service layer.
I don't think your approach is ideal. I would have only one call to the controller, and then start delegating the different tasks to different services.
if(Validator.validatePerson(perosn)) {
return loginService.login(person);
} else {
return "error";
}
The accepted answer is correct, there is no proper solution.
However here's a workaround that worked for me. I wanted to build a dispatcher that takes in json and forwards the request internally based on a command field:
#Controller
public class StackoverflowExampleController {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
#PostMapping("/post")
public ModelAndView post(#RequestBody String body) {
JsonNode tree = OBJECT_MAPPER.readTree(body);
String command = tree.get("command").asText();
return new ModelAndView("forward:/" + command + "?json=" + URLEncoder.encode(body));
}
#PostMapping("/test")
#ResponseBody
public String test(#RequestParam String json) {
return json;
}
}
Related
I have some code for download file from web server.
Everything works alright, but in console I have this exception:
июн 26, 2015 2:08:42 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [default] in context with path [/TestTask] threw exception
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:462)
at org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler.handleErrorInDevMode(DefaultDispatcherErrorHandler.java:109)
at org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler.handleError(DefaultDispatcherErrorHandler.java:57)
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:909)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:576)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Why and what it can be? And how i can fix this problem? I try find answer in the google, but I failed.
The code:
package actions;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Action;
import org.apache.log4j.Logger;
import org.apache.struts.chain.contexts.ServletActionContext;
import service.CsvCreator;
import com.opensymphony.xwork2.ActionSupport;
public class DownloadCsvAction extends ActionSupport {
private static final long serialVersionUID = -4714537109287679996L;
private CsvCreator CSVcreator;
private static final Logger logger = Logger.getLogger(DownloadCsvAction.class);
public CsvCreator getCSVcreator() {
return CSVcreator;
}
public void setCSVcreator(CsvCreator cSVcreator) {
CSVcreator = cSVcreator;
}
#Override
public String execute() {
HttpServletResponse response = org.apache.struts2.ServletActionContext.getResponse();
response.setHeader("Content-Disposition", "attachment; filename=\"phone_records.csv\"");
response.setContentType("text/csv");
ServletOutputStream out;
try {
out = response.getOutputStream();
String tableHeader = "Caller, Event, Reciever, Timestamp\n";
out.write(tableHeader.getBytes("UTF-8"));
out.write(CSVcreator.getAllRecordsInString().getBytes("UTF-8"));
out.flush();
out.close();
} catch (IOException e) {
logger.error(e.getMessage());
}
return SUCCESS;
}
}
And my struts.xml:
<action name="DownloadCsvAction" class="DownloadCsvAction">
<result name="success" type="dispatcher"/>
</action>
Why and what it can be?
Because response is already committed. You have closed response before it's used by the Struts2.
And how I can fix this problem?
When your action execution ends, return Action.NONE result code. This code tells the invoker to not execute any result because response might be already committed.
You can also rewrite the action implementation to use stream result type. In this way you have not to do with the response and let Struts2 do the rest. Example of using stream result is here.
I am developing a REST API with Spring MVC.
And it builds successfully, but when I try to deploy it to Tomcat 8.0.57
it gives the following error saying I have already a bean method in that controller. But I dont have any two methods with same names or RequestMethod.
This is the Apache Tomcat Log
29-Nov-2017 18:29:41.796 INFO [http-nio-8087-exec-72] org.apache.catalina.core.ApplicationContext.log 1 Spring WebApplicationInitializers detected on classpath
29-Nov-2017 18:29:41.844 INFO [http-nio-8087-exec-72] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext
29-Nov-2017 18:29:42.783 SEVERE [http-nio-8087-exec-72] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'chatUserController' method
public java.lang.String org.test.chatapi.controller.ChatUserController.saveUser(org.test.chatapi.model.User)
to {[],methods=[POST]}: There is already 'chatMessageController' bean method
public java.lang.Integer org.test.chatapi.controller.ChatMessageController.saveMessage(org.test.chatapi.model.Message) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4736)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5181)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:460)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1586)
at sun.reflect.GeneratedMethodAccessor94.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1460)
at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:906)
at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:344)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'chatUserController' method
public java.lang.String org.test.chatapi.controller.ChatUserController.saveUser(org.test.chatapi.model.User)
to {[],methods=[POST]}: There is already 'chatMessageController' bean method
public java.lang.Integer org.test.chatapi.controller.ChatMessageController.saveMessage(org.test.chatapi.model.Message) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:570)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:534)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:258)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:244)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:214)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:184)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:124)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 59 more
29-Nov-2017 18:29:42.789 INFO [http-nio-8087-exec-72] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
And these are the Controllers.
ChatUserController
#RestController
public class ChatUserController {
// Store the Users temporarily
ArrayList<User> users = new ArrayList<>();
// Get all the online users
#RequestMapping(name = "/users/", method = RequestMethod.GET)
public ArrayList<User> getUsers(){
users.add(new User("Janith","Hellow worlds"));
return users;
}
// Save new user / User Login
#RequestMapping(name = "/users/",method = RequestMethod.POST)
public String saveUser(#RequestBody User user){
if(user != null){
users.add(user);
return "Successfull Saved";
}else{
return "Failed";
}
}
// Remove the user / User sign out
#RequestMapping(name = "/users/{uname}", method = RequestMethod.DELETE)
public String deleteUser(#PathVariable String uname){
for(User u:users){
if(u.getUsername().equals(uname)){
users.remove(u);
return "Removed Successfully";
}
}
return "User Not found. Should be already Deleted.";
}
}
ChatMessagesController
#RestController
public class ChatMessageController {
ArrayList<Message> messagesList = new ArrayList<>();
#RequestMapping(name = "/messages/{username}", method = RequestMethod.PUT)
public ArrayList<Message> getChat(#PathVariable String username) {
// create a new list of unread messages
ArrayList<Message> myMessages = new ArrayList<>();
// add the unread messages to list
for (Message m : messagesList) {
if (m.getReciever().equals(username)) {
if (!m.isViewed()) {
m.setViewed(true);
myMessages.add(m);
}
}
}
return myMessages;
}
#RequestMapping(name = "/messages/", method = RequestMethod.POST)
public Integer saveMessage(#RequestBody Message message){
if(message != null){
message.setViewed(false);
messagesList.add(message);
return new Integer(1);
}else{
return new Integer(0);
}
}
}
But this ChatUserController worked fine, I deployed and tested it.
This error is getting after adding the ChatMessageController's second method saveMessage(). And also this same error showed when the first method getChat() was in GET RequestMethod. It was fixed after I changed it to the PUT method.
I am new to Spring MVC Web API, So I appreciate any help regarding this.
In my case I go to read Spring doc to find some explanation but I finished when found this in RequestMapping interface:
Note: This annotation can be used both at the class and at the method level. In most cases, at the method level applications will prefer to use one of the HTTP method specific variants #GetMapping, #PostMapping, #PutMapping, #DeleteMapping, or #PatchMapping.
So I decided also to prefer to use #GetMapping, #PostMapping, #PutMapping, #DeleteMapping, or #PatchMapping and it works in my case.
Try to make:
#GetMapping("/users/")
public String saveUser(#RequestBody User user){
//...
}
#DeleteMapping("/users/{uname}")
public String deleteUser(#PathVariable String uname){
//...
}
P.S: also we need use value if we need set path:
#RequestMapping(value = "/users/", method = RequestMethod.GET)
name its only name, not path
I'm testing a Spring Web Service with Jmeter. We're also using activiti, but since I'm a newb at both, that's about as far as I can tell. Supposedly, the application is to receive parameters from the request.
However, I hit a snag here (UpdateInbdParams):
private String taskId;
private Map<String, String> vars;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public Map<String, String> getVars() {
return vars;
}
public void setVars(HashMap<String, String> vars) {
this.vars = vars;
}
I'm supposed to send a string, and a Map. The latter is there so supposedly, we could send any parameters we need later, without modifying the code. But how do I test the latter, like this?
That returns this:
{"vars":null}
For reference, here's part of the code that bugs out:
#RequestMapping(method = RequestMethod.POST)
public UpdateOutbdParams post(Locale locale, UpdateInbdParams model) {
UpdateOutbdParams response = new UpdateOutbdParams();
try{
try{
TaskService taskService = this.processEngine.getTaskService();
Task task = taskService.createTaskQuery().taskId(model.getTaskId()).singleResult();
RuntimeService runtimeService = this.processEngine.getRuntimeService();
/** ERRORS HERE **/
runtimeService.setVariables(task.getExecutionId(), model.getVars());
/** ERRORS END HERE **/
taskService.complete(model.getTaskId());
System.out.println(model.getVars().toString());
System.out.println("Task execution id " + task.getExecutionId());
}catch(Exception ex){
ex.printStackTrace();
System.out.println("Inner catch: "+ex.getMessage());
}
}catch(Exception ex){
ex.printStackTrace();
System.out.println("Outer catch: "+ex.getMessage());
return response;
}
return response;
}
And here's the actual error:
java.lang.NullPointerException
at com.myprojects.sample.api.txn.controllers.TxnTaskController.post(TxnTaskController.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Inner catch: null
So I'm guessing it has something to do with how it (didn't) receive a Map value. Any ideas?
Thanks.
i'm working on a project with Spring, i have this problem, i google the error message and i did find a solutions even all SO posts about this same problem
java.lang.IllegalStateException: "getOutputStream()" has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:578)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:212)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:109)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:115)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:108)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:175)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
at org.apache.jsp.WEB_002dINF.Pages.generate_jsp._jspService(generate_jsp.java:209)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:584)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:523)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:230)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
this is my controller :
#RequestMapping(method = RequestMethod.GET, value = "/GenerateM")
public String genererGet(HttpServletRequest request, ModelMap model, HttpServletResponse response) throws Exception {
// Some code ...
OutputStream out;
try {
response.setContentType("rtf");
String filename = name + ".out.rtf";
response.setHeader("Content-Disposition", "attachment; filename = " + filename);
out = response.getOutputStream();
FileInputStream in = new FileInputStream(new File(rtf.getRtfOutput()));
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
out.close();
} catch (IOException a) {
a.printStackTrace();
}
return "generate";
}
i saw many SO posts like : THIS and THIS and THIS but no solution for me
can some one help ?
You start by writing a response by yourself, and then return the name of the view, and thus telling Spring that it should generate an HTML page using the generate.jsp.
Make your method return void instead of a String. An HTTP response can have only one body: either it's a file attachment, or an HTML page, but not both.
#JB Nizet Thank's for help. In my case, I retured ModelAndView ojbect when download failing to forward error page:
#RequestMapping(value = { "/downloadfile.action" }, method = RequestMethod.POST)
public ModelAndView downloadFile(HttpServletRequest req, HttpServletResponse res, Model model)
{
catch (Excetion e) {
return errorPage
}
}
I change that to return null
I have a problem with my MVC server. When I post my JSON:
{
"shipName":"shfdsfds",
"signal":"fdsfsd321",
"longitude":43,
"latitude":32,
"maxSpeed":342
}
using PUT method and in Signal class two constructors is defined:
public Signal(){
}
public Signal(String shipName, String signal, int latitude, int longitude,
int maxSpeed) {
ShipName = shipName;
Signal = signal;
Latitude = latitude;
Longitude = longitude;
MaxSpeed = maxSpeed;
}
everytime I receive Status Code: 200-Ok, but wrong value of prams (addSignal: 0).
My controler:
#RequestMapping(value = "/addSignal", method = RequestMethod.PUT)
#ModelAttribute
public ResponseEntity<Signal> add(
#ModelAttribute Signal signal) throws SQLException,
ClassNotFoundException {
System.out.println("addSignal: "+signal.getMaxSpeed());
return new ResponseEntity<Signal>(signal, HttpStatus.OK);
}
When I try remove the first constructor (public Signal(){}), I receive error:
Status Code: 500 Internal Server Error
Console:
maj 16, 2015 3:18:23 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [server] in context with path [/shipserver] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mkozykowski.api.Signal]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.mkozykowski.api.Signal.<init>()] with root cause
java.lang.NoSuchMethodException: com.mkozykowski.api.Signal.<init>()
at java.lang.Class.getConstructor0(Class.java:2892)
at java.lang.Class.getDeclaredConstructor(Class.java:2058)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:105)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:101)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:833)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:651)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
---------edit---------
I have changed my controller:
#RequestMapping(value = "/addSignal", method = RequestMethod.PUT, produces = "application/json")
public ResponseEntity<Signal> add(
#RequestBody Signal signal) throws SQLException,
ClassNotFoundException {
System.out.println("addSignal: "+signal.getMaxSpeed());
return new ResponseEntity<Signal>(signal, HttpStatus.OK);
}
In Signal class now I have one constructor:
public Signal(#JsonProperty("shipName")String shipName,#JsonProperty("signal")String signal,
#JsonProperty("latitude")int latitude, #JsonProperty("longitude")int longitude,
#JsonProperty("maxSpeed")int maxSpeed) {
ShipName = shipName;
Signal = signal;
Latitude = latitude;
Longitude = longitude;
MaxSpeed = maxSpeed;
}
Sending Json by RESTClient I add header:Content-Type:application/json.
Now I receive error:
HTTP Status 415
In my console nothing appears.
I feel like you should use #RequestBody instead of #ModelAttribute.
And to be sure that json deserializer correctly constructs your class using json data i suggest annotating constructor parameters with #JsonProperty("propertyName") where propertyName matches json property name.
---edit---
Are you sure that you correctly set header? Because your code works fine for me.