我正在尝试为简单的Hello world Alexa Skill构建一个Spring Boot Web服务。
我在传递vocabBrawlSpeechlet
aws speechlet API时在运行时获得Null指针异常。即使我将vocabBrawlSpeechlet
作为new VocabBrawlSpeechlet()
传递,我在vocabBrawlSpeechlet类中使用autowire时也会出现空指针异常。
Servlet类
package com.vocabBrawlAlexa;
@WebServlet("/hello")
public class HelloWorldServlet extends SpeechletServlet {
private static final Logger LOGGER = LogManager.getLogger(HelloWorldServlet.class.getName());
/**
*
*/
private static final long serialVersionUID = -8294485619021129263L;
private VocabBrawlSpeechlet vocabBrawlSpeechlet;
@Autowired
public HelloWorldServlet(VocabBrawlSpeechlet vocabBrawlSpeechlet) {
LOGGER.debug("Autowiring vocabBrawlSpeechlet");
this.vocabBrawlSpeechlet = vocabBrawlSpeechlet;
}
public HelloWorldServlet() {
LOGGER.debug(vocabBrawlSpeechlet);
this.setSpeechlet(vocabBrawlSpeechlet);
}
}
Speechlet类
package com.vocabBrawlAlexa.controller;
@Component
public class VocabBrawlSpeechlet implements SpeechletV2 {
static final Logger log = Logger.getLogger(VocabBrawlSpeechlet.class);
private IAlexaService alexaService;
/**
* Constructor.
*
* @param alexaService service.
*/
@Autowired
public VocabBrawlSpeechlet(IAlexaService alexaService) {
this.alexaService = alexaService;
}
public VocabBrawlSpeechlet() {
// TODO Auto-generated constructor stub
}
@Override
public void onSessionStarted(SpeechletRequestEnvelope<SessionStartedRequest> requestEnvelope) {
log.info("onSessionStarted " );
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
// any initialization logic goes here
}
@Override
public SpeechletResponse onLaunch(SpeechletRequestEnvelope<LaunchRequest> requestEnvelope) {
log.info("onLaunch");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
return getWelcomeResponse();
}
@Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
IntentRequest request = requestEnvelope.getRequest();
log.debug("reached Intent");
log.info("onIntent");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
Intent intent = request.getIntent();
String intentName = (intent != null) ? intent.getName() : null;
if ("HelloWorldIntent".equals(intentName)) {
log.debug("HelloWorldIntent Intent");
log.debug(alexaService);
//IAlexaService alexa = new AlexaServiceImpl();
return alexaService.getHelloIntentResponse();
} else if ("AMAZON.HelpIntent".equals(intentName)) {
return getHelpResponse();
} else {
return getAskResponse("HelloWorld", "This is unsupported. Please try something else.");
}
}
@Override
public void onSessionEnded(SpeechletRequestEnvelope<SessionEndedRequest> requestEnvelope) {
log.info("onSessionEnded");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
// any cleanup logic goes here
}
/**
* Creates and returns a {@code SpeechletResponse} with a welcome message.
*
* @return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getWelcomeResponse() {
String speechText = "Welcome to the Alexa Skills Kit, you can say hello";
return getAskResponse("HelloWorld", speechText);
}
/**
* Creates a {@code SpeechletResponse} for the hello intent.
*
* @return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getHelloResponse() {
log.debug("reached hello world");
String speechText = "Hello world";
// Create the Simple card content.
SimpleCard card = getSimpleCard("HelloWorld", speechText);
// Create the plain text output.
PlainTextOutputSpeech speech = getPlainTextOutputSpeech(speechText);
return SpeechletResponse.newTellResponse(speech, card);
}
/**
* Creates a {@code SpeechletResponse} for the help intent.
*
* @return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getHelpResponse() {
String speechText = "You can say hello to me!";
return getAskResponse("HelloWorld", speechText);
}
/**
* Helper method that creates a card object.
* @param title title of the card
* @param content body of the card
* @return SimpleCard the display card to be sent along with the voice response.
*/
private SimpleCard getSimpleCard(String title, String content) {
SimpleCard card = new SimpleCard();
card.setTitle(title);
card.setContent(content);
return card;
}
/**
* Helper method for retrieving an OutputSpeech object when given a string of TTS.
* @param speechText the text that should be spoken out to the user.
* @return an instance of SpeechOutput.
*/
private PlainTextOutputSpeech getPlainTextOutputSpeech(String speechText) {
PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
speech.setText(speechText);
return speech;
}
/**
* Helper method that returns a reprompt object. This is used in Ask responses where you want
* the user to be able to respond to your speech.
* @param outputSpeech The OutputSpeech object that will be said once and repeated if necessary.
* @return Reprompt instance.
*/
private Reprompt getReprompt(OutputSpeech outputSpeech) {
Reprompt reprompt = new Reprompt();
reprompt.setOutputSpeech(outputSpeech);
return reprompt;
}
/**
* Helper method for retrieving an Ask response with a simple card and reprompt included.
* @param cardTitle Title of the card that you want displayed.
* @param speechText speech text that will be spoken to the user.
* @return the resulting card and speech text.
*/
private SpeechletResponse getAskResponse(String cardTitle, String speechText) {
SimpleCard card = getSimpleCard(cardTitle, speechText);
PlainTextOutputSpeech speech = getPlainTextOutputSpeech(speechText);
Reprompt reprompt = getReprompt(speech);
return SpeechletResponse.newAskResponse(speech, reprompt, card);
}
}
申请类
package com.vocabBrawlAlexa;
@SpringBootApplication
@ServletComponentScan
@ComponentScan("com.vocabBrawlAlexa")
public class VocabBrawlAlexaApplication {
private static final Logger LOGGER = LogManager.getLogger(VocabBrawlAlexaApplication.class.getName());
public static void main(String[] args) {
LOGGER.info("Info Message Logged !!!");
//setAmazonProperties();
LOGGER.info("Info Message Logged asdfsa !!!");
setAmazonProperties();
SpringApplication.run(VocabBrawlAlexaApplication.class, args);
}
/**
* Sets system properties which are picked up by the {@link SpeechletServlet}.
*/
private static void setAmazonProperties() {
// Disable signature checks for development
LOGGER.info("Info Message Logged setAmazonProperties !!!");
System.setProperty(Sdk.DISABLE_REQUEST_SIGNATURE_CHECK_SYSTEM_PROPERTY, "true");
// Allow all application ids for development
System.setProperty(Sdk.SUPPORTED_APPLICATION_IDS_SYSTEM_PROPERTY, "amzn1.ask.skill.1672b699-610a-42b6-83cb-0a4e7c9f5ccf");
// Disable timestamp verification for development
System.setProperty(Sdk.TIMESTAMP_TOLERANCE_SYSTEM_PROPERTY, "1500");
}
}
更新:
我已根据建议删除了默认构造函数。 PFB改变的servlet代码
@WebServlet("/hello")
public class HelloWorldServlet extends SpeechletServlet {
private static final Logger LOGGER = LogManager.getLogger(HelloWorldServlet.class.getName());
/**
*
*/
private static final long serialVersionUID = -8294485619021129263L;
private VocabBrawlSpeechlet vocabBrawlSpeechlet;
@Autowired
public HelloWorldServlet(VocabBrawlSpeechlet vocabBrawlSpeechlet) {
LOGGER.debug("Autowiring vocabBrawlSpeechlet");
this.vocabBrawlSpeechlet = vocabBrawlSpeechlet;
this.setSpeechlet(this.vocabBrawlSpeechlet);
}
}
在第一次点击期间,我得到了500例外,之后我得到了404
java.lang.InstantiationException: com.vocabBrawlAlexa.HelloWorldServlet
java.lang.Class.newInstance(Class.java:368)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
java.lang.Thread.run(Thread.java:748)